calendar 14
This commit is contained in:
parent
7dab3da369
commit
0d78cc4e6a
@ -149,31 +149,29 @@ export async function DELETE(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Vérifier que le calendrier existe et appartient à l'utilisateur
|
// Verify calendar ownership
|
||||||
const existingCalendar = await prisma.calendar.findUnique({
|
const calendar = await prisma.calendar.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: params.id,
|
id: params.id,
|
||||||
|
userId: session.user.username,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!existingCalendar) {
|
if (!calendar) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Calendrier non trouvé" },
|
{ error: "Calendrier non trouvé ou non autorisé" },
|
||||||
{ status: 404 }
|
{ status: 404 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingCalendar.userId !== session.user.username) {
|
// Delete the calendar (this will also delete all associated events due to the cascade delete)
|
||||||
return NextResponse.json({ error: "Non autorisé" }, { status: 403 });
|
|
||||||
}
|
|
||||||
|
|
||||||
await prisma.calendar.delete({
|
await prisma.calendar.delete({
|
||||||
where: {
|
where: {
|
||||||
id: params.id,
|
id: params.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return new NextResponse(null, { status: 204 });
|
return NextResponse.json({ success: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erreur lors de la suppression du calendrier:", error);
|
console.error("Erreur lors de la suppression du calendrier:", error);
|
||||||
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
|
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
|
||||||
|
|||||||
@ -14,15 +14,17 @@ export async function DELETE(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Verify event ownership
|
// Verify event ownership through calendar
|
||||||
const event = await prisma.event.findFirst({
|
const event = await prisma.event.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: params.id,
|
id: params.id,
|
||||||
userId: session.user.username,
|
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
calendar: true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!event) {
|
if (!event || event.calendar.userId !== session.user.username) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Événement non trouvé ou non autorisé" },
|
{ error: "Événement non trouvé ou non autorisé" },
|
||||||
{ status: 404 }
|
{ status: 404 }
|
||||||
|
|||||||
@ -44,8 +44,11 @@ export async function POST(req: NextRequest) {
|
|||||||
end: new Date(end),
|
end: new Date(end),
|
||||||
isAllDay: allDay || false,
|
isAllDay: allDay || false,
|
||||||
location,
|
location,
|
||||||
calendarId,
|
calendar: {
|
||||||
userId: session.user.username,
|
connect: {
|
||||||
|
id: calendarId
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -74,15 +77,22 @@ export async function PUT(req: NextRequest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify event ownership
|
// Verify calendar ownership
|
||||||
const existingEvent = await prisma.event.findFirst({
|
const calendar = await prisma.calendar.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id: calendarId,
|
||||||
userId: session.user.username,
|
userId: session.user.username,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
events: {
|
||||||
|
where: {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!existingEvent) {
|
if (!calendar || calendar.events.length === 0) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: "Événement non trouvé ou non autorisé" },
|
{ error: "Événement non trouvé ou non autorisé" },
|
||||||
{ status: 404 }
|
{ status: 404 }
|
||||||
@ -98,7 +108,11 @@ export async function PUT(req: NextRequest) {
|
|||||||
end: new Date(end),
|
end: new Date(end),
|
||||||
isAllDay: allDay || false,
|
isAllDay: allDay || false,
|
||||||
location,
|
location,
|
||||||
calendarId,
|
calendar: {
|
||||||
|
connect: {
|
||||||
|
id: calendarId
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -79,10 +79,11 @@ interface CalendarDialogProps {
|
|||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: (calendarData: Partial<Calendar>) => Promise<void>;
|
onSave: (calendarData: Partial<Calendar>) => Promise<void>;
|
||||||
|
onDelete?: (calendarId: string) => Promise<void>;
|
||||||
initialData?: Partial<Calendar>;
|
initialData?: Partial<Calendar>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogProps) {
|
function CalendarDialog({ open, onClose, onSave, onDelete, initialData }: CalendarDialogProps) {
|
||||||
const [name, setName] = useState(initialData?.name || "");
|
const [name, setName] = useState(initialData?.name || "");
|
||||||
const [color, setColor] = useState(initialData?.color || "#4f46e5");
|
const [color, setColor] = useState(initialData?.color || "#4f46e5");
|
||||||
const [description, setDescription] = useState(initialData?.description || "");
|
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 = () => {
|
const resetForm = () => {
|
||||||
setName("");
|
setName("");
|
||||||
setColor("#4f46e5");
|
setColor("#4f46e5");
|
||||||
@ -229,30 +244,41 @@ function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogPr
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter className="mt-6 border-t border-gray-100 pt-4">
|
<DialogFooter className="mt-6 border-t border-gray-100 pt-4">
|
||||||
<div className="flex gap-3 w-full sm:justify-end">
|
<div className="flex justify-between w-full">
|
||||||
<Button
|
{initialData?.id && (
|
||||||
type="button"
|
<Button
|
||||||
variant="outline"
|
type="button"
|
||||||
onClick={onClose}
|
variant="destructive"
|
||||||
disabled={isSubmitting}
|
onClick={handleDelete}
|
||||||
className="rounded-lg border-gray-300 text-gray-700 hover:bg-gray-50"
|
disabled={isSubmitting}
|
||||||
>
|
>
|
||||||
<X className="w-4 h-4 mr-2" />
|
<X className="w-4 h-4 mr-2" />
|
||||||
Annuler
|
Supprimer
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
)}
|
||||||
type="submit"
|
<div className="flex gap-3">
|
||||||
disabled={!name || isSubmitting}
|
<Button
|
||||||
className="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white"
|
type="button"
|
||||||
>
|
variant="outline"
|
||||||
<Check className="w-4 h-4 mr-2" />
|
onClick={onClose}
|
||||||
{isSubmitting
|
disabled={isSubmitting}
|
||||||
? "Enregistrement..."
|
className="rounded-lg border-gray-300 text-gray-700 hover:bg-gray-50"
|
||||||
: initialData?.id
|
>
|
||||||
? "Mettre à jour"
|
Annuler
|
||||||
: "Créer"
|
</Button>
|
||||||
}
|
<Button
|
||||||
</Button>
|
type="submit"
|
||||||
|
disabled={!name || isSubmitting}
|
||||||
|
className="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white"
|
||||||
|
>
|
||||||
|
{isSubmitting
|
||||||
|
? "Enregistrement..."
|
||||||
|
: initialData?.id
|
||||||
|
? "Mettre à jour"
|
||||||
|
: "Créer"
|
||||||
|
}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</form>
|
</form>
|
||||||
@ -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 handleDateSelect = (selectInfo: any) => {
|
||||||
const startDate = new Date(selectInfo.start);
|
const startDate = new Date(selectInfo.start);
|
||||||
const endDate = new Date(selectInfo.end);
|
const endDate = new Date(selectInfo.end);
|
||||||
@ -730,6 +783,7 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
open={isCalendarModalOpen}
|
open={isCalendarModalOpen}
|
||||||
onClose={() => setIsCalendarModalOpen(false)}
|
onClose={() => setIsCalendarModalOpen(false)}
|
||||||
onSave={handleCalendarSave}
|
onSave={handleCalendarSave}
|
||||||
|
onDelete={handleCalendarDelete}
|
||||||
initialData={selectedCalendar || undefined}
|
initialData={selectedCalendar || undefined}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user