/** * Fetches a `years`-year window of Swedish calendar metadata (röda dagar, * klämdagar, weekends, workspace day overrides) starting at `startYear`. * * Backs both the Kalender page's shading + click-to-override (§3.4/§3.6) and * the Settings red-days list (§3.8) from the same `GET /api/calendar/days` * endpoint — see `app/routers/calendar.py` / ARCHITECTURE.md §13.3. * * There is no shared cache/invalidation layer (no TanStack Query) here, so a * day-override mutation elsewhere does not automatically make this window * stale — callers that mutate overrides (see `useDayOverrides`) must * explicitly call `refetch` afterwards or the calendar grid will keep * showing the pre-mutation shading until a full reload. */ import { useCallback, useEffect, useState } from 'react' import * as api from '@/services/api' import type { CalendarWindow } from '@/types' interface UseCalendarDaysResult { data: CalendarWindow | null isLoading: boolean error: string | null refetch: () => Promise } export function useCalendarDays( workspaceId: string, startYear: number, years: number = 4, ): UseCalendarDaysResult { const [data, setData] = useState(null) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) const fetchWindow = useCallback(async () => { if (!workspaceId) return setIsLoading(true) setError(null) try { const result = await api.getCalendarDays(workspaceId, startYear, years) setData(result) } catch (err: unknown) { setError(err instanceof Error ? err.message : 'Failed to load calendar days') } finally { setIsLoading(false) } }, [workspaceId, startYear, years]) useEffect(() => { void fetchWindow() }, [fetchWindow]) return { data, isLoading, error, refetch: fetchWindow } }