"use client" import { useMemo } from "react" import { useQueries, useQuery } from "@tanstack/react-query" import { format } from "date-fns" import { apiClient } from "@/lib/api/client" import { useAuthReady } from "@/lib/api/use-auth-ready" import { expandApiEvents } from "@/lib/agenda/agenda-events" import type { AgendaCalendar, AgendaCalendarsResponse, AgendaEvent, AgendaEventsResponse, } from "@/lib/agenda/agenda-types" export const agendaCalendarsKey = ["agenda", "calendars"] as const export function agendaEventsKey(calendarId: string, from: string, to: string) { return ["agenda", "events", calendarId, from, to] as const } export function useAgendaCalendars() { const { ready, authenticated } = useAuthReady() return useQuery({ queryKey: agendaCalendarsKey, enabled: ready && authenticated, staleTime: 5 * 60_000, queryFn: async () => { const res = await apiClient.get("/calendar") return res.calendars ?? [] }, }) } /** * Charge et développe les événements de plusieurs agendas sur une fenêtre. * La fenêtre est élargie au mois pour profiter du cache entre vues. */ export function useAgendaEvents( calendars: AgendaCalendar[], rangeStart: Date, rangeEnd: Date, ) { const { ready, authenticated } = useAuthReady() const from = format(rangeStart, "yyyy-MM-dd") const to = format(rangeEnd, "yyyy-MM-dd") const results = useQueries({ queries: calendars.map((cal) => ({ queryKey: agendaEventsKey(cal.id, from, to), enabled: ready && authenticated, staleTime: 30_000, queryFn: async () => { const res = await apiClient.get( `/calendar/${encodeURIComponent(cal.id)}/events`, { from, to, page_size: "500" }, ) return res.events ?? [] }, })), }) const isLoading = results.some((r) => r.isLoading) const isError = results.every((r) => r.isError) && results.length > 0 const events: AgendaEvent[] = useMemo(() => { const all: AgendaEvent[] = [] calendars.forEach((cal, i) => { const data = results[i]?.data if (data) all.push(...expandApiEvents(cal, data, rangeStart, rangeEnd)) }) return all.sort((a, b) => a.start.getTime() - b.start.getTime()) // eslint-disable-next-line react-hooks/exhaustive-deps }, [calendars, rangeStart.getTime(), rangeEnd.getTime(), ...results.map((r) => r.data)]) return { events, isLoading, isError } }