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
- 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:

View file

@ -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 }) {
</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 */}
<Box sx={{
display: 'flex',