MeetUp/src/app/api/event/route.ts

263 lines
6.4 KiB
TypeScript

import { prisma } from '@/prisma';
import { auth } from '@/auth';
import { NextResponse } from 'next/server';
import { z } from 'zod/v4';
const postEventSchema = z
.object({
title: z.string().min(1, 'Title is required'),
description: z.string().optional(),
start_time: z.iso.datetime(),
end_time: z.iso.datetime(),
location: z.string().optional().default(''),
})
.refine((data) => new Date(data.start_time) < new Date(data.end_time), {
error: 'Start time must be before end time',
});
/**
* @swagger
* /api/event:
* get:
* summary: Get all events for the authenticated user
* description: Returns all events where the user is an organizer or a participant.
* tags:
* - Event
* responses:
* 200:
* description: List of events for the user.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* events:
* type: array
* items:
* $ref: "#/components/schemas/Event"
* 401:
* description: Not authenticated.
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/ErrorResponse"
* example:
* success: false
* message: Not authenticated
* 404:
* description: User not found.
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/ErrorResponse"
* example:
* success: false
* message: User not found
*/
export const GET = auth(async (req) => {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },
{ status: 401 },
);
if (!req.auth.user || !req.auth.user.id)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const dbUser = await prisma.user.findUnique({
where: {
id: req.auth.user.id,
},
});
if (!dbUser)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const userEvents = await prisma.meeting.findMany({
where: {
OR: [
{ organizer_id: dbUser.id },
{ participants: { some: { user_id: dbUser.id } } },
],
},
select: {
id: true,
title: true,
description: true,
start_time: true,
end_time: true,
status: true,
location: true,
created_at: true,
updated_at: true,
organizer: {
select: {
id: true,
name: true,
},
},
participants: {
select: {
user: {
select: {
id: true,
name: true,
},
},
status: true,
},
},
},
});
return NextResponse.json({
success: true,
events: userEvents,
});
});
/**
* @swagger
* /api/event:
* post:
* summary: Create a new event
* description: Creates a new event as the authenticated user (organizer).
* tags:
* - Event
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - title
* - start_time
* - end_time
* properties:
* title:
* type: string
* description:
* type: string
* start_time:
* type: string
* format: date-time
* end_time:
* type: string
* format: date-time
* location:
* type: string
* responses:
* 200:
* description: Event created successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* event:
* $ref: "#/components/schemas/Event"
* 400:
* description: Invalid request data.
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/ZodErrorResponse"
* 401:
* description: Not authenticated.
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/ErrorResponse"
* example:
* success: false
* message: Not authenticated
* 404:
* description: User not found.
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/ErrorResponse"
* example:
* success: false
* message: User not found
*/
export const POST = auth(async (req) => {
if (!req.auth)
return NextResponse.json(
{ success: false, message: 'Not authenticated' },
{ status: 401 },
);
if (!req.auth.user || !req.auth.user.id)
return NextResponse.json(
{ success: false, message: 'User not found' },
{ status: 404 },
);
const dataRaw = await req.json();
const data = await postEventSchema.safeParseAsync(dataRaw);
if (!data.success) {
return NextResponse.json(
{
success: false,
message: 'Invalid request data',
errors: data.error.issues,
},
{ status: 400 },
);
}
const { title, description, start_time, end_time, location } = data.data;
const newEvent = await prisma.meeting.create({
data: {
title,
description,
start_time,
end_time,
location,
organizer_id: req.auth.user.id,
},
select: {
id: true,
title: true,
description: true,
start_time: true,
end_time: true,
status: true,
location: true,
created_at: true,
updated_at: true,
organizer: {
select: {
id: true,
name: true,
},
},
participants: {
select: {
user: {
select: {
id: true,
name: true,
},
},
status: true,
},
},
},
});
return NextResponse.json({
success: true,
event: newEvent,
});
});