diff --git a/frontend/src/components/stats/SleepTimetable.tsx b/frontend/src/components/stats/SleepTimetable.tsx index 269b13a..3944609 100644 --- a/frontend/src/components/stats/SleepTimetable.tsx +++ b/frontend/src/components/stats/SleepTimetable.tsx @@ -13,6 +13,13 @@ function getDayName(dateStr: string) { return new Date(dateStr + 'T00:00:00').toLocaleDateString('en-US', { weekday: 'short' }); } +function formatDayLabel(dateStr: string) { + const date = new Date(dateStr + 'T00:00:00'); + const weekday = date.toLocaleDateString('en-US', { weekday: 'short' }); + const day = date.getDate(); + return `${weekday} ${day}`; +} + function formatTimeLabel(mins: number) { const hours = Math.floor(mins / 60); const minutes = mins % 60; @@ -24,12 +31,6 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = const [selectedDayIndex, setSelectedDayIndex] = useState(0); const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1024); - useEffect(() => { - const handleResize = () => setWindowWidth(window.innerWidth); - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); - }, []); - const days = useMemo(() => { const start = new Date(from_date + 'T00:00:00'); const end = new Date(to_date + 'T23:59:59'); @@ -42,6 +43,18 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = return result; // Chronological (oldest to newest) }, [from_date, to_date]); + useEffect(() => { + const handleResize = () => setWindowWidth(window.innerWidth); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + useEffect(() => { + if (days.length > 0) { + setSelectedDayIndex(days.length - 1); + } + }, [days]); + const reversedDays = useMemo(() => [...days].reverse(), [days]); const timeSteps = useMemo(() => { @@ -67,7 +80,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = const groups = []; for (let i = 0; i < activeDays.length; i += 3) { groups.push({ - label: `${getDayName(activeDays[i])} - ${getDayName(activeDays[Math.min(i + 2, activeDays.length - 1)])}`, + label: `${formatDayLabel(activeDays[i])} - ${formatDayLabel(activeDays[Math.min(i + 2, activeDays.length - 1)])}`, startIndex: i, }); } @@ -79,7 +92,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = // Small tier (single day) const groups = activeDays.map((day, idx) => ({ - label: getDayName(day), + label: formatDayLabel(day), startIndex: idx, })); return { @@ -122,11 +135,11 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = return (
-

Sleep Timetable

+

Sleep Timetable

{/* Tab Selector (Mobile & Medium) */} {(tier === 'medium' || tier === 'small') && ( -
+
{tabGroups.map((group, idx) => { const isActive = selectedDayIndex === days.indexOf(reversedDays[group.startIndex]); @@ -155,9 +168,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = style={{ gridTemplateColumns: tier === 'desktop' ? `4rem repeat(${days.length}, minmax(40px, 1fr))` - : tier === 'medium' - ? `4rem repeat(3, 1fr)` - : `4rem 1fr` + : `4rem repeat(${visibleDays.length}, 1fr)` }} >
{/* Empty corner cell */} @@ -171,15 +182,13 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) = {/* Time Grid Container */}
+ className="grid" + style={{ + gridTemplateColumns: tier === 'desktop' + ? `4rem repeat(${days.length}, minmax(40px, 1fr))` + : `4rem repeat(${visibleDays.length}, 1fr)` + }} + > {/* Time Rows */} {timeSteps.map((step) => ( diff --git a/frontend/tests/unit/components/stats/SleepTimetable.test.tsx b/frontend/tests/unit/components/stats/SleepTimetable.test.tsx index d1d0afc..1c0af74 100644 --- a/frontend/tests/unit/components/stats/SleepTimetable.test.tsx +++ b/frontend/tests/unit/components/stats/SleepTimetable.test.tsx @@ -63,7 +63,7 @@ describe('SleepTimetable', () => { // Check for 3-day interval tabs // In reversed order (25, 24, 23...), the first group is Fri - Wed - expect(screen.getByRole('button', { name: /FRI - WED/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /Fri \d+ - Wed \d+/i })).toBeInTheDocument(); }); it('renders in small mode (single-day tabs and 1-column grid)', () => {