Fixed the timetable finally
This commit is contained in:
@@ -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 (
|
||||
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
|
||||
<h3 className="text-lg font-semibold mb-4 text-gray-800">Sleep Timetable</h3>
|
||||
<h3 className="text-lg font-semibold mb-2 text-gray-800">Sleep Timetable</h3>
|
||||
|
||||
{/* Tab Selector (Mobile & Medium) */}
|
||||
{(tier === 'medium' || tier === 'small') && (
|
||||
<div className="flex overflow-x-auto gap-2 mb-4 pb-2 no-scrollbar">
|
||||
<div className="flex overflow-x-auto gap-2 mb-2 pb-1 no-scrollbar">
|
||||
{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)`
|
||||
}}
|
||||
>
|
||||
<div className="h-2" /> {/* Empty corner cell */}
|
||||
@@ -171,15 +182,13 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
|
||||
{/* Time Grid Container */}
|
||||
<div className="relative">
|
||||
<div
|
||||
className="grid"
|
||||
style={{
|
||||
gridTemplateColumns: tier === 'desktop'
|
||||
? `4rem repeat(${days.length}, minmax(40px, 1fr))`
|
||||
: tier === 'medium'
|
||||
? `4rem repeat(3, 1fr)`
|
||||
: `4rem 1fr`
|
||||
}}
|
||||
>
|
||||
className="grid"
|
||||
style={{
|
||||
gridTemplateColumns: tier === 'desktop'
|
||||
? `4rem repeat(${days.length}, minmax(40px, 1fr))`
|
||||
: `4rem repeat(${visibleDays.length}, 1fr)`
|
||||
}}
|
||||
>
|
||||
{/* Time Rows */}
|
||||
{timeSteps.map((step) => (
|
||||
<Fragment key={step}>
|
||||
|
||||
@@ -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)', () => {
|
||||
|
||||
Reference in New Issue
Block a user