From 7a7fc6120e8561730c657315fd722b9117379ee1 Mon Sep 17 00:00:00 2001 From: Jin Young Bang Date: Sun, 14 Apr 2024 21:45:26 -0400 Subject: [PATCH 1/2] refactor: style updates --- src/app/checkin/[id]/page.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/checkin/[id]/page.tsx b/src/app/checkin/[id]/page.tsx index b8c96d8..ac51fbd 100644 --- a/src/app/checkin/[id]/page.tsx +++ b/src/app/checkin/[id]/page.tsx @@ -9,9 +9,9 @@ export default function Checkin() { const { data: session } = useSession(); return ( -
-
- +
+
+

Hi, {session?.user?.name}!

Welcome to Phi Chi Theta, Zeta Chapter's Rush! We're excited to have you here.

@@ -20,7 +20,7 @@ export default function Checkin() {
- +
); From 9825d1ef186fe9671c5005819162e7ed211b3479 Mon Sep 17 00:00:00 2001 From: Jin Young Bang Date: Wed, 17 Apr 2024 14:31:17 -0400 Subject: [PATCH 2/2] feat: implement backend routing with error page --- src/app/checkin/[id]/layout.tsx | 1 - src/app/checkin/[id]/page.tsx | 124 ++++++++++++++++++++++++++++++-- src/app/checkin/error/page.tsx | 48 +++++++++++++ src/components/ui/alert.tsx | 59 +++++++++++++++ src/types/Events.tsx | 7 ++ 5 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 src/app/checkin/error/page.tsx create mode 100644 src/components/ui/alert.tsx create mode 100644 src/types/Events.tsx diff --git a/src/app/checkin/[id]/layout.tsx b/src/app/checkin/[id]/layout.tsx index 70c70bc..4ee9fc0 100644 --- a/src/app/checkin/[id]/layout.tsx +++ b/src/app/checkin/[id]/layout.tsx @@ -15,7 +15,6 @@ export default function RootLayout({ }) { return ( -
{children}
diff --git a/src/app/checkin/[id]/page.tsx b/src/app/checkin/[id]/page.tsx index ac51fbd..f38c45f 100644 --- a/src/app/checkin/[id]/page.tsx +++ b/src/app/checkin/[id]/page.tsx @@ -1,26 +1,140 @@ "use client" +import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Checkbox } from "@/components/ui/checkbox" import { useSession, signOut } from "next-auth/react"; +import { Event } from "@/types/Events" +import { useRouter } from 'next/navigation' +import Loader from "@/components/Loader" -export default function Checkin() { +import { + Alert, + AlertDescription, + AlertTitle, +} from "@/components/ui/alert" + + +export default function Checkin({ params }: { params: { id: string } }) { + const router = useRouter(); const { data: session } = useSession(); + const [event, setEvent] = useState(null); + const [code, setCode] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [isButtonDisabled, setIsButtonDisabled] = useState(false); + const [error, setError] = useState(null); + + + useEffect(() => { + fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/events/rush/${params.id}`, { + }) + .then((res) => { + if (!res.ok) { + router.push("/checkin/error"); + throw new Error("Failed to fetch event"); + } + return res.json(); + }) + .then((data) => { + setEvent(data); + setIsLoading(false); + }) + .catch((err) => { + setError(err); + }); + }, []); + + const handleSubmit = () => { + setIsButtonDisabled(true); + fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/events/rush/checkin/${params.id}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + code: code, + name: session?.user?.name, + email: session?.user?.email, + }), + }) + .then(async (res) => { + console.log(res) + setIsButtonDisabled(false); + if (!res.ok) { + const err = await res.json(); + throw new Error(err.Message); + } + return res.json(); + }) + .then((data) => { + router.push("https://bupct.com/"); + }) + .catch((err) => { + setError(err); + setIsButtonDisabled(false); + }); + } + + const AlertComponent = () => { + return ( + error && ( + + {/* */} + + Error + + {error.message} + + + + ) + ) + } + if (isLoading) { + return + } return ( -
+
+

Hi, {session?.user?.name}!

Welcome to Phi Chi Theta, Zeta Chapter's Rush! We're excited to have you here.

-

Please enter your code to check-in:

+

Please enter your code to check-in to {event?.name}:

- + setCode(e.target.value)} />
- +
); diff --git a/src/app/checkin/error/page.tsx b/src/app/checkin/error/page.tsx new file mode 100644 index 0000000..864d030 --- /dev/null +++ b/src/app/checkin/error/page.tsx @@ -0,0 +1,48 @@ +"use client" + +export default function Error() { + + return ( + +
+
+ + + + + + + + + + + + + + + +

Uh-oh!

+ +

We can't find that page.

+
+
+ ); +} + + diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx new file mode 100644 index 0000000..839e81f --- /dev/null +++ b/src/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border border-neutral-200 p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-neutral-950 dark:border-neutral-800 dark:[&>svg]:text-neutral-50", + { + variants: { + variant: { + default: "bg-white text-neutral-950 dark:bg-neutral-950 dark:text-neutral-50", + destructive: + "border-red-500/50 text-red-500 dark:border-red-500 [&>svg]:text-red-500 dark:border-red-900/50 dark:text-red-900 dark:dark:border-red-900 dark:[&>svg]:text-red-900", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)) +Alert.displayName = "Alert" + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertTitle.displayName = "AlertTitle" + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertDescription.displayName = "AlertDescription" + +export { Alert, AlertTitle, AlertDescription } diff --git a/src/types/Events.tsx b/src/types/Events.tsx new file mode 100644 index 0000000..4d39827 --- /dev/null +++ b/src/types/Events.tsx @@ -0,0 +1,7 @@ +export interface Event { + _id: string + categoryId: string + name: string + dateCreated: string + numAttendees: number | null +} \ No newline at end of file