bugfixes and some redesign
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useStats } from '../../hooks/useStats';
|
||||
import { timeToMinutes } from '../../utils/time';
|
||||
import { timeToMinutes, formatMinutesAfter } from '../../utils/time';
|
||||
|
||||
interface TimetableProps {
|
||||
from_date: string;
|
||||
@@ -17,6 +17,11 @@ const Timetable: React.FC<TimetableProps> = ({ from_date, to_date, day_start, da
|
||||
return <div className="text-center p-4 text-gray-500">No data available for this period.</div>;
|
||||
}
|
||||
|
||||
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] = [];
|
||||
@@ -28,29 +33,53 @@ const Timetable: React.FC<TimetableProps> = ({ from_date, to_date, day_start, da
|
||||
<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">
|
||||
{Object.keys(groupedSlots).sort((a, b) => b.localeCompare(a)).map((date) => (
|
||||
<div key={date} className="mb-8 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));
|
||||
<div className="relative w-full">
|
||||
{/* The progress bar container */}
|
||||
<div className="relative h-8 bg-gray-50 p-1 rounded-lg overflow-hidden">
|
||||
{groupedSlots[date].map((slot: any) => {
|
||||
let sStart = timeToMinutes(slot.slot_start);
|
||||
if (sStart < startMins) sStart += 1440;
|
||||
|
||||
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>}
|
||||
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 (
|
||||
<div
|
||||
key={`${date}-${slot.slot_start}`}
|
||||
className={`absolute h-full rounded-sm transition-all duration-300 cursor-help ${
|
||||
slot.sleeping ? 'bg-blue-900' : 'bg-gray-200'
|
||||
}`}
|
||||
style={{ left: `${left}%`, width: `${width}%` }}
|
||||
title={`${slot.slot_start} - ${slot.slot_end}`}
|
||||
>
|
||||
{/* 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 text-white/70">
|
||||
{width > 15 && <span>{slot.slot_start}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Time hints below the bar */}
|
||||
<div className="flex justify-between mt-1 px-1 text-[10px] text-gray-400">
|
||||
{Array.from({ length: Math.ceil(totalDayMinutes / 120) + 1 }).map((_, i) => {
|
||||
const minsOffset = i * 120;
|
||||
if (minsOffset > totalDayMinutes) return null;
|
||||
return (
|
||||
<span key={i} className="w-0 min-w-[30px] text-center">
|
||||
{formatMinutesAfter(minsOffset, day_start)}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@@ -60,3 +89,4 @@ const Timetable: React.FC<TimetableProps> = ({ from_date, to_date, day_start, da
|
||||
};
|
||||
|
||||
export default Timetable;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user