import { useMemo } from 'react'; import { useStats } from '../../hooks/useStats'; import { formatMinutesAfter, getToday } from '../../utils/time'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from 'recharts'; interface WakeupBedtimeProps { from_date: string; to_date: string; wakeup_ref: string; bedtime_ref: string; } const WakeupPlot: React.FC = ({ from_date, to_date, wakeup_ref = '07:00', bedtime_ref = '20:00' }) => { const { wakeupBedtime, isLoading } = useStats(from_date, to_date, '07:00', '20:00', wakeup_ref, bedtime_ref); const chartData = useMemo(() => { if (!wakeupBedtime?.days) return []; return wakeupBedtime.days.map((day) => { const daysAgo = Math.floor( (new Date(getToday()).getTime() - new Date(day.date).getTime()) / (1000 * 60 * 60 * 24) ); const offsetFromRef = day.wakeup_minutes ?? 0; return { date: daysAgo === 0 ? 'Today' : `${daysAgo}d ago`, minutes: offsetFromRef, time: day.wakeup_minutes !== null ? formatMinutesAfter(offsetFromRef, wakeup_ref) : 'N/A', }; }).reverse(); }, [wakeupBedtime, wakeup_ref]); const stats = useMemo(() => { if (!wakeupBedtime?.days) return null; const validMinutes = wakeupBedtime.days .map((day) => day.wakeup_minutes) .filter((m): m is number => m !== null); if (validMinutes.length === 0) return null; const min = Math.min(...validMinutes); const max = Math.max(...validMinutes); const avg = validMinutes.reduce((sum, m) => sum + m, 0) / validMinutes.length; const sorted = [...validMinutes].sort((a, b) => a - b); const mid = Math.floor(sorted.length / 2); const median = sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2; return { min, max, avg, median }; }, [wakeupBedtime]); if (isLoading) return
Loading plot...
; if (!chartData.length) { return
No data available for this period.
; } return (

Wakeup Times

formatMinutesAfter(Number(value), wakeup_ref)} domain={['dataMin - 30', 'dataMax + 30']} /> [ typeof value === 'number' ? formatMinutesAfter(value, wakeup_ref) : String(value ?? ''), 'Wakeup', ]} labelFormatter={(label) => label} /> {stats && (

Earliest

{formatMinutesAfter(stats.min, wakeup_ref)}

Latest

{formatMinutesAfter(stats.max, wakeup_ref)}

Average

{formatMinutesAfter(Math.round(stats.avg), wakeup_ref)}

Median

{formatMinutesAfter(Math.round(stats.median), wakeup_ref)}

)}
); }; export default WakeupPlot;