diff --git a/app/(api)/_datalib/userToEvent/createUserToEvent.ts b/app/(api)/_datalib/userToEvent/createUserToEvent.ts new file mode 100644 index 00000000..cfe7e85b --- /dev/null +++ b/app/(api)/_datalib/userToEvent/createUserToEvent.ts @@ -0,0 +1,53 @@ +import { NextResponse } from 'next/server'; +import { getDatabase } from '@utils/mongodb/mongoClient.mjs'; +import isBodyEmpty from '@utils/request/isBodyEmpty'; +import parseAndReplace from '@utils/request/parseAndReplace'; +import { NoContentError, HttpError } from '@utils/response/Errors'; + +export async function createUserToEvent(body: object) { + try { + console.log('Received body:', body); + + if (isBodyEmpty(body)) { + console.log('Body is empty'); + throw new NoContentError(); + } + + const db = await getDatabase(); + console.log('Connected to database'); + + const parsedBody = await parseAndReplace(body); + console.log('Parsed body:', parsedBody); + + const currentDate = new Date().toISOString(); + const creationStatus = await db.collection('user_to_event').insertOne({ + ...parsedBody, + _last_modified: currentDate, + _created_at: currentDate, + }); + console.log('Creation status:', creationStatus); + + const createdAssociation = await db.collection('user_to_event').findOne({ + _id: creationStatus.insertedId, + }); + console.log('Created association:', createdAssociation); + + if (!createdAssociation) { + console.log('Created association not found'); + throw new HttpError('Failed to fetch the created association'); + } + + // Returning a NextResponse directly + return NextResponse.json( + { ok: true, body: createdAssociation, error: null }, + { status: 201 } + ); + } catch (e) { + const error = e as HttpError; + console.log('Error:', error.message); + return NextResponse.json( + { ok: false, body: null, error: error.message }, + { status: error.status || 400 } + ); + } +} diff --git a/app/(api)/_datalib/userToEvent/deleteUserToEvent.ts b/app/(api)/_datalib/userToEvent/deleteUserToEvent.ts new file mode 100644 index 00000000..5fd5bc50 --- /dev/null +++ b/app/(api)/_datalib/userToEvent/deleteUserToEvent.ts @@ -0,0 +1,53 @@ +// DeleteUserToEvent function +import { NextResponse } from 'next/server'; +import { ObjectId } from 'mongodb'; +import { getDatabase } from '@utils/mongodb/mongoClient.mjs'; +import NotFoundError from '@utils/response/NotFoundError'; +import HttpError from '@utils/response/HttpError'; + +export const DeleteUserToEvent = async (id: string) => { + try { + const db = await getDatabase(); + const object_id = new ObjectId(id); + + // TESTING PURPOSES: Log query to see its structure + DELETE LATER + console.log('Query being used for deletion:', id); + + // Perform delete operation based on the query object + const deleteStatus = await db + .collection('user_to_event') + .deleteOne({ _id: object_id }); + + const findStatus = await db + .collection('user_to_event') + .findOne({ _id: object_id }); + + console.log('FOUND', findStatus); + + // TESTING PURPOSES: delete later + console.log(deleteStatus); + + // If no documents matched the query, return a not-found message + if (deleteStatus.deletedCount === 0) { + throw new NotFoundError( + `No matching associations found for the provided query.` + ); + } + + // Confirmation response of deleted count + return NextResponse.json( + { + ok: true, + body: `${deleteStatus.deletedCount} association(s) deleted.`, + error: null, + }, + { status: 200 } + ); + } catch (e) { + const error = e as HttpError; + return NextResponse.json( + { ok: false, body: null, error: error.message }, + { status: error.status || 400 } + ); + } +}; diff --git a/app/(api)/_datalib/userToEvent/getUserToEvent.ts b/app/(api)/_datalib/userToEvent/getUserToEvent.ts new file mode 100644 index 00000000..b8a360a0 --- /dev/null +++ b/app/(api)/_datalib/userToEvent/getUserToEvent.ts @@ -0,0 +1,46 @@ +// GetUserToEvent.ts +import { NextResponse } from 'next/server'; +import { getDatabase } from '@utils/mongodb/mongoClient.mjs'; +import { HttpError } from '@utils/response/Errors'; + +export const GetUserToEvent = async (query: object = {}) => { + try { + const db = await getDatabase(); + + const userEvents = await db + .collection('user_to_event') + .aggregate([ + { + $match: query, + }, + { + $lookup: { + from: 'events', + localField: 'event_id', + foreignField: '_id', + as: 'events', + }, + }, + { + $lookup: { + from: 'users', + localField: 'user_id', + foreignField: '_id', + as: 'users', + }, + }, + ]) + .toArray(); + + return NextResponse.json( + { ok: true, body: userEvents, error: null }, + { status: 200 } + ); + } catch (e) { + const error = e as HttpError; + return NextResponse.json( + { ok: false, body: null, error: error.message }, + { status: error.status || 400 } + ); + } +}; diff --git a/app/(api)/_datalib/userToEvent/updateUserToEvent.ts b/app/(api)/_datalib/userToEvent/updateUserToEvent.ts new file mode 100644 index 00000000..d519a497 --- /dev/null +++ b/app/(api)/_datalib/userToEvent/updateUserToEvent.ts @@ -0,0 +1,66 @@ +import { NextResponse } from 'next/server'; +import { getDatabase } from '@utils/mongodb/mongoClient.mjs'; +import { ObjectId } from 'mongodb'; +import isBodyEmpty from '@utils/request/isBodyEmpty'; +import parseAndReplace from '@utils/request/parseAndReplace'; +import { + HttpError, + NoContentError, + NotFoundError, +} from '@utils/response/Errors'; + +export const updateUserToEvent = async ( + userId: string, + eventId: string, + body: object +) => { + try { + // FOR TESTING ONLY delete later + console.log('Received userId:', userId); + console.log('Received eventId:', eventId); + console.log('Received body for update:', body); + + const user_id = new ObjectId(userId); + const event_id = new ObjectId(eventId); + + // Check if the body is empty + if (isBodyEmpty(body)) { + throw new NoContentError(); + } + + const parsedBody = await parseAndReplace(body); + const db = await getDatabase(); + + // Update user details if the user ID is provided + const userUpdateResult = await db + .collection('users') + .updateOne({ _id: user_id }, { $set: parsedBody }); + + // Update event details if the event ID is provided + const eventUpdateResult = await db + .collection('events') + .updateOne({ _id: event_id }, { $set: parsedBody }); + + // Check if either the user or event was updated + const userUpdated = userUpdateResult.modifiedCount > 0; + const eventUpdated = eventUpdateResult.modifiedCount > 0; + + if (!userUpdated && !eventUpdated) { + throw new NotFoundError( + `No user with id: ${userId} or event with id: ${eventId} found.` + ); + } + + // Success response + return NextResponse.json( + { ok: true, userUpdated, eventUpdated, error: null }, + { status: 200 } + ); + } catch (e) { + const error = e as HttpError; + return NextResponse.json( + { ok: false, body: null, error: error.message }, + { status: error.status || 400 } + ); + } +}; diff --git a/app/(api)/api/user-to-event/[id]/delete.ts b/app/(api)/api/user-to-event/[id]/delete.ts new file mode 100644 index 00000000..0ebec6fc --- /dev/null +++ b/app/(api)/api/user-to-event/[id]/delete.ts @@ -0,0 +1,11 @@ +// DELETE handler +import { NextRequest } from 'next/server'; +import { DeleteUserToEvent } from '@datalib/userToEvent/deleteUserToEvent'; + +export async function DELETE( + _: NextRequest, + { params }: { params: { id: string } } +) { + // Return the response from DeleteUserToEvent + return DeleteUserToEvent(params.id); +} diff --git a/app/(api)/api/user-to-event/[id]/get.ts b/app/(api)/api/user-to-event/[id]/get.ts new file mode 100644 index 00000000..0e90b52f --- /dev/null +++ b/app/(api)/api/user-to-event/[id]/get.ts @@ -0,0 +1,29 @@ +// app/api/userToEvent/[id]/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import { GetUserToEvent } from '@datalib/userToEvent/getUserToEvent'; + +export async function GET( + req: NextRequest, + { params }: { params: { id: string } } +) { + const { id } = params; + const idType = req.headers.get('idType') || 'user_id'; // Default to "user_id" if no header is provided + + // Validate idType to ensure it's either 'user_id' or 'event_id' + if (idType !== 'user_id' && idType !== 'event_id') { + return NextResponse.json( + { + ok: false, + body: null, + error: 'Invalid idType provided. Use "user_id" or "event_id".', + }, + { status: 400 } + ); + } + + const result = await GetUserToEvent({ + id, + idType: idType as 'user_id' | 'event_id', + }); + return result; +} diff --git a/app/(api)/api/user-to-event/[id]/put.ts b/app/(api)/api/user-to-event/[id]/put.ts new file mode 100644 index 00000000..c73e4aa6 --- /dev/null +++ b/app/(api)/api/user-to-event/[id]/put.ts @@ -0,0 +1,11 @@ +import { NextRequest } from 'next/server'; +import { updateUserToEvent } from '@datalib/userToEvent/updateUserToEvent'; + +export async function PUT( + request: NextRequest, + { params }: { params: { userId: string; eventId: string } } +) { + const { userId, eventId } = params; + const body = await request.json(); + return updateUserToEvent(userId, eventId, body); +} diff --git a/app/(api)/api/user-to-event/[id]/route.ts b/app/(api)/api/user-to-event/[id]/route.ts new file mode 100644 index 00000000..2cf8c447 --- /dev/null +++ b/app/(api)/api/user-to-event/[id]/route.ts @@ -0,0 +1,10 @@ +import authenticated from '@utils/authentication/authenticated'; +import { PUT as put } from './put'; +import { GET as get } from './get'; +import { DELETE as del } from './delete'; + +const PUT = authenticated(put); +const GET = authenticated(get); +const DELETE = authenticated(del); + +export { PUT, GET, DELETE }; diff --git a/app/(api)/api/user-to-event/get.ts b/app/(api)/api/user-to-event/get.ts new file mode 100644 index 00000000..55055636 --- /dev/null +++ b/app/(api)/api/user-to-event/get.ts @@ -0,0 +1,8 @@ +import { NextRequest } from 'next/server'; +import getQueries from '@utils/request/getQueries'; +import { GetUserToEvent } from '@datalib/userToEvent/getUserToEvent'; // Adjust the import path as needed + +export async function GET(request: NextRequest) { + const queries = await getQueries(request, 'userToEvent'); // Fetch query parameters for userToEvent + return GetUserToEvent(queries); // Call the GetUserToEvent function with the queries +} diff --git a/app/(api)/api/user-to-event/post.ts b/app/(api)/api/user-to-event/post.ts new file mode 100644 index 00000000..2f93f027 --- /dev/null +++ b/app/(api)/api/user-to-event/post.ts @@ -0,0 +1,7 @@ +import { NextRequest } from 'next/server'; +import { createUserToEvent } from '@datalib/userToEvent/createUserToEvent'; + +export async function POST(request: NextRequest) { + const body = await request.json(); + return createUserToEvent(body); +} diff --git a/app/(api)/api/user-to-event/route.ts b/app/(api)/api/user-to-event/route.ts new file mode 100644 index 00000000..1dd9dc1b --- /dev/null +++ b/app/(api)/api/user-to-event/route.ts @@ -0,0 +1,10 @@ +// import authenticated from '@utils/authentication/authenticated'; +import { POST } from './post'; +import { GET } from './get'; +// import { PUT } from './[id]/put'; +import { DELETE } from './[id]/delete'; + +// const POST = authenticated(post); +// const GET = authenticated(get); + +export { POST, GET, /*PUT, */ DELETE };