added indicator when using cached results
This commit is contained in:
parent
c174f3c1d4
commit
062dea1ba6
2 changed files with 47 additions and 0 deletions
20
README.md
20
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
|
- 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:
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue