Files
babymonitor/frontend/src/components/stats/SleepTimetable.tsx
T
2026-04-24 22:43:45 +02:00

63 lines
2.5 KiB
TypeScript

import React from 'react';
import { useStats } from '../../hooks/useStats';
import { timeToMinutes } from '../../utils/time';
interface TimetableProps {
from_date: string;
to_date: string;
day_start: string;
day_end: string;
};
const Timetable: React.FC<TimetableProps> = ({ from_date, to_date, day_start, day_end }) => {
const { timetable, isLoading } = useStats(from_date, to_date, day_start, day_end);
if (isLoading) return <div className="text-center p-4">Loading timetable...</div>;
if (!timetable?.slots || timetable.slots.length === 0) {
return <div className="text-center p-4 text-gray-500">No data available for this period.</div>;
}
// 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 (
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200 overflow-x-auto">
<h3 className="text-lg font-semibold mb-4 text-gray-800">Sleep Timetable</h3>
<div className="min-w-[800px]">
{Object.keys(groupedSlots).map((date) => (
<div key={date} className="mb-6 last:mb-0">
<h4 className="text-sm font-medium text-gray-500 mb-2">{date}</h4>
<div className="flex w-full h-8 gap-1 bg-gray-50 p-1 rounded-lg overflow-hidden">
{groupedSlots[date].map((slot: any) => {
const duration = Math.max(1, timeToMinutes(slot.slot_end) - timeToMinutes(slot.slot_start));
return (
<div
key={`${date}-${slot.slot_start}`}
className={`h-full rounded-sm transition-all duration-300 cursor-help ${
slot.sleeping ? 'bg-blue-900' : 'bg-gray-200'
}`}
style={{ flex: duration }}
title={`${slot.slot_start} - ${slot.slot_end} (${duration}m)`}
>
{/* Only show text if there's enough space */}
<div className="overflow-hidden whitespace-nowrap text-[10px] leading-none flex items-center justify-center h-full px-1">
{duration > 40 && <span className="text-white/70">{slot.slot_start}</span>}
</div>
</div>
);
})}
</div>
</div>
))}
</div>
</div>
);
};
export default Timetable;