From 062dea1ba6577ed2c68238e92ad5d72347a26353 Mon Sep 17 00:00:00 2001 From: Drew Peifer Date: Thu, 12 Feb 2026 03:41:48 -0500 Subject: [PATCH] added indicator when using cached results --- README.md | 20 ++++++++++++++++++++ claudash/src/components/Dashboard.jsx | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/README.md b/README.md index bd96ed9..9c5c26c 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,26 @@ The application uses a local Express proxy server (`proxy-server.js`) to communi - Keeps the API key secure from browser developer tools - Provides a single point for API request/response logging +**The proxy server is automatically started when you run `npm start`** and runs on port 3001 alongside the Vite dev server (port 5173). + +#### Troubleshooting the Proxy Server + +If you encounter errors like "Failed to fetch" or "Network request failed" when generating briefings: + +1. **Check if the proxy server is running**: Look for console output showing `Proxy server listening on port 3001` +2. **Restart the application**: The easiest way to restart both servers is to: + - Stop the current process (Ctrl+C in terminal) + - Run `npm start` again + +If you need to run the servers separately for debugging: +```bash +# Terminal 1: Run proxy server only +npm run proxy + +# Terminal 2: Run Vite dev server only +npm run dev +``` + ### Source Parser The `sourceParser.js` service intelligently handles various data formats: diff --git a/claudash/src/components/Dashboard.jsx b/claudash/src/components/Dashboard.jsx index dd69fb0..3e0ba02 100644 --- a/claudash/src/components/Dashboard.jsx +++ b/claudash/src/components/Dashboard.jsx @@ -17,6 +17,7 @@ function Dashboard({ themeToggle, isDark }) { const [error, setError] = useState(null); const [refreshing, setRefreshing] = useState(false); const [tokenUsage, setTokenUsage] = useState(null); + const [cacheInfo, setCacheInfo] = useState(null); useEffect(() => { loadDashboard(); @@ -34,6 +35,18 @@ function Dashboard({ themeToggle, isDark }) { const todaysBriefing = getTodaysBriefing(); setBriefing(todaysBriefing.briefing); setSourceData(todaysBriefing.sources || {}); + + // Calculate cache age + const cacheAge = Date.now() - todaysBriefing.timestamp; + const cacheAgeMinutes = Math.floor(cacheAge / (1000 * 60)); + + // Set cache info to display message + setCacheInfo({ + age: cacheAgeMinutes, + timestamp: todaysBriefing.timestamp + }); + setTokenUsage(null); // Clear token usage when using cache + setLoading(false); return; } @@ -83,10 +96,12 @@ function Dashboard({ themeToggle, isDark }) { if (result && typeof result === 'object' && result.text) { setBriefing(result.text); setTokenUsage(result.usage); + setCacheInfo(null); // Clear cache info when generating fresh briefing console.log('Token usage:', result.usage); } else if (typeof result === 'string') { // Fallback for string responses setBriefing(result); + setCacheInfo(null); } // Save to localStorage @@ -186,6 +201,18 @@ function Dashboard({ themeToggle, isDark }) { )} + {cacheInfo && ( + + + 💾 Using cached results from {cacheInfo.age < 1 ? 'less than a minute' : cacheInfo.age === 1 ? '1 minute' : `${cacheInfo.age} minutes`} ago — no API costs incurred + {' '} + + (Click refresh to generate a new briefing) + + + + )} + {/* Widget Grid - easily rearrangeable */}