calendar 13
This commit is contained in:
parent
04d266614c
commit
7dab3da369
@ -29,6 +29,13 @@ export async function GET(req: NextRequest) {
|
|||||||
where: {
|
where: {
|
||||||
userId: session.user.username,
|
userId: session.user.username,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
events: {
|
||||||
|
orderBy: {
|
||||||
|
start: 'asc'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "desc",
|
createdAt: "desc",
|
||||||
},
|
},
|
||||||
|
|||||||
43
app/api/events/[id]/route.ts
Normal file
43
app/api/events/[id]/route.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { getServerSession } from "next-auth/next";
|
||||||
|
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
|
||||||
|
import { prisma } from "@/lib/prisma";
|
||||||
|
|
||||||
|
export async function DELETE(
|
||||||
|
req: NextRequest,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
|
||||||
|
if (!session?.user?.username) {
|
||||||
|
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Verify event ownership
|
||||||
|
const event = await prisma.event.findFirst({
|
||||||
|
where: {
|
||||||
|
id: params.id,
|
||||||
|
userId: session.user.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!event) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Événement non trouvé ou non autorisé" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.event.delete({
|
||||||
|
where: {
|
||||||
|
id: params.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la suppression de l'événement:", error);
|
||||||
|
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
110
app/api/events/route.ts
Normal file
110
app/api/events/route.ts
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { getServerSession } from "next-auth/next";
|
||||||
|
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
|
||||||
|
import { prisma } from "@/lib/prisma";
|
||||||
|
|
||||||
|
export async function POST(req: NextRequest) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
|
||||||
|
if (!session?.user?.username) {
|
||||||
|
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { title, description, start, end, allDay, location, calendarId } = await req.json();
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
if (!title || !start || !end || !calendarId) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Titre, début, fin et calendrier sont requis" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify calendar ownership
|
||||||
|
const calendar = await prisma.calendar.findFirst({
|
||||||
|
where: {
|
||||||
|
id: calendarId,
|
||||||
|
userId: session.user.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!calendar) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Calendrier non trouvé ou non autorisé" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const event = await prisma.event.create({
|
||||||
|
data: {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
start: new Date(start),
|
||||||
|
end: new Date(end),
|
||||||
|
isAllDay: allDay || false,
|
||||||
|
location,
|
||||||
|
calendarId,
|
||||||
|
userId: session.user.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(event, { status: 201 });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la création de l'événement:", error);
|
||||||
|
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function PUT(req: NextRequest) {
|
||||||
|
const session = await getServerSession(authOptions);
|
||||||
|
|
||||||
|
if (!session?.user?.username) {
|
||||||
|
return NextResponse.json({ error: "Non authentifié" }, { status: 401 });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { id, title, description, start, end, allDay, location, calendarId } = await req.json();
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
if (!id || !title || !start || !end || !calendarId) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "ID, titre, début, fin et calendrier sont requis" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify event ownership
|
||||||
|
const existingEvent = await prisma.event.findFirst({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
userId: session.user.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!existingEvent) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Événement non trouvé ou non autorisé" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const event = await prisma.event.update({
|
||||||
|
where: { id },
|
||||||
|
data: {
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
start: new Date(start),
|
||||||
|
end: new Date(end),
|
||||||
|
isAllDay: allDay || false,
|
||||||
|
location,
|
||||||
|
calendarId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(event);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erreur lors de la mise à jour de l'événement:", error);
|
||||||
|
return NextResponse.json({ error: "Erreur serveur" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -446,6 +446,7 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
const response = await fetch("/api/calendars");
|
const response = await fetch("/api/calendars");
|
||||||
if (!response.ok) throw new Error("Failed to fetch calendars");
|
if (!response.ok) throw new Error("Failed to fetch calendars");
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
console.log("Fetched calendars:", data); // Debug log
|
||||||
setCalendars(data.map((cal: Calendar & { events: Event[] }) => ({
|
setCalendars(data.map((cal: Calendar & { events: Event[] }) => ({
|
||||||
...cal,
|
...cal,
|
||||||
events: cal.events || []
|
events: cal.events || []
|
||||||
@ -597,6 +598,26 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add a calendar selector component
|
||||||
|
const CalendarSelector = () => (
|
||||||
|
<div className="flex items-center gap-4 mb-4">
|
||||||
|
{calendars.map((calendar) => (
|
||||||
|
<Button
|
||||||
|
key={calendar.id}
|
||||||
|
variant={calendar.id === selectedCalendarId ? "secondary" : "ghost"}
|
||||||
|
className="flex items-center gap-2"
|
||||||
|
onClick={() => setSelectedCalendarId(calendar.id)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="w-3 h-3 rounded-full"
|
||||||
|
style={{ backgroundColor: calendar.color }}
|
||||||
|
/>
|
||||||
|
<span>{calendar.name}</span>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Card className="p-4">
|
<Card className="p-4">
|
||||||
@ -658,6 +679,8 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<CalendarSelector />
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="h-96 flex items-center justify-center">
|
<div className="h-96 flex items-center justify-center">
|
||||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||||
|
|||||||
BIN
node_modules/fsevents/fsevents.node
generated
vendored
BIN
node_modules/fsevents/fsevents.node
generated
vendored
Binary file not shown.
@ -32,8 +32,10 @@ model Event {
|
|||||||
isAllDay Boolean @default(false)
|
isAllDay Boolean @default(false)
|
||||||
calendar Calendar @relation(fields: [calendarId], references: [id], onDelete: Cascade)
|
calendar Calendar @relation(fields: [calendarId], references: [id], onDelete: Cascade)
|
||||||
calendarId String
|
calendarId String
|
||||||
|
userId String
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
@@index([calendarId])
|
@@index([calendarId])
|
||||||
|
@@index([userId])
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user