"use client"; import { ApiResponse } from "@/types/types"; import request from "@/lib/request"; import "@schedule-x/theme-shadcn/dist/index.css"; import { useNextCalendarApp, ScheduleXCalendar } from "@schedule-x/react"; import { createEventsServicePlugin } from "@schedule-x/events-service"; import { createDragAndDropPlugin } from "@schedule-x/drag-and-drop"; import { createResizePlugin } from "@schedule-x/resize"; import { createEventRecurrencePlugin } from "@schedule-x/event-recurrence"; import { createViewDay, createViewWeek } from "@schedule-x/calendar"; import { useEffect, useState } from "react"; import { format } from "date-fns"; import { Dialog, DialogProps } from "@radix-ui/react-dialog"; import { DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { KeyedMutator } from "swr"; import { getCookie } from "cookies-next"; import { useTheme } from "next-themes"; import { EventForm, eventFormSchema, EventFormValues } from "./event-dialog"; import ICalendarEvent from "@/interfaces/ICalendarEvent"; import { UseFormReturn } from "react-hook-form"; import mapFrequencyToRrule from "@/lib/mapFrequencyToRrule"; const Planning: React.FC<{ events: ICalendarEvent[]; mutate?: KeyedMutator>; }> = ({ events, mutate }) => { const { resolvedTheme } = useTheme(); console.log(resolvedTheme); const isConnected = getCookie("auth_token"); const plugins = isConnected ? [ createEventsServicePlugin(), createDragAndDropPlugin(), createResizePlugin(), createEventRecurrencePlugin(), ] : []; const [eventSelected, setEventSelected] = useState( null, ); const [newEvent, setNewEvent] = useState | null>( null, ); const handleEventUpdate = async ( eventSelected: ICalendarEvent | Omit, ) => { const event = { ...eventSelected, start: `${new Date(eventSelected.start).toISOString()}`, end: `${new Date(eventSelected.end).toISOString()}`, } as ICalendarEvent; try { const res = await request(`/events/${event.id}/update`, { method: "PATCH", body: event, requiresAuth: true, csrfToken: false, }); if (res.status === "Error") { // calendar?.events?.update(oldEvent); } } catch (e) { console.log(e); } }; const calendar = useNextCalendarApp( { theme: "shadcn", views: [createViewDay(), createViewWeek()], defaultView: "week", isDark: resolvedTheme === "dark" ? true : false, isResponsive: true, locale: "fr-FR", dayBoundaries: { start: "06:00", end: "00:00", }, events: events.map((event) => ({ ...event, start: format(new Date(event.start), "yyyy-MM-dd HH:mm"), end: format(new Date(event.end), "yyyy-MM-dd HH:mm"), })), callbacks: { onEventClick(event, e) { setEventSelected(event as ICalendarEvent); }, async onEventUpdate(newEvent) { await handleEventUpdate(newEvent as ICalendarEvent); }, }, }, plugins, ); useEffect(() => { calendar?.events.getAll(); }, []); useEffect(() => { calendar?.setTheme(resolvedTheme === "dark" ? "dark" : "light"); }, [resolvedTheme]); const AddButton: React.FC = () => ( ); return (
{newEvent && ( { setNewEvent((e) => (open ? e : null)); }} onAdd={async (formValues) => { const rrule = mapFrequencyToRrule( formValues.frequency, formValues.frequencyEndDate, ); const [sHours, sMinutes] = formValues.startTime.split(":"); formValues.startDate.setHours( parseInt(sHours), parseInt(sMinutes), ); const [eHours, eMinutes] = formValues.endTime.split(":"); formValues.endDate.setHours( parseInt(eHours), parseInt(eMinutes), ); const event: Omit = { ...newEvent, start: formValues.startDate.toISOString(), end: formValues.endDate.toISOString(), title: `${formValues.title}`, fullday: formValues.fullDay, rrule: rrule, isVisible: formValues.isVisible, }; const res = await request(`/events/new`, { method: "POST", body: event, requiresAuth: true, csrfToken: false, }); if (res.status === "Error") { console.log("Error"); } if (res.status === "Success") { mutate?.(); console.log("Success"); } }} event={newEvent} /> )} {eventSelected && ( { setEventSelected((e) => (open ? e : null)); }} event={eventSelected} onDelete={async (id) => { calendar?.events?.remove(id); try { const res = await request( `/events/${id}/delete`, { method: "DELETE", requiresAuth: false, csrfToken: false, }, ); if (res.status === "Error") { console.log("Error"); } if (res.status === "Success") { console.log("Success"); } } catch (e) { console.log(e); } setEventSelected(null); }} onUpdate={async (formValues) => { const rrule = mapFrequencyToRrule( formValues.frequency, formValues.frequencyEndDate, ); const [sHours, sMinutes] = formValues.startTime.split(":"); formValues.startDate.setHours( parseInt(sHours), parseInt(sMinutes), ); const [eHours, eMinutes] = formValues.endTime.split(":"); formValues.endDate.setHours( parseInt(eHours), parseInt(eMinutes), ); const event: ICalendarEvent = { ...eventSelected, start: formValues.startDate.toISOString(), end: formValues.endDate.toISOString(), title: `${formValues.title}`, fullday: formValues.fullDay, rrule: rrule, isVisible: formValues.isVisible, }; await handleEventUpdate(event); setEventSelected(null); }} /> )}
); }; const EventDialog: React.FC< { onDelete?: (id: string) => void; onUpdate?: (formValues: EventFormValues) => void; onAdd?: (formValues: EventFormValues) => void; event: ICalendarEvent | Omit; } & DialogProps > = ({ open, onOpenChange, onDelete, onUpdate, onAdd, event }) => { const [form, setForm] = useState>(); const handleOnAdd = (data: EventFormValues) => { onAdd?.(data); }; const onSubmit = (data: EventFormValues) => { try { const validatedData = eventFormSchema.parse(data); handleOnAdd(data); } catch (e) { console.error(e); } }; return ( {event.title} {event.description} {onUpdate && ( )} {onDelete && ( )} {onAdd && !onUpdate && !onDelete && ( )} ); }; export default Planning;