removed strict mode, rendering row titles

This commit is contained in:
Drew Peifer 2026-02-14 02:53:26 -05:00
parent 8bbdcf3673
commit 6e6176af7f
4 changed files with 88 additions and 41 deletions

View file

@ -27,7 +27,6 @@ body {
h1, h2, h3, h4, h5, h6 {
font-family: "Russo One", sans-serif !important;
font-size:1.2rem;
}
/* App theme containers */
.app-dark {
@ -59,7 +58,6 @@ h1, h2, h3, h4, h5, h6 {
flex-grow: 2;
}
.widget-row.condensed {
flex-wrap: wrap;
justify-content: space-evenly;
}
.news-widget img {

View file

@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';
import { Box, Container, CircularProgress, IconButton, Alert } from '@mui/material';
import { Brightness4, Brightness7, Refresh } from '@mui/icons-material';
import { fetchAllSources } from '../services/dataFetcher';
@ -18,15 +18,27 @@ function Dashboard({ themeToggle, isDark }) {
const [refreshing, setRefreshing] = useState(false);
const [tokenUsage, setTokenUsage] = useState(null);
const [cacheInfo, setCacheInfo] = useState(null);
const isLoadingRef = useRef(false);
useEffect(() => {
console.log('=== Dashboard mounting, calling loadDashboard ===');
loadDashboard();
}, []);
async function loadDashboard(forceRefresh = false) {
// Prevent concurrent requests using ref for immediate check
if (isLoadingRef.current) {
console.log('=== loadDashboard SKIPPED - already in progress ===');
console.log('Attempted at:', new Date().toISOString());
return;
}
isLoadingRef.current = true;
try {
console.log('=== loadDashboard called ===');
console.log('Force refresh:', forceRefresh);
console.log('Request timestamp:', new Date().toISOString());
setError(null);
// Check if we already have today's briefing (unless forcing refresh)
@ -126,11 +138,15 @@ function Dashboard({ themeToggle, isDark }) {
} finally {
setLoading(false);
setRefreshing(false);
isLoadingRef.current = false;
console.log('=== loadDashboard completed at:', new Date().toISOString(), '===');
}
}
const handleRefresh = () => {
setRefreshing(true);
setLoading(true);
setLoadingStatus('Refreshing your dashboard...');
loadDashboard(true);
};
@ -221,17 +237,28 @@ function Dashboard({ themeToggle, isDark }) {
/>
</Box>
{/* Render rows based on the new data structure */}
{/* Render rows based on the data structure */}
{Object.entries(sourceData).map(([key, data]) => {
// Skip special entries like weather and legacy flat entries
if (key === 'weather' || key.startsWith('reddit_') || key.startsWith('rss_') || key.startsWith('source_')) {
// Skip non-array entries (like weather)
if (!Array.isArray(data) || data.length === 0) {
return null;
}
// Only process row entries (row1, row2, etc.)
if (key.startsWith('row') && Array.isArray(data)) {
return (
<Box key={key} className="widget-row condensed">
return (
<Box key={key} sx={{ mb: 2 }}>
{/* Display row header if not using legacy row naming */}
{!key.startsWith('row') && (
<h1 style={{
marginBottom: '12px',
marginTop: '20px',
color: 'inherit',
fontWeight: 600
}}>
{key}
</h1>
)}
<Box className="widget-row condensed">
{data.map((widgetData, index) => (
<NewsWidget
key={`${key}-${index}`}
@ -239,26 +266,9 @@ function Dashboard({ themeToggle, isDark }) {
/>
))}
</Box>
);
}
return null;
</Box>
);
})}
{/* Fallback for legacy format - if no rows detected, render flat structure */}
{!Object.keys(sourceData).some(k => k.startsWith('row')) && (
<Box className="widget-row condensed">
{Object.entries(sourceData).map(([key, data]) => {
if (key === 'weather' || !data) return null;
return (
<NewsWidget
key={key}
data={data}
/>
);
})}
</Box>
)}
</Box>
</Container>

View file

@ -3,7 +3,5 @@ import ReactDOM from 'react-dom/client'
import App from './App.jsx'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
<App />
)

View file

@ -123,7 +123,15 @@ CURRENT DATA:
- Includes relevant weather information if available
- Ends with something engaging or thought-provoking
Focus on the most newsworthy and interesting items. Don't try to mention everything.`;
Focus on the most newsworthy and interesting items. Don't try to mention everything.
IMPORTANT: Provide your response as valid JSON with exactly two fields:
{
"fullBriefing": "Your complete 300-400 word friendly briefing text here",
"condensedSummary": "A 50-75 word ultra-condensed summary of the key topics and main stories for historical context"
}
The JSON must be properly formatted with escaped quotes where necessary.`;
return prompt;
}
@ -171,13 +179,46 @@ export async function generateBriefing(currentData, previousBriefing) {
const prompt = buildBriefingPrompt(currentData, previousBriefing);
const result = await callClaude(prompt);
// Generate condensed summary for historical storage
const condensedSummary = await generateCondensedSummary(result.text);
return {
...result,
condensedSummary: condensedSummary
};
// Parse JSON response that now includes both fullBriefing and condensedSummary
try {
// Strip markdown code blocks if present
let jsonText = result.text;
if (jsonText.includes('```json')) {
jsonText = jsonText.replace(/```json\s*/g, '').replace(/```\s*/g, '');
} else if (jsonText.includes('```')) {
jsonText = jsonText.replace(/```\s*/g, '');
}
jsonText = jsonText.trim();
const parsed = JSON.parse(jsonText);
// Validate the JSON structure
if (!parsed.fullBriefing || !parsed.condensedSummary) {
throw new Error('Invalid response structure from Claude');
}
console.log('Successfully parsed briefing with condensed summary');
console.log('Condensed summary:', parsed.condensedSummary.substring(0, 100) + '...');
return {
text: parsed.fullBriefing,
condensedSummary: parsed.condensedSummary,
usage: result.usage
};
} catch (parseError) {
console.error('Failed to parse JSON response, attempting fallback:', parseError);
// Fallback: if JSON parsing fails, use the raw text and generate summary separately
// This maintains backward compatibility but should rarely happen
console.warn('Using fallback: generating condensed summary separately');
const condensedSummary = await generateCondensedSummary(result.text);
return {
text: result.text,
condensedSummary: condensedSummary,
usage: result.usage
};
}
} catch (error) {
console.error('Error generating briefing:', error);