'use client';
import { useState, useEffect } from 'react';
import {
Box,
Typography,
Grid,
Card,
CardContent,
Select,
MenuItem,
FormControl,
InputLabel,
CircularProgress,
Alert,
Tab,
Tabs,
Chip,
List,
ListItem,
ListItemIcon,
ListItemText,
useTheme,
} from '@mui/material';
import {
TrendingUp,
Restaurant,
Hotel,
BabyChangingStation,
Warning,
CheckCircle,
Timeline,
Assessment,
} from '@mui/icons-material';
import { AppShell } from '@/components/layouts/AppShell/AppShell';
import { ProtectedRoute } from '@/components/common/ProtectedRoute';
import { childrenApi, Child } from '@/lib/api/children';
import { analyticsApi, PatternInsights, PredictionInsights } from '@/lib/api/analytics';
import PredictionsCard from '@/components/features/analytics/PredictionsCard';
import { extractError } from '@/lib/utils/errorHandler';
import GrowthSpurtAlert from '@/components/features/analytics/GrowthSpurtAlert';
import WeeklyReportCard from '@/components/features/analytics/WeeklyReportCard';
import MonthlyReportCard from '@/components/features/analytics/MonthlyReportCard';
import { useAuth } from '@/lib/auth/AuthContext';
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
{value === index && {children}}
);
}
export default function AnalyticsPage() {
const theme = useTheme();
const { user } = useAuth();
const [children, setChildren] = useState([]);
const [selectedChildId, setSelectedChildId] = useState('');
const [tabValue, setTabValue] = useState(0);
const [loading, setLoading] = useState(true);
const [insights, setInsights] = useState(null);
const [predictions, setPredictions] = useState(null);
const [insightsLoading, setInsightsLoading] = useState(false);
const [predictionsLoading, setPredictionsLoading] = useState(false);
const [days, setDays] = useState(7);
const [error, setError] = useState('');
const familyId = user?.families?.[0]?.familyId;
useEffect(() => {
if (familyId) {
loadChildren();
}
}, [familyId]);
useEffect(() => {
if (selectedChildId && children.length > 0) {
// Validate that selectedChildId belongs to current user's children
const childExists = children.some(child => child.id === selectedChildId);
if (childExists) {
loadInsights();
loadPredictions();
} else {
console.warn('[AnalyticsPage] Selected child not found in user\'s children, resetting');
setSelectedChildId(children[0].id);
setError('Selected child not found. Showing data for your first child.');
}
}
}, [selectedChildId, days, children]);
const loadChildren = async () => {
if (!familyId) {
setLoading(false);
setError('No family found');
return;
}
try {
console.log('[AnalyticsPage] Loading children for familyId:', familyId);
const data = await childrenApi.getChildren(familyId);
console.log('[AnalyticsPage] Loaded children:', data);
setChildren(data);
if (data.length > 0) {
const existingChildStillValid = data.some(child => child.id === selectedChildId);
if (!selectedChildId || !existingChildStillValid) {
setSelectedChildId(data[0].id);
}
}
setError('');
} catch (error: any) {
console.error('[AnalyticsPage] Failed to load children:', error);
const errorData = extractError(error);
setError(errorData.userMessage || errorData.message);
} finally {
setLoading(false);
}
};
const loadInsights = async () => {
if (!selectedChildId) return;
setInsightsLoading(true);
try {
const data = await analyticsApi.getInsights(selectedChildId, days);
setInsights(data);
} catch (error: any) {
console.error('Failed to load insights:', error);
const errorData = extractError(error);
console.error('Insights error:', errorData.message);
} finally {
setInsightsLoading(false);
}
};
const loadPredictions = async () => {
if (!selectedChildId) return;
setPredictionsLoading(true);
try {
const data = await analyticsApi.getPredictions(selectedChildId);
setPredictions(data);
} catch (error: any) {
console.error('Failed to load predictions:', error);
const errorData = extractError(error);
console.error('Predictions error:', errorData.message);
} finally {
setPredictionsLoading(false);
}
};
if (loading) {
return (
);
}
if (children.length === 0) {
return (
Add a child to your family to view analytics and predictions.
);
}
return (
{/* Header */}
Analytics & Predictions
AI-powered insights and predictions for your child's patterns
{/* Child Selector and Date Range */}
Child
Date Range
{/* Growth Spurt Alert */}
{insights?.growthSpurt && }
{/* Tabs */}
setTabValue(newValue)}>
} iconPosition="start" />
} iconPosition="start" />
} iconPosition="start" />
} iconPosition="start" />
{/* Tab Panels */}
{/* Sleep Patterns */}
{insights?.sleep && (
Sleep Patterns
Avg Duration
{Math.round(insights.sleep.averageDuration)} min
Night Wakings
{insights.sleep.nightWakings}
Avg Bedtime
{insights.sleep.averageBedtime}
Avg Wake Time
{insights.sleep.averageWakeTime}
Nap Count
{insights.sleep.napCount}
Consistency
{Math.round(insights.sleep.consistency * 100)}%
)}
{/* Feeding Patterns */}
{insights?.feeding && (
Feeding Patterns
Total Feedings
{insights.feeding.totalFeedings}
Avg Interval
{insights.feeding.averageInterval.toFixed(1)} hrs
Avg Duration
{Math.round(insights.feeding.averageDuration)} min
Consistency
{Math.round(insights.feeding.consistency * 100)}%
{Object.keys(insights.feeding.feedingMethod).length > 0 && (
Feeding Methods
{Object.entries(insights.feeding.feedingMethod).map(([method, count]) => (
))}
)}
)}
{/* Diaper Patterns */}
{insights?.diaper && (
Diaper Patterns
Wet/Day
{insights.diaper.wetDiapersPerDay.toFixed(1)}
Dirty/Day
{insights.diaper.dirtyDiapersPerDay.toFixed(1)}
Avg Interval
{insights.diaper.averageInterval.toFixed(1)} hrs
{insights.diaper.notes && (
{insights.diaper.notes}
)}
)}
{insightsLoading && (
)}
{!insightsLoading && !insights && (
Not enough data to analyze patterns yet. Track more activities!
)}
{/* Recommendations */}
{insights?.recommendations && insights.recommendations.length > 0 && (
Recommendations
{insights.recommendations.map((rec, index) => (
))}
)}
{/* Concerns */}
{insights?.concernsDetected && insights.concernsDetected.length > 0 && (
Concerns Detected
{insights.concernsDetected.map((concern, index) => (
))}
If you have concerns about your child's health, please consult with your pediatrician.
)}
{(!insights?.recommendations || insights.recommendations.length === 0) &&
(!insights?.concernsDetected || insights.concernsDetected.length === 0) && (
No recommendations or concerns at this time. Keep tracking!
)}
);
}