import React from 'react'; import { useStats } from '../../hooks/useStats'; import { timeToMinutes, formatMinutesAfter } from '../../utils/time'; interface TimetableProps { from_date: string; to_date: string; day_start: string; day_end: string; }; const Timetable: React.FC = ({ from_date, to_date, day_start, day_end }) => { const { timetable, isLoading } = useStats(from_date, to_date, day_start, day_end); if (isLoading) return
Loading timetable...
; if (!timetable?.slots || timetable.slots.length === 0) { return
No data available for this period.
; } const startMins = timeToMinutes(day_start); let endMins = timeToMinutes(day_end); if (endMins < startMins) endMins += 1440; const totalDayMinutes = endMins - startMins; // Grouping slots by date to make it easier to render rows const groupedSlots = timetable.slots.reduce((acc: any, slot) => { if (!acc[slot.date]) acc[slot.date] = []; acc[slot.date].push(slot); return acc; }, {}); return (

Sleep Timetable

{Object.keys(groupedSlots).sort((a, b) => b.localeCompare(a)).map((date) => (

{date}

{/* The progress bar container */}
{groupedSlots[date].map((slot: any) => { let sStart = timeToMinutes(slot.slot_start); if (sStart < startMins) sStart += 1440; let sEnd = timeToMinutes(slot.slot_end); if (sEnd < sStart) sEnd += 1440; else if (sEnd < startMins) sEnd += 1440; const left = ((sStart - startMins) / totalDayMinutes) * 100; const width = ((sEnd - sStart) / totalDayMinutes) * 100; return (
{/* Only show text if there's enough space */}
{width > 15 && {slot.slot_start}}
); })}
{/* Time hints below the bar */}
{Array.from({ length: Math.ceil(totalDayMinutes / 120) + 1 }).map((_, i) => { const minsOffset = i * 120; if (minsOffset > totalDayMinutes) return null; return ( {formatMinutesAfter(minsOffset, day_start)} ); })}
))}
); }; export default Timetable;