feat: Update UI colors to use dynamic theme system and fix predictions
**Theme-Aware Colors Across App:** - Updated track page cards to use theme.palette colors - Updated analytics page icons to use theme colors - Updated login/register gradient backgrounds to use theme colors - All colors now respond to Standard/High Contrast theme toggle **Fixed Next Predicted Activity Section:** - Connected to real analytics API predictions endpoint - Fetches sleep and feeding predictions based on actual data - Shows "Nap time in X minutes" when prediction available - Displays formatted time using formatDistanceToNow - Falls back to "Not enough data available for now. Keep tracking :)" when no predictions **Multi-Language Support:** - Added "notEnoughData" translation key to all 7 languages: - English: "Not enough data available for now. Keep tracking :)" - Spanish: "No hay suficientes datos disponibles por ahora. ¡Sigue rastreando! :)" - French: "Pas assez de données disponibles pour le moment. Continuez à suivre :)" - Portuguese: "Dados insuficientes disponíveis no momento. Continue rastreando :)" - Chinese: "暂无足够数据。请继续记录 :)" - German: "Derzeit nicht genügend Daten verfügbar. Weiter verfolgen :)" - Italian: "Dati insufficienti al momento. Continua a monitorare :)" **Color Mapping by Theme:** *Purple Theme (Standard):* - Feeding: Primary (#8b52ff) - Sleep: Secondary (#ff7094) - Diaper: Warning (amber) - Medical: Error (red) - Activity: Success (green) - Growth: Primary Dark *Peach Theme (High Contrast):* - Feeding: Primary (#FFB6C1) - Sleep: Secondary (#FFDAB9) - Diaper: Warning (amber) - Medical: Error (red) - Activity: Success (green) - Growth: Primary Dark **Files Modified:** - app/track/page.tsx - Dynamic theme colors - app/analytics/page.tsx - Theme-aware icon colors - app/(auth)/login/page.tsx - Gradient uses theme - app/(auth)/register/page.tsx - Gradient uses theme - app/page.tsx - Predictions integration - locales/*/dashboard.json - All 7 languages 🎉 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -23,15 +23,18 @@ import { useAuth } from '@/lib/auth/AuthContext';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useQuery } from '@apollo/client/react';
|
||||
import { GET_DASHBOARD } from '@/graphql/queries/dashboard';
|
||||
import { format } from 'date-fns';
|
||||
import { format, formatDistanceToNow } from 'date-fns';
|
||||
import { useRealTimeActivities } from '@/hooks/useWebSocket';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { analyticsApi } from '@/lib/api/analytics';
|
||||
|
||||
export default function HomePage() {
|
||||
const { t } = useTranslation('dashboard');
|
||||
const { user, isLoading: authLoading } = useAuth();
|
||||
const router = useRouter();
|
||||
const [selectedChildId, setSelectedChildId] = useState<string | null>(null);
|
||||
const [predictions, setPredictions] = useState<any>(null);
|
||||
const [predictionsLoading, setPredictionsLoading] = useState(false);
|
||||
|
||||
// GraphQL query for dashboard data
|
||||
const { data, loading, error, refetch } = useQuery(GET_DASHBOARD, {
|
||||
@@ -94,6 +97,26 @@ export default function HomePage() {
|
||||
}
|
||||
}, [data, selectedChildId]);
|
||||
|
||||
// Fetch predictions when selectedChildId changes
|
||||
useEffect(() => {
|
||||
const fetchPredictions = async () => {
|
||||
if (!selectedChildId) return;
|
||||
|
||||
setPredictionsLoading(true);
|
||||
try {
|
||||
const predictionData = await analyticsApi.getPredictions(selectedChildId);
|
||||
setPredictions(predictionData);
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch predictions:', err);
|
||||
setPredictions(null);
|
||||
} finally {
|
||||
setPredictionsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchPredictions();
|
||||
}, [selectedChildId]);
|
||||
|
||||
const quickActions = [
|
||||
{ icon: <Restaurant />, label: t('quickActions.feeding'), color: '#E91E63', path: '/track/feeding' }, // Pink with 4.5:1 contrast
|
||||
{ icon: <Hotel />, label: t('quickActions.sleep'), color: '#1976D2', path: '/track/sleep' }, // Blue with 4.5:1 contrast
|
||||
@@ -322,12 +345,39 @@ export default function HomePage() {
|
||||
<Typography variant="body2" sx={{ color: 'rgba(0, 0, 0, 0.7)' }} gutterBottom>
|
||||
{t('predictions.title')}
|
||||
</Typography>
|
||||
<Typography variant="h6" fontWeight="600" gutterBottom>
|
||||
{t('predictions.napTime', { minutes: 45 })}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'rgba(0, 0, 0, 0.7)' }}>
|
||||
{t('predictions.basedOnPatterns')}
|
||||
</Typography>
|
||||
{predictionsLoading ? (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
||||
<CircularProgress size={20} />
|
||||
<Typography variant="body2">Loading predictions...</Typography>
|
||||
</Box>
|
||||
) : predictions?.sleep?.nextNapTime || predictions?.feeding?.nextFeedingTime ? (
|
||||
<>
|
||||
{predictions.sleep?.nextNapTime && (
|
||||
<>
|
||||
<Typography variant="h6" fontWeight="600" gutterBottom>
|
||||
Nap time {formatDistanceToNow(new Date(predictions.sleep.nextNapTime), { addSuffix: true })}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'rgba(0, 0, 0, 0.7)' }}>
|
||||
{predictions.sleep.reasoning || t('predictions.basedOnPatterns')}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
{!predictions.sleep?.nextNapTime && predictions.feeding?.nextFeedingTime && (
|
||||
<>
|
||||
<Typography variant="h6" fontWeight="600" gutterBottom>
|
||||
Feeding time {formatDistanceToNow(new Date(predictions.feeding.nextFeedingTime), { addSuffix: true })}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'rgba(0, 0, 0, 0.7)' }}>
|
||||
{predictions.feeding.reasoning || t('predictions.basedOnPatterns')}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Typography variant="body1" sx={{ color: 'rgba(0, 0, 0, 0.7)' }}>
|
||||
{t('predictions.notEnoughData')}
|
||||
</Typography>
|
||||
)}
|
||||
</Paper>
|
||||
</Box>
|
||||
</motion.div>
|
||||
|
||||
Reference in New Issue
Block a user