added indicator when using cached results

This commit is contained in:
Drew Peifer 2026-02-12 03:41:48 -05:00
parent c174f3c1d4
commit 062dea1ba6
2 changed files with 47 additions and 0 deletions

View file

@ -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 - Keeps the API key secure from browser developer tools
- Provides a single point for API request/response logging - 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 ### Source Parser
The `sourceParser.js` service intelligently handles various data formats: The `sourceParser.js` service intelligently handles various data formats:

View file

@ -17,6 +17,7 @@ function Dashboard({ themeToggle, isDark }) {
const [error, setError] = useState(null); const [error, setError] = useState(null);
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
const [tokenUsage, setTokenUsage] = useState(null); const [tokenUsage, setTokenUsage] = useState(null);
const [cacheInfo, setCacheInfo] = useState(null);
useEffect(() => { useEffect(() => {
loadDashboard(); loadDashboard();
@ -34,6 +35,18 @@ function Dashboard({ themeToggle, isDark }) {
const todaysBriefing = getTodaysBriefing(); const todaysBriefing = getTodaysBriefing();
setBriefing(todaysBriefing.briefing); setBriefing(todaysBriefing.briefing);
setSourceData(todaysBriefing.sources || {}); 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); setLoading(false);
return; return;
} }
@ -83,10 +96,12 @@ function Dashboard({ themeToggle, isDark }) {
if (result && typeof result === 'object' && result.text) { if (result && typeof result === 'object' && result.text) {
setBriefing(result.text); setBriefing(result.text);
setTokenUsage(result.usage); setTokenUsage(result.usage);
setCacheInfo(null); // Clear cache info when generating fresh briefing
console.log('Token usage:', result.usage); console.log('Token usage:', result.usage);
} else if (typeof result === 'string') { } else if (typeof result === 'string') {
// Fallback for string responses // Fallback for string responses
setBriefing(result); setBriefing(result);
setCacheInfo(null);
} }
// Save to localStorage // Save to localStorage
@ -186,6 +201,18 @@ function Dashboard({ themeToggle, isDark }) {
</Box> </Box>
)} )}
{cacheInfo && (
<Box sx={{ mb: 2, p: 2, bgcolor: 'success.main', color: 'success.contrastText', borderRadius: 1, border: '1px solid', borderColor: 'success.dark' }}>
<Typography variant="body2">
<strong>💾 Using cached results</strong> from {cacheInfo.age < 1 ? 'less than a minute' : cacheInfo.age === 1 ? '1 minute' : `${cacheInfo.age} minutes`} ago no API costs incurred
{' '}
<Typography component="span" variant="caption" sx={{ opacity: 0.9 }}>
(Click refresh to generate a new briefing)
</Typography>
</Typography>
</Box>
)}
{/* Widget Grid - easily rearrangeable */} {/* Widget Grid - easily rearrangeable */}
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',