From 2c4b5c2846b25edab13a575f7375e983839cec60 Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Thu, 8 Apr 2021 15:20:38 +0100 Subject: [PATCH] Create, edit and delete event types --- components/Shell.tsx | 6 +- pages/api/availability/eventtype.ts | 97 +++++++++++++ pages/availability/event/[type].tsx | 141 +++++++++++++++++++ pages/availability/index.tsx | 204 ++++++++++++++++++++++++++++ 4 files changed, 445 insertions(+), 3 deletions(-) create mode 100644 pages/api/availability/eventtype.ts create mode 100644 pages/availability/event/[type].tsx create mode 100644 pages/availability/index.tsx diff --git a/components/Shell.tsx b/components/Shell.tsx index 0484c0a795..78b1248782 100644 --- a/components/Shell.tsx +++ b/components/Shell.tsx @@ -28,10 +28,10 @@ export default function Shell(props) { Dashboard - + {/* Bookings - - + */} + Availability diff --git a/pages/api/availability/eventtype.ts b/pages/api/availability/eventtype.ts new file mode 100644 index 0000000000..1d118ffd4d --- /dev/null +++ b/pages/api/availability/eventtype.ts @@ -0,0 +1,97 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getSession } from 'next-auth/client'; +import prisma from '../../../lib/prisma'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const session = await getSession({req: req}); + + if (!session) { + res.status(401).json({message: "Not authenticated"}); + return; + } + + if (req.method == "POST") { + // TODO: Add user ID to user session object + const user = await prisma.user.findFirst({ + where: { + email: session.user.email, + }, + select: { + id: true + } + }); + + if (!user) { res.status(404).json({message: 'User not found'}); return; } + + const title = req.body.title; + const description = req.body.description; + const length = parseInt(req.body.length); + + const createEventType = await prisma.eventType.create({ + data: { + title: title, + description: description, + length: length, + userId: user.id, + }, + }); + + res.status(200).json({message: 'Event created successfully'}); + } + + if (req.method == "PATCH") { + // TODO: Add user ID to user session object + const user = await prisma.user.findFirst({ + where: { + email: session.user.email, + }, + select: { + id: true + } + }); + + if (!user) { res.status(404).json({message: 'User not found'}); return; } + + const id = req.body.id; + const title = req.body.title; + const description = req.body.description; + const length = parseInt(req.body.length); + + const updateEventType = await prisma.eventType.update({ + where: { + id: id, + }, + data: { + title: title, + description: description, + length: length + }, + }); + + res.status(200).json({message: 'Event updated successfully'}); + } + + if (req.method == "DELETE") { + // TODO: Add user ID to user session object + const user = await prisma.user.findFirst({ + where: { + email: session.user.email, + }, + select: { + id: true + } + }); + + if (!user) { res.status(404).json({message: 'User not found'}); return; } + + const id = req.body.id; + + const deleteEventType = await prisma.eventType.delete({ + where: { + id: id, + }, + }); + + res.status(200).json({message: 'Event deleted successfully'}); + } +} \ No newline at end of file diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx new file mode 100644 index 0000000000..adbadfe11f --- /dev/null +++ b/pages/availability/event/[type].tsx @@ -0,0 +1,141 @@ +import Head from 'next/head'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { useRef } from 'react'; +import prisma from '../../../lib/prisma'; +import Shell from '../../../components/Shell'; +import { useSession, getSession } from 'next-auth/client'; + +export default function EventType(props) { + const router = useRouter(); + const [ session, loading ] = useSession(); + const titleRef = useRef(); + const descriptionRef = useRef(); + const lengthRef = useRef(); + + if (loading) { + return

Loading...

; + } else { + if (!session) { + window.location.href = "/auth/login"; + } + } + + async function updateEventTypeHandler(event) { + event.preventDefault(); + + const enteredTitle = titleRef.current.value; + const enteredDescription = descriptionRef.current.value; + const enteredLength = lengthRef.current.value; + + // TODO: Add validation + + const response = await fetch('/api/availability/eventtype', { + method: 'PATCH', + body: JSON.stringify({id: props.eventType.id, title: enteredTitle, description: enteredDescription, length: enteredLength}), + headers: { + 'Content-Type': 'application/json' + } + }); + + console.log(response); + } + + async function deleteEventTypeHandler(event) { + event.preventDefault(); + + const response = await fetch('/api/availability/eventtype', { + method: 'DELETE', + body: JSON.stringify({id: props.eventType.id}), + headers: { + 'Content-Type': 'application/json' + } + }); + + router.push('/availability'); + } + + return ( +
+ + {props.eventType.title} | Event Type | Calendso + + + +
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ minutes +
+
+
+ + Cancel +
+
+
+
+
+
+
+

+ Delete this event type +

+
+

+ Once you delete this event type, it will be permanently removed. +

+
+
+ +
+
+
+
+
+
+
+ ); +} + +export async function getServerSideProps(context) { + + const eventType = await prisma.eventType.findUnique({ + where: { + id: parseInt(context.query.type), + }, + select: { + id: true, + title: true, + description: true, + length: true + } + }); + + return { + props: { + eventType + }, + } +} \ No newline at end of file diff --git a/pages/availability/index.tsx b/pages/availability/index.tsx new file mode 100644 index 0000000000..7ab42e5aa3 --- /dev/null +++ b/pages/availability/index.tsx @@ -0,0 +1,204 @@ +import Head from 'next/head'; +import Link from 'next/link'; +import prisma from '../../lib/prisma'; +import Shell from '../../components/Shell'; +import Router from 'next/router'; +import { useRef } from 'react'; +import { useState } from 'react'; +import { useSession, getSession } from 'next-auth/client'; + +export default function Availability(props) { + const [ session, loading ] = useSession(); + const [showAddModal, setShowAddModal] = useState(false); + const titleRef = useRef(); + const descriptionRef = useRef(); + const lengthRef = useRef(); + + if (loading) { + return

Loading...

; + } else { + if (!session) { + window.location.href = "/auth/login"; + } + } + + function toggleAddModal() { + setShowAddModal(!showAddModal); + } + + async function createEventTypeHandler(event) { + event.preventDefault(); + + const enteredTitle = titleRef.current.value; + const enteredDescription = descriptionRef.current.value; + const enteredLength = lengthRef.current.value; + + // TODO: Add validation + + const response = await fetch('/api/availability/eventtype', { + method: 'POST', + body: JSON.stringify({title: enteredTitle, description: enteredDescription, length: enteredLength}), + headers: { + 'Content-Type': 'application/json' + } + }); + + console.log(response); + Router.reload(); + } + + return( +
+ + Availability | Calendso + + + +
+

+ Event Types +

+
+ +
+
+
+
+
+
+ + + + + + + + + + + {props.types.map((eventType) => + + + + + + + )} + +
+ Name + + Description + + Length + + Edit +
+ {eventType.title} + + {eventType.description} + + {eventType.length} minutes + + Edit +
+
+
+
+
+ {showAddModal && +
+
+ + + + +
+
+
+ + + +
+
+ +
+

+ Create a new event type for people to book times with. +

+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ minutes +
+
+
+
+
+ + +
+
+
+
+
+ } +
+
+ ); +} + +export async function getServerSideProps(context) { + const session = await getSession(context); + + const user = await prisma.user.findFirst({ + where: { + email: session.user.email, + }, + select: { + id: true + } + }); + + const types = await prisma.eventType.findMany({ + where: { + userId: user.id, + }, + select: { + id: true, + title: true, + description: true, + length: true + } + }); + return { + props: {types}, // will be passed to the page component as props + } +} \ No newline at end of file