From 2170594bc49940eccc44efd7c8e352fe66cb17a0 Mon Sep 17 00:00:00 2001 From: Alma Date: Sun, 13 Apr 2025 12:36:50 +0200 Subject: [PATCH] calendar --- .env | 2 +- app/api/calendar/route.ts | 135 ++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 17 +++++ prisma/schema.prisma | 14 ++-- 4 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 app/api/calendar/route.ts create mode 100644 docker-compose.yml diff --git a/.env b/.env index b44f5b7d..43b38314 100644 --- a/.env +++ b/.env @@ -9,7 +9,7 @@ KEYCLOAK_BASE_URL=https://connect.slm-lab.net NEXTCLOUD_URL=https://espace.slm-lab.net -DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?schema=public" +DATABASE_URL="postgresql://postgres:postgres@localhost:5432/calendar_db?schema=public" # Sidebar iframes NEXT_PUBLIC_IFRAME_DIARY_URL=https://espace.slm-lab.net/apps/diary diff --git a/app/api/calendar/route.ts b/app/api/calendar/route.ts new file mode 100644 index 00000000..360623d2 --- /dev/null +++ b/app/api/calendar/route.ts @@ -0,0 +1,135 @@ +import { NextResponse } from "next/server"; +import { getServerSession } from "next-auth/next"; +import { authOptions } from "@/app/api/auth/[...nextauth]/route"; +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +// GET events +export async function GET(req: Request) { + try { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const { searchParams } = new URL(req.url); + const start = searchParams.get("start"); + const end = searchParams.get("end"); + + const events = await prisma.event.findMany({ + where: { + userId: session.user.id, + ...(start && end + ? { + start: { + gte: new Date(start), + }, + end: { + lte: new Date(end), + }, + } + : {}), + }, + orderBy: { + start: "asc", + }, + }); + + return NextResponse.json(events); + } catch (error) { + console.error("Error fetching events:", error); + return NextResponse.json( + { error: "Error fetching events" }, + { status: 500 } + ); + } +} + +// POST new event +export async function POST(req: Request) { + try { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const body = await req.json(); + const event = await prisma.event.create({ + data: { + ...body, + userId: session.user.id, + }, + }); + + return NextResponse.json(event); + } catch (error) { + console.error("Error creating event:", error); + return NextResponse.json( + { error: "Error creating event" }, + { status: 500 } + ); + } +} + +// PUT update event +export async function PUT(req: Request) { + try { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const body = await req.json(); + const { id, ...data } = body; + + const event = await prisma.event.update({ + where: { + id, + }, + data, + }); + + return NextResponse.json(event); + } catch (error) { + console.error("Error updating event:", error); + return NextResponse.json( + { error: "Error updating event" }, + { status: 500 } + ); + } +} + +// DELETE event +export async function DELETE(req: Request) { + try { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const { searchParams } = new URL(req.url); + const id = searchParams.get("id"); + + if (!id) { + return NextResponse.json( + { error: "Event ID is required" }, + { status: 400 } + ); + } + + await prisma.event.delete({ + where: { + id, + }, + }); + + return NextResponse.json({ success: true }); + } catch (error) { + console.error("Error deleting event:", error); + return NextResponse.json( + { error: "Error deleting event" }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..3d94cfc4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' +services: + db: + image: postgres:15 + restart: always + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=calendar_db + ports: + - '5432:5432' + volumes: + - db:/var/lib/postgresql/data + +volumes: + db: + driver: local \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ede1c1f5..3f40a7d5 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,13 +21,17 @@ model Calendar { } model Event { - id String @id @default(uuid()) - calendarId String + id String @id @default(cuid()) title String description String? - startTime DateTime - endTime DateTime + start DateTime + end DateTime + allDay Boolean @default(false) + location String? + userId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - calendar Calendar @relation(fields: [calendarId], references: [id]) + + @@index([userId]) + @@index([start, end]) } \ No newline at end of file