diff --git a/prisma/prisma/prisma.tsx b/prisma/prisma/prisma.tsx new file mode 100644 index 0000000..736f146 --- /dev/null +++ b/prisma/prisma/prisma.tsx @@ -0,0 +1,4 @@ +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); +export default prisma; diff --git a/src/app/api/events/route.tsx b/src/app/api/events/route.tsx new file mode 100644 index 0000000..611ff4e --- /dev/null +++ b/src/app/api/events/route.tsx @@ -0,0 +1,92 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import prisma from "../../../../prisma/prisma/prisma"; + +async function createEvent(req: NextApiRequest, res: NextApiResponse) { + const { name, date, location, description } = req.body; + if (!name || !date || !location || !description) { + return res.status(400).json({ error: 'All fields are required' }); + } + try { + const event = await prisma.event.create({ + data: { + name, + date: new Date(date), + location, + description, + }, + }); + res.status(201).json(event); + } catch (error) { + res.status(500).json({ error: 'Failed to create event' }); + } +} + + +async function getEvents(req: NextApiRequest, res: NextApiResponse) { + try { + const events = await prisma.event.findMany(); + res.status(200).json(events); + } catch (error) { + res.status(500).json({ error: 'Failed to fetch events' }); + } +} + + +async function updateEvent(req: NextApiRequest, res: NextApiResponse) { + const { id, name, date, location, description } = req.body; + if (!id || !name || !date || !location || !description) { + return res.status(400).json({ error: 'All fields are required' }); + } + try { + const event = await prisma.event.update({ + where: { id: parseInt(id) }, + data: { + name, + date: new Date(date), + location, + description, + }, + }); + res.status(200).json(event); + } catch (error) { + res.status(500).json({ error: 'Failed to update event' }); + } +} + + +async function deleteEvent(req: NextApiRequest, res: NextApiResponse) { + const { id } = req.body; + if (!id) { + return res.status(400).json({ error: 'ID is required' }); + } + try { + await prisma.event.delete({ + where: { id: parseInt(id) }, + }); + res.status(204).end(); + } catch (error) { + res.status(500).json({ error: 'Failed to delete event' }); + } +} + + + export default async function handler(req: NextApiRequest, res: NextApiResponse) { + switch (req.method) { + case 'GET': + await getEvents(req, res); + break; + case 'POST': + await createEvent(req, res); + break; + case 'PUT': + case 'PATCH': + await updateEvent(req, res); + break; + case 'DELETE': + await deleteEvent(req, res); + break; + default: + res.setHeader('Allow', ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } \ No newline at end of file diff --git a/src/app/api/members/route.tsx b/src/app/api/members/route.tsx new file mode 100644 index 0000000..7fad68d --- /dev/null +++ b/src/app/api/members/route.tsx @@ -0,0 +1,90 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import prisma from "../../../../prisma/prisma/prisma"; + +async function createMember(req: NextApiRequest, res: NextApiResponse) { + const { firstName, lastName, matricno, email, role } = req.body; + if (!firstName || !lastName || !matricno || !email || !role) { + return res.status(400).json({ error: 'All fields are required' }); + } + try { + const member = await prisma.member.create({ + data: { + firstName, + lastName, + matricno, + email, + role, + }, + }); + res.status(201).json(member); + } catch (error) { + res.status(500).json({ error: 'Failed to create member' }); + } + } + + async function getMembers(req: NextApiRequest, res: NextApiResponse) { + try { + const members = await prisma.member.findMany(); + res.status(200).json(members); + } catch (error) { + res.status(500).json({ error: 'Failed to fetch members' }); + } + } + + async function updateMember(req: NextApiRequest, res: NextApiResponse) { + const { id, firstName, lastName, matricno, email, role } = req.body; + if (!id || !firstName || !lastName || !matricno || !email || !role) { + return res.status(400).json({ error: 'All fields are required' }); + } + try { + const member = await prisma.member.update({ + where: { id: parseInt(id) }, + data: { + firstName, + lastName, + matricno, + email, + role, + }, + }); + res.status(200).json(member); + } catch (error) { + res.status(500).json({ error: 'Failed to update member' }); + } + } + + async function deleteMember(req: NextApiRequest, res: NextApiResponse) { + const { id } = req.body; + if (!id) { + return res.status(400).json({ error: 'ID is required' }); + } + try { + await prisma.member.delete({ + where: { id: parseInt(id) }, + }); + res.status(204).end(); + } catch (error) { + res.status(500).json({ error: 'Failed to delete member' }); + } + } + + export default async function handler(req: NextApiRequest, res: NextApiResponse) { + switch (req.method) { + case 'GET': + await getMembers(req, res); + break; + case 'POST': + await createMember(req, res); + break; + case 'PUT': + case 'PATCH': + await updateMember(req, res); + break; + case 'DELETE': + await deleteMember(req, res); + break; + default: + res.setHeader('Allow', ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } \ No newline at end of file diff --git a/src/app/api/projects/route.tsx b/src/app/api/projects/route.tsx new file mode 100644 index 0000000..f92ce61 --- /dev/null +++ b/src/app/api/projects/route.tsx @@ -0,0 +1,106 @@ +import { NextApiRequest, NextApiResponse } from "next"; +import prisma from "../../../../prisma/prisma/prisma"; + +async function createProject(req: NextApiRequest, res: NextApiResponse) { + const { title, description, startDate, endDate, members } = req.body; + if (!title || !description || !startDate || !members) { + return res.status(400).json({ error: 'Title, description, startDate, and members are required' }); + } + try { + const validMembers = await prisma.member.findMany({ where: { id: { in: members } } }); + if (validMembers.length !== members.length) { + return res.status(400).json({ error: 'Some member IDs are invalid' }); + } + const project = await prisma.project.create({ + data: { + title, + description, + startDate: new Date(startDate), + endDate: endDate ? new Date(endDate) : null, + members: { + connect: members.map((memberId: number) => ({ id: memberId })), + }, + }, + }); + res.status(201).json(project); + } catch (error) { + res.status(500).json({ error: 'Failed to create project' }); + } +} + + + async function getProjects(req: NextApiRequest, res: NextApiResponse) { + try { + const projects = await prisma.project.findMany(); + res.status(200).json(projects); + } catch (error) { + res.status(500).json({ error: 'Failed to fetch projects' }); + } + } + + + async function updateProject(req: NextApiRequest, res: NextApiResponse) { + const { id, title, description, startDate, endDate, members } = req.body; + if (!id || !title || !description || !startDate || !members) { + return res.status(400).json({ error: 'ID, title, description, startDate, and members are required' }); + } + try { + const validMembers = await prisma.member.findMany({ where: { id: { in: members } } }); + if (validMembers.length !== members.length) { + return res.status(400).json({ error: 'Some member IDs are invalid' }); + } + const project = await prisma.project.update({ + where: { id: parseInt(id) }, + data: { + title, + description, + startDate: new Date(startDate), + endDate: endDate ? new Date(endDate) : null, + members: { + set: members.map((memberId: number) => ({ id: memberId })), + }, + }, + }); + res.status(200).json(project); + } catch (error) { + res.status(500).json({ error: 'Failed to update project' }); + } + } + + + async function deleteProject(req: NextApiRequest, res: NextApiResponse) { + const { id } = req.body; + if (!id) { + return res.status(400).json({ error: 'ID is required' }); + } + try { + await prisma.project.delete({ + where: { id: parseInt(id) }, + }); + res.status(204).end(); + } catch (error) { + res.status(500).json({ error: 'Failed to delete project' }); + } + } + + + export default async function handler(req: NextApiRequest, res: NextApiResponse) { + switch (req.method) { + case 'GET': + await getProjects(req, res); + break; + case 'POST': + await createProject(req, res); + break; + case 'PUT': + case 'PATCH': + await updateProject(req, res); + break; + case 'DELETE': + await deleteProject(req, res); + break; + default: + res.setHeader('Allow', ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']); + res.status(405).end(`Method ${req.method} Not Allowed`); + } + } \ No newline at end of file