"use client" import { useMutation, useQueryClient } from "@tanstack/react-query" import { apiClient } from "@/lib/api/client" import { formatICSDateOnly, formatICSDateTimeUTC } from "@/lib/agenda/agenda-date" import type { AgendaApiEvent, AgendaEventDraft } from "@/lib/agenda/agenda-types" function eventApiPath(davPath: string): string { return `/calendar/events/${davPath.replace(/^\/+/, "")}` } /** Convertit un brouillon UI en payload API (dates ICS). */ export function draftToApiEvent( draft: AgendaEventDraft, existing?: AgendaApiEvent, ): Partial { const start = draft.allDay ? formatICSDateOnly(draft.start) : formatICSDateTimeUTC(draft.start) const end = draft.allDay ? formatICSDateOnly(draft.end) : formatICSDateTimeUTC(draft.end) return { uid: existing?.uid, summary: draft.title.trim() || "(Sans titre)", description: draft.description ?? existing?.description ?? "", location: draft.location ?? existing?.location ?? "", start, end, all_day: draft.allDay, attendees: draft.attendees ?? existing?.attendees ?? [], organizer: existing?.organizer, meet_url: existing?.meet_url, color: draft.color ?? existing?.color, rrule: draft.rrule ?? existing?.rrule ?? "", exdates: existing?.exdates, } } function useInvalidateAgenda() { const queryClient = useQueryClient() return () => { void queryClient.invalidateQueries({ queryKey: ["agenda", "events"] }) } } export function useCreateAgendaEvent() { const invalidate = useInvalidateAgenda() return useMutation({ mutationFn: ({ calendarId, event, }: { calendarId: string event: Partial }) => apiClient.post(`/calendar/${encodeURIComponent(calendarId)}/events`, event), onSuccess: invalidate, }) } export function useUpdateAgendaEvent() { const invalidate = useInvalidateAgenda() return useMutation({ mutationFn: ({ path, etag, event, }: { path: string etag: string event: Partial }) => apiClient.put<{ etag: string }>(eventApiPath(path), event, { "If-Match": etag || "*", }), onSuccess: invalidate, }) } export function useDeleteAgendaEvent() { const invalidate = useInvalidateAgenda() return useMutation({ mutationFn: ({ path }: { path: string }) => apiClient.delete(eventApiPath(path)), onSuccess: invalidate, }) } export function useRespondAgendaInvitation() { const invalidate = useInvalidateAgenda() return useMutation({ mutationFn: ({ path, response, etag, }: { path: string response: "accepted" | "declined" | "tentative" etag?: string }) => apiClient.post<{ etag: string }>( `/calendar/events/response/${path.replace(/^\/+/, "")}`, { response, if_match: etag ?? "" }, ), onSuccess: invalidate, }) } export function useCreateAgendaMeetLink() { const invalidate = useInvalidateAgenda() return useMutation({ mutationFn: ({ path, etag }: { path: string; etag?: string }) => apiClient.post<{ meet_url: string; etag: string }>( `/calendar/events/meet-link/${path.replace(/^\/+/, "")}`, { if_match: etag ?? "" }, ), onSuccess: invalidate, }) } export function useCreateAgendaCalendar() { const queryClient = useQueryClient() return useMutation({ mutationFn: (input: { display_name: string; color?: string }) => apiClient.post<{ id: string }>("/calendar", input), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: ["agenda", "calendars"] }) }, }) } export function useUpdateAgendaCalendar() { const queryClient = useQueryClient() return useMutation({ mutationFn: ({ id, ...input }: { id: string display_name?: string color?: string }) => apiClient.patch(`/calendar/${encodeURIComponent(id)}`, input), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: ["agenda"] }) }, }) } export function useDeleteAgendaCalendar() { const queryClient = useQueryClient() return useMutation({ mutationFn: ({ id }: { id: string }) => apiClient.delete(`/calendar/${encodeURIComponent(id)}`), onSuccess: () => { void queryClient.invalidateQueries({ queryKey: ["agenda"] }) }, }) }