'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 { useQuery } from '@apollo/client/react'; import { GET_DASHBOARD } from '@/graphql/queries/dashboard'; import { format } from 'date-fns'; import { useRealTimeActivities } from '@/hooks/useWebSocket'; import { useTranslation } from '@/hooks/useTranslation'; export default function HomePage() { const { t } = useTranslation('dashboard'); const { user, isLoading: authLoading } = useAuth(); const router = useRouter(); const [selectedChildId, setSelectedChildId] = useState(null); // GraphQL query for dashboard data const { data, loading, error, refetch } = useQuery(GET_DASHBOARD, { variables: { childId: selectedChildId }, skip: authLoading || !user, fetchPolicy: 'cache-and-network', }); // Log GraphQL errors and data for debugging useEffect(() => { console.log('[HomePage] === GraphQL Debug Info ==='); console.log('[HomePage] Raw data:', data); console.log('[HomePage] Data type:', typeof data); console.log('[HomePage] Data keys:', data ? Object.keys(data) : 'null'); if (error) { console.error('[HomePage] GraphQL error:', error); console.error('[HomePage] GraphQL error details:', { message: error.message, networkError: error.networkError, graphQLErrors: error.graphQLErrors, }); } if (data) { console.log('[HomePage] GraphQL data:', data); console.log('[HomePage] Dashboard data:', data.dashboard); } console.log('[HomePage] Query state:', { loading, error: !!error, hasData: !!data, user: !!user, skip: authLoading || !user, childrenCount: data?.dashboard?.children?.length || 0, selectedChildId, }); console.log('[HomePage] LocalStorage token:', typeof window !== 'undefined' ? localStorage.getItem('accessToken')?.substring(0, 20) : 'SSR'); }, [error, data, loading, user, authLoading, selectedChildId]); // Real-time activity handler to refetch dashboard data const refreshDashboard = useCallback(async () => { if (refetch) { console.log('[HomePage] Refreshing dashboard data...'); await refetch(); } }, [refetch]); // Subscribe to real-time activity updates useRealTimeActivities( refreshDashboard, // On activity created refreshDashboard, // On activity updated refreshDashboard // On activity deleted ); // Set the first child as selected when data loads useEffect(() => { if (data?.dashboard?.children && data.dashboard.children.length > 0 && !selectedChildId) { const firstChild = data.dashboard.children[0]; setSelectedChildId(firstChild.id); } }, [data, selectedChildId]); const quickActions = [ { icon: , label: t('quickActions.feeding'), color: '#E91E63', path: '/track/feeding' }, // Pink with 4.5:1 contrast { icon: , label: t('quickActions.sleep'), color: '#1976D2', path: '/track/sleep' }, // Blue with 4.5:1 contrast { icon: , label: t('quickActions.diaper'), color: '#F57C00', path: '/track/diaper' }, // Orange with 4.5:1 contrast { icon: , label: t('quickActions.medicine'), color: '#C62828', path: '/track/medication' }, // Red with 4.5:1 contrast { icon: , label: t('quickActions.activities'), color: '#558B2F', path: '/activities' }, // Green with 4.5:1 contrast { icon: , label: t('quickActions.aiAssistant'), 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`; } }; // Extract data from GraphQL response const children = data?.dashboard?.children || []; const selectedChild = data?.dashboard?.selectedChild; const dailySummary = data?.dashboard?.todaySummary; const isLoading = authLoading || loading; return ( {user?.name ? t('welcomeBackWithName', { name: user.name }) : t('welcomeBack')} 👋 {t('subtitle')} {/* Quick Actions */} {t('quickActions.title')} {quickActions.map((action, index) => ( router.push(action.path)} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); router.push(action.path); } }} aria-label={t('quickActions.navigateTo', { action: 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 */} {selectedChild ? t('summary.titleWithChild', { childName: selectedChild.name }) : t('summary.title')} } > {isLoading ? ( ) : ( {!dailySummary ? ( {children.length === 0 ? t('summary.noChild') : t('summary.noActivities')} ) : ( )} )} {/* Next Predicted Activity */} {t('predictions.title')} {t('predictions.napTime', { minutes: 45 })} {t('predictions.basedOnPatterns')} ); }