From 0d78cc4e6ab2837119ab0268809390ce41f43a51 Mon Sep 17 00:00:00 2001 From: Alma Date: Sun, 13 Apr 2025 14:16:02 +0200 Subject: [PATCH] calendar 14 --- app/api/calendars/[id]/route.ts | 16 ++-- app/api/events/[id]/route.ts | 8 +- app/api/events/route.ts | 28 +++++-- components/calendar/calendar-client.tsx | 104 ++++++++++++++++++------ 4 files changed, 112 insertions(+), 44 deletions(-) diff --git a/app/api/calendars/[id]/route.ts b/app/api/calendars/[id]/route.ts index fefca9f3..a7630d55 100644 --- a/app/api/calendars/[id]/route.ts +++ b/app/api/calendars/[id]/route.ts @@ -149,31 +149,29 @@ export async function DELETE( } try { - // Vérifier que le calendrier existe et appartient à l'utilisateur - const existingCalendar = await prisma.calendar.findUnique({ + // Verify calendar ownership + const calendar = await prisma.calendar.findFirst({ where: { id: params.id, + userId: session.user.username, }, }); - if (!existingCalendar) { + if (!calendar) { return NextResponse.json( - { error: "Calendrier non trouvé" }, + { error: "Calendrier non trouvé ou non autorisé" }, { status: 404 } ); } - if (existingCalendar.userId !== session.user.username) { - return NextResponse.json({ error: "Non autorisé" }, { status: 403 }); - } - + // Delete the calendar (this will also delete all associated events due to the cascade delete) await prisma.calendar.delete({ where: { id: params.id, }, }); - return new NextResponse(null, { status: 204 }); + return NextResponse.json({ success: true }); } catch (error) { console.error("Erreur lors de la suppression du calendrier:", error); return NextResponse.json({ error: "Erreur serveur" }, { status: 500 }); diff --git a/app/api/events/[id]/route.ts b/app/api/events/[id]/route.ts index a31a7ecc..6eab7ba9 100644 --- a/app/api/events/[id]/route.ts +++ b/app/api/events/[id]/route.ts @@ -14,15 +14,17 @@ export async function DELETE( } try { - // Verify event ownership + // Verify event ownership through calendar const event = await prisma.event.findFirst({ where: { id: params.id, - userId: session.user.username, }, + include: { + calendar: true + } }); - if (!event) { + if (!event || event.calendar.userId !== session.user.username) { return NextResponse.json( { error: "Événement non trouvé ou non autorisé" }, { status: 404 } diff --git a/app/api/events/route.ts b/app/api/events/route.ts index 9e40c785..02ec5954 100644 --- a/app/api/events/route.ts +++ b/app/api/events/route.ts @@ -44,8 +44,11 @@ export async function POST(req: NextRequest) { end: new Date(end), isAllDay: allDay || false, location, - calendarId, - userId: session.user.username, + calendar: { + connect: { + id: calendarId + } + } }, }); @@ -74,15 +77,22 @@ export async function PUT(req: NextRequest) { ); } - // Verify event ownership - const existingEvent = await prisma.event.findFirst({ + // Verify calendar ownership + const calendar = await prisma.calendar.findFirst({ where: { - id, + id: calendarId, userId: session.user.username, }, + include: { + events: { + where: { + id + } + } + } }); - if (!existingEvent) { + if (!calendar || calendar.events.length === 0) { return NextResponse.json( { error: "Événement non trouvé ou non autorisé" }, { status: 404 } @@ -98,7 +108,11 @@ export async function PUT(req: NextRequest) { end: new Date(end), isAllDay: allDay || false, location, - calendarId, + calendar: { + connect: { + id: calendarId + } + } }, }); diff --git a/components/calendar/calendar-client.tsx b/components/calendar/calendar-client.tsx index 5fc18a09..ca0043e6 100644 --- a/components/calendar/calendar-client.tsx +++ b/components/calendar/calendar-client.tsx @@ -79,10 +79,11 @@ interface CalendarDialogProps { open: boolean; onClose: () => void; onSave: (calendarData: Partial) => Promise; + onDelete?: (calendarId: string) => Promise; initialData?: Partial; } -function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogProps) { +function CalendarDialog({ open, onClose, onSave, onDelete, initialData }: CalendarDialogProps) { const [name, setName] = useState(initialData?.name || ""); const [color, setColor] = useState(initialData?.color || "#4f46e5"); const [description, setDescription] = useState(initialData?.description || ""); @@ -117,6 +118,20 @@ function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogPr } }; + const handleDelete = async () => { + if (!initialData?.id || !onDelete) return; + + setIsSubmitting(true); + try { + await onDelete(initialData.id); + resetForm(); + } catch (error) { + console.error("Erreur lors de la suppression du calendrier:", error); + } finally { + setIsSubmitting(false); + } + }; + const resetForm = () => { setName(""); setColor("#4f46e5"); @@ -229,30 +244,41 @@ function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogPr -
- - +
+ {initialData?.id && ( + + )} +
+ + +
@@ -494,6 +520,33 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend } }; + const handleCalendarDelete = async (calendarId: string) => { + try { + setLoading(true); + const response = await fetch(`/api/calendars/${calendarId}`, { + method: "DELETE", + }); + + if (!response.ok) { + throw new Error("Failed to delete calendar"); + } + + await fetchCalendars(); + setIsCalendarModalOpen(false); + + // If the deleted calendar was selected, select another one + if (selectedCalendarId === calendarId) { + const remainingCalendars = calendars.filter(cal => cal.id !== calendarId); + setSelectedCalendarId(remainingCalendars[0]?.id || ""); + } + } catch (error) { + console.error("Error deleting calendar:", error); + setError(error instanceof Error ? error.message : "Failed to delete calendar"); + } finally { + setLoading(false); + } + }; + const handleDateSelect = (selectInfo: any) => { const startDate = new Date(selectInfo.start); const endDate = new Date(selectInfo.end); @@ -730,6 +783,7 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend open={isCalendarModalOpen} onClose={() => setIsCalendarModalOpen(false)} onSave={handleCalendarSave} + onDelete={handleCalendarDelete} initialData={selectedCalendar || undefined} />