159 lines
4.3 KiB
TypeScript
159 lines
4.3 KiB
TypeScript
"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<AgendaApiEvent> {
|
|
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<AgendaApiEvent>
|
|
}) =>
|
|
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<AgendaApiEvent>
|
|
}) =>
|
|
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"] })
|
|
},
|
|
})
|
|
}
|