ultisuite-client/lib/agenda/use-external-agenda-events.ts
R3D347HR4Y ad1370ea7e
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat: enhance configuration and add new demo layouts
- Introduced turbopack alias for canvas in next.config.mjs.
- Updated package.json scripts for development and branding tasks.
- Added new dependencies for Tiptap extensions.
- Implemented new demo layouts for agenda, contacts, drive, and mail applications.
- Enhanced globals.css for improved theming and splash screen animations.
- Added OAuth callback handling for drive mounts.
- Updated layout components to integrate new demo shells and improve structure.
2026-06-12 19:10:24 +02:00

73 lines
2.4 KiB
TypeScript

"use client"
import { useMemo } from "react"
import { useQueries } from "@tanstack/react-query"
import { format } from "date-fns"
import { expandApiEvents } from "@/lib/agenda/agenda-events"
import { parseIcsFeed } from "@/lib/agenda/agenda-ical-parser"
import type { AgendaEvent } from "@/lib/agenda/agenda-types"
import type { AgendaExternalCalendar as ExternalCalendarConfig } from "@/lib/agenda/agenda-settings-types"
import { externalCalendarToAgendaCalendar } from "@/lib/agenda/agenda-calendar-visibility"
export function externalIcsQueryKey(calendarId: string, from: string, to: string) {
return ["agenda", "external-ics", calendarId, from, to] as const
}
async function fetchExternalIcs(url: string): Promise<string> {
const res = await fetch(`/api/agenda/ical?url=${encodeURIComponent(url)}`)
if (!res.ok) {
throw new Error("Impossible de charger le calendrier externe")
}
return res.text()
}
export function useExternalAgendaEvents(
externalCalendars: ExternalCalendarConfig[],
rangeStart: Date,
rangeEnd: Date,
) {
const from = format(rangeStart, "yyyy-MM-dd")
const to = format(rangeEnd, "yyyy-MM-dd")
const results = useQueries({
queries: externalCalendars.map((cal) => ({
queryKey: externalIcsQueryKey(cal.id, from, to),
staleTime: 5 * 60_000,
queryFn: async () => {
const raw = await fetchExternalIcs(cal.url)
return parseIcsFeed(raw)
},
})),
})
const isLoading = results.some((r) => r.isLoading)
const isError = results.some((r) => r.isError)
const rangeStartMs = rangeStart.getTime()
const rangeEndMs = rangeEnd.getTime()
const resultsFingerprint = useMemo(
() =>
externalCalendars
.map((cal, i) => {
const r = results[i]
return `${cal.id}:${r?.dataUpdatedAt ?? 0}:${r?.fetchStatus ?? "idle"}`
})
.join("|"),
[externalCalendars, results],
)
const events: AgendaEvent[] = useMemo(() => {
const all: AgendaEvent[] = []
externalCalendars.forEach((config, i) => {
const data = results[i]?.data
if (!data) return
const calendar = externalCalendarToAgendaCalendar(config)
all.push(...expandApiEvents(calendar, data, rangeStart, rangeEnd))
})
return all.sort((a, b) => a.start.getTime() - b.start.getTime())
}, [externalCalendars, results, rangeStartMs, rangeEndMs, resultsFingerprint])
return { events, isLoading, isError }
}