'use client'; import { useState, useEffect, useCallback } from 'react'; import { Box, Typography, Button, Paper, CircularProgress, Grid } from '@mui/material'; import { AppShell } from '@/components/layouts/AppShell/AppShell'; import { ProtectedRoute } from '@/components/common/ProtectedRoute'; import { EmailVerificationBanner } from '@/components/common/EmailVerificationBanner'; import { ErrorBoundary } from '@/components/common/ErrorBoundary'; import { DataErrorFallback } from '@/components/common/ErrorFallbacks'; import { NetworkStatusIndicator } from '@/components/common/NetworkStatusIndicator'; import { StatGridSkeleton } from '@/components/common/LoadingSkeletons'; import { Restaurant, Hotel, BabyChangingStation, Insights, SmartToy, Analytics, MedicalServices, } from '@mui/icons-material'; import { motion } from 'framer-motion'; import { useAuth } from '@/lib/auth/AuthContext'; import { useRouter } from 'next/navigation'; import { trackingApi, DailySummary } from '@/lib/api/tracking'; import { childrenApi, Child } from '@/lib/api/children'; import { format } from 'date-fns'; import { useRealTimeActivities } from '@/hooks/useWebSocket'; export default function HomePage() { const { user, isLoading: authLoading } = useAuth(); const router = useRouter(); const [children, setChildren] = useState([]); const [selectedChild, setSelectedChild] = useState(null); const [dailySummary, setDailySummary] = useState(null); const [loading, setLoading] = useState(true); const familyId = user?.families?.[0]?.familyId; // Real-time activity handler to refresh daily summary const refreshDailySummary = useCallback(async () => { if (!selectedChild) return; try { const today = format(new Date(), 'yyyy-MM-dd'); const summary = await trackingApi.getDailySummary(selectedChild.id, today); console.log('[HomePage] Refreshed daily summary:', summary); setDailySummary(summary); } catch (error) { console.error('[HomePage] Failed to refresh summary:', error); } }, [selectedChild]); // Subscribe to real-time activity updates useRealTimeActivities( refreshDailySummary, // On activity created refreshDailySummary, // On activity updated refreshDailySummary // On activity deleted ); // Load children and daily summary useEffect(() => { const loadData = async () => { // Wait for auth to complete before trying to load data if (authLoading) { return; } if (!familyId) { console.log('[HomePage] No familyId found'); console.log('[HomePage] User object:', JSON.stringify(user, null, 2)); console.log('[HomePage] User.families:', user?.families); setLoading(false); return; } console.log('[HomePage] Loading data for familyId:', familyId); try { // Load children const childrenData = await childrenApi.getChildren(familyId); console.log('[HomePage] Children loaded:', childrenData.length); setChildren(childrenData); if (childrenData.length > 0) { const firstChild = childrenData[0]; setSelectedChild(firstChild); // Load today's summary for first child const today = format(new Date(), 'yyyy-MM-dd'); console.log('[HomePage] Fetching daily summary for child:', firstChild.id, 'date:', today); const summary = await trackingApi.getDailySummary(firstChild.id, today); console.log('[HomePage] Daily summary response:', summary); setDailySummary(summary); } } catch (error) { console.error('[HomePage] Failed to load data:', error); } finally { setLoading(false); } }; loadData(); }, [familyId, authLoading, user]); const quickActions = [ { icon: , label: 'Feeding', color: '#E91E63', path: '/track/feeding' }, // Pink with 4.5:1 contrast { icon: , label: 'Sleep', color: '#1976D2', path: '/track/sleep' }, // Blue with 4.5:1 contrast { icon: , label: 'Diaper', color: '#F57C00', path: '/track/diaper' }, // Orange with 4.5:1 contrast { icon: , label: 'Medicine', color: '#C62828', path: '/track/medication' }, // Red with 4.5:1 contrast { icon: , label: 'Activities', color: '#558B2F', path: '/activities' }, // Green with 4.5:1 contrast { icon: , label: 'AI Assistant', color: '#D84315', path: '/ai-assistant' }, // Deep orange with 4.5:1 contrast ]; const formatSleepHours = (minutes: number) => { const hours = Math.floor(minutes / 60); const mins = minutes % 60; if (hours > 0 && mins > 0) { return `${hours}h ${mins}m`; } else if (hours > 0) { return `${hours}h`; } else { return `${mins}m`; } }; return ( Welcome Back{user?.name ? `, ${user.name}` : ''}! 👋 Track your child's activities and get AI-powered insights {/* Quick Actions */} Quick Actions {quickActions.map((action, index) => ( router.push(action.path)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); router.push(action.path); } }} aria-label={`Navigate to ${action.label}`} sx={{ p: 3, height: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', cursor: 'pointer', bgcolor: action.color, color: 'white', border: 'none', transition: 'transform 0.2s', '&:hover': { transform: 'scale(1.05)', }, '&:focus-visible': { outline: '3px solid white', outlineOffset: '-3px', transform: 'scale(1.05)', }, }} > {action.label} ))} {/* Today's Summary */} Today's Summary{selectedChild ? ` - ${selectedChild.name}` : ''} } > {loading ? ( ) : ( {!dailySummary ? ( {children.length === 0 ? 'Add a child to start tracking' : 'No activities tracked today'} ) : ( )} )} {/* Next Predicted Activity */} Next Predicted Activity Nap time in 45 minutes Based on your child's sleep patterns ); }