timetable maybe working, very cloase at least

This commit is contained in:
2026-06-03 22:14:18 +02:00
parent db0f717560
commit 7d4e2a376c
6 changed files with 126 additions and 136 deletions
+8 -9
View File
@@ -32,9 +32,7 @@ export function localToUTC(localValue: string): string {
}
async function fetchStats<T>(endpoint: string, from_date: string, to_date: string, extraParams: Record<string, string> = {}): Promise<T> {
const fromDT = new Date(`${from_date}T00:00:00`).toISOString();
const toDT = new Date(`${to_date}T23:59:59`).toISOString();
const params = new URLSearchParams({ from_date: fromDT, to_date: toDT, ...extraParams });
const params = new URLSearchParams({ from_date, to_date, ...extraParams });
const response = await fetch(`${BASE_URL}/api/stats/${endpoint}?${params.toString()}`);
if (!response.ok) throw new Error(`Failed to fetch ${endpoint}`);
return response.json();
@@ -44,18 +42,19 @@ export async function fetchSummary(from_date: string, to_date: string): Promise<
return fetchStats('summary', from_date, to_date);
}
export async function fetchDailySummary(from_date: string, to_date: string, day_start: string, day_end: string): Promise<DailySummaryResponse> {
return fetchStats('daily-summary', from_date, to_date, { day_start, day_end });
export async function fetchDailySummary(from_date: string, to_date: string, day_start: string, day_end: string, timezone_offset = 0): Promise<DailySummaryResponse> {
return fetchStats('daily-summary', from_date, to_date, { day_start, day_end, timezone_offset: timezone_offset.toString() });
}
export async function fetchTimetable(from_date: string, to_date: string, day_start: string, day_end: string): Promise<TimetableResponse> {
return fetchStats('timetable', from_date, to_date, { day_start, day_end });
export async function fetchTimetable(from_date: string, to_date: string, day_start: string, day_end: string, timezone_offset = 0): Promise<TimetableResponse> {
return fetchStats('timetable', from_date, to_date, { day_start, day_end, timezone_offset: timezone_offset.toString() });
}
export async function fetchWakeSleepTimes(from_date: string, to_date: string, wakeup_ref: string, bedtime_ref: string): Promise<WakeupBedtimeResponse> {
export async function fetchWakeSleepTimes(from_date: string, to_date: string, wakeup_ref: string, bedtime_ref: string, timezone_offset = 0): Promise<WakeupBedtimeResponse> {
return fetchStats('wake-sleep-times', from_date, to_date, {
wakeup_ref: localHHMMToUTCHHMM(wakeup_ref),
bedtime_ref: localHHMMToUTCHHMM(bedtime_ref)
bedtime_ref: localHHMMToUTCHHMM(bedtime_ref),
timezone_offset: timezone_offset.toString()
});
}
@@ -1,6 +1,6 @@
import { useMemo, useState, useEffect, Fragment } from 'react';
import { useStats } from '../../hooks/useStats';
import { timeToMinutes, adjustForTimezone } from '../../utils/time';
import { timeToMinutes } from '../../utils/time';
interface TimetableProps {
from_date: string;
@@ -27,7 +27,8 @@ function formatTimeLabel(mins: number) {
}
const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) => {
const { timetable, isLoading } = useStats(from_date, to_date, day_start, day_end);
const timezoneOffset = typeof window !== 'undefined' ? new Date().getTimezoneOffset() : 0;
const { timetable, isLoading } = useStats(from_date, to_date, day_start, day_end, '04:00', '19:00', timezoneOffset);
const [selectedDayIndex, setSelectedDayIndex] = useState(0);
const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1024);
@@ -106,8 +107,8 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
return timetable.slots.some((slot) => {
if (slot.date !== date || !slot.sleeping) return false;
const sStart = adjustForTimezone(timeToMinutes(slot.slot_start));
const sEnd = adjustForTimezone(timeToMinutes(slot.slot_end));
const sStart = timeToMinutes(slot.slot_start);
const sEnd = timeToMinutes(slot.slot_end);
if (sEnd <= sStart) {
const overlap1 = Math.max(sStart, intervalStart) < Math.min(1440, intervalEnd);
@@ -203,6 +204,7 @@ const Timetable = ({ from_date, to_date, day_start, day_end }: TimetableProps) =
return (
<div
key={`${day}-${step}`}
data-testid={`cell-${day}-${formatTimeLabel(step)}`}
className={`h-2 w-full border border-gray-100 ${sleeping ? 'bg-green-500' : 'bg-gray-50'}`}
/>
);
+8 -7
View File
@@ -15,21 +15,22 @@ export function useStats(
day_start = '07:00',
day_end = '20:00',
wakeup_ref = '04:00',
bedtime_ref = '19:00'
bedtime_ref = '19:00',
timezoneOffset = 0
) {
const dailySummaryQuery = useQuery<DailySummaryResponse>({
queryKey: ['dailySummary', from_date, to_date, day_start, day_end],
queryFn: () => fetchDailySummary(from_date, to_date, day_start, day_end),
queryKey: ['dailySummary', from_date, to_date, day_start, day_end, timezoneOffset],
queryFn: () => fetchDailySummary(from_date, to_date, day_start, day_end, timezoneOffset),
});
const timetableQuery = useQuery<TimetableResponse>({
queryKey: ['timetable', from_date, to_date, day_start, day_end],
queryFn: () => fetchTimetable(from_date, to_date, day_start, day_end),
queryKey: ['timetable', from_date, to_date, day_start, day_end, timezoneOffset],
queryFn: () => fetchTimetable(from_date, to_date, day_start, day_end, timezoneOffset),
});
const wakeupBedtimeQuery = useQuery<WakeupBedtimeResponse>({
queryKey: ['wakeSleepTimes', from_date, to_date, wakeup_ref, bedtime_ref],
queryFn: () => fetchWakeSleepTimes(from_date, to_date, wakeup_ref, bedtime_ref),
queryKey: ['wakeSleepTimes', from_date, to_date, wakeup_ref, bedtime_ref, timezoneOffset],
queryFn: () => fetchWakeSleepTimes(from_date, to_date, wakeup_ref, bedtime_ref, timezoneOffset),
});
return {