diff --git a/apps/web/src/actions/admin/registration-actions.ts b/apps/web/src/actions/admin/registration-actions.ts index ca3b5777..e10ac735 100644 --- a/apps/web/src/actions/admin/registration-actions.ts +++ b/apps/web/src/actions/admin/registration-actions.ts @@ -35,3 +35,12 @@ export const toggleSecretRegistrationEnabled = adminAction( return { success: true, statusSet: enabled }; } ); + +export const toggleRSVPs = adminAction( + defaultRegistrationToggleSchema, + async ({ enabled }, { user, userId }) => { + await kv.set("config:registration:allowRSVPs", enabled); + revalidatePath("/admin/toggles/registration"); + return { success: true, statusSet: enabled }; + } +); diff --git a/apps/web/src/app/admin/toggles/layout.tsx b/apps/web/src/app/admin/toggles/layout.tsx index a9dae869..64a06a0f 100644 --- a/apps/web/src/app/admin/toggles/layout.tsx +++ b/apps/web/src/app/admin/toggles/layout.tsx @@ -11,7 +11,7 @@ export default function Layout({ children }: ToggleLayoutProps) { - +
{children}
diff --git a/apps/web/src/app/admin/toggles/registration/page.tsx b/apps/web/src/app/admin/toggles/registration/page.tsx index 0b4fc507..95088c1a 100644 --- a/apps/web/src/app/admin/toggles/registration/page.tsx +++ b/apps/web/src/app/admin/toggles/registration/page.tsx @@ -8,11 +8,14 @@ export default async function Page() { pipe.get("config:registration:secretRegistrationEnabled"); // const result = await pipe.exec(); - const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled]: (string | null)[] = - await kv.mget( - "config:registration:registrationEnabled", - "config:registration:secretRegistrationEnabled" - ); + const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled, defaultRSVPsEnabled]: ( + | string + | null + )[] = await kv.mget( + "config:registration:registrationEnabled", + "config:registration:secretRegistrationEnabled", + "config:registration:allowRSVPs" + ); return (
@@ -25,6 +28,7 @@ export default async function Page() { defaultSecretRegistrationEnabled, false )} + defaultRSVPsEnabled={parseRedisBoolean(defaultRSVPsEnabled, true)} />
); diff --git a/apps/web/src/app/register/page.tsx b/apps/web/src/app/register/page.tsx index bc8fdc43..e20d9a49 100644 --- a/apps/web/src/app/register/page.tsx +++ b/apps/web/src/app/register/page.tsx @@ -12,86 +12,79 @@ import { parseRedisBoolean } from "@/lib/utils/server/redis"; import { Button } from "@/components/shadcn/ui/button"; export default async function Page() { - const { userId } = auth(); + const { userId } = auth(); - if (!userId) return redirect("/sign-up"); + if (!userId) return redirect("/sign-up"); - const user = await currentUser(); + const user = await currentUser(); - if (!user) return redirect("/sign-up"); + if (!user) return redirect("/sign-up"); - const registration = await db.query.users.findFirst({ - where: eq(users.clerkID, user.id), - }); + const registration = await db.query.users.findFirst({ + where: eq(users.clerkID, user.id), + }); - if (registration) { - return redirect("/dash"); - } + if (registration) { + return redirect("/dash"); + } - const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled]: ( - | string - | null - )[] = await kv.mget( - "config:registration:registrationEnabled", - "config:registration:secretRegistrationEnabled" - ); + const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled]: (string | null)[] = + await kv.mget( + "config:registration:registrationEnabled", + "config:registration:secretRegistrationEnabled" + ); - if (parseRedisBoolean(defaultRegistrationEnabled, true) === true) { - return ( - <> - -
-
-

Register

-

- Welcome Hacker! Please fill out - the form below to complete your registration for {c.hackathonName} - . -

-

- Psttt... Running into a issue? Please let us know on{" "} - - Discord - - ! -

- -
-
- - ); - } + if (parseRedisBoolean(defaultRegistrationEnabled, true) === true) { + return ( + <> + +
+
+

Register

+

+ Welcome Hacker! Please fill out the form below to + complete your registration for {c.hackathonName}. +

+

+ Psttt... Running into a issue? Please let us know on{" "} + + Discord + + ! +

+ +
+
+ + ); + } - return ( -
-
-

{c.hackathonName}

-

- Registration -

-
-

- Registration Is Currently Closed -

-

- If you believe this is a mistake or have any questions, feel free to - reach out to us at {c.issueEmail}! -

+ return ( +
+
+

{c.hackathonName}

+

+ Registration +

+
+

Registration Is Currently Closed

+

+ If you believe this is a mistake or have any questions, feel free to reach out to us at{" "} + {c.issueEmail}! +

- - - -

- Already registered?{" "} - - Sign-in. - -

-
-
- ); + + + +

+ Already registered? + + Sign-in. + +

+
+
+ ); } export const runtime = "edge"; diff --git a/apps/web/src/app/rsvp/page.tsx b/apps/web/src/app/rsvp/page.tsx index d45466ea..b5bf90ec 100644 --- a/apps/web/src/app/rsvp/page.tsx +++ b/apps/web/src/app/rsvp/page.tsx @@ -6,6 +6,12 @@ import { db } from "db"; import { eq } from "db/drizzle"; import { users } from "db/schema"; import ClientToast from "@/components/shared/ClientToast"; +import { SignedOut, RedirectToSignIn } from "@clerk/nextjs"; +import { kv } from "@vercel/kv"; +import { parseRedisBoolean } from "@/lib/utils/server/redis"; +import Link from "next/link"; +import { Button } from "@/components/shadcn/ui/button"; +import { CheckCircleIcon } from "lucide-react"; export default async function RsvpPage({ searchParams, @@ -15,7 +21,12 @@ export default async function RsvpPage({ const { userId } = auth(); if (!userId) { - return redirect("/"); + console.error("No user id"); + return ( + + + + ); } const user = await db.query.users.findFirst({ @@ -23,22 +34,56 @@ export default async function RsvpPage({ }); if (!user) { - return
loading...
; + return redirect("/register"); } - return ( - <> - + const rsvpEnabled = await kv.get("config:registration:allowRSVPs"); + + // TODO: fix type jank here + if ( + parseRedisBoolean(rsvpEnabled as string | boolean | null | undefined, true) === true || + user.rsvp === true + ) { + return ( + <> + +
+
+

{c.hackathonName}

+

+ RSVP +

+ +
+ + ); + } else { + return (

{c.hackathonName}

RSVP

- +
+

+ RSVPs Are Currently Closed +

+

+ We have currently reached capacity for RSVPs. However, we still encourage you to show up + for walk-ins! If you have any questions or concerns, feel free to ask on{" "} + + Discord + {" "} + or email us at {c.issueEmail}! +

+ + + +
- - ); + ); + } } export const runtime = "edge"; diff --git a/apps/web/src/components/dash/admin/toggles/RegistrationSettings.tsx b/apps/web/src/components/dash/admin/toggles/RegistrationSettings.tsx index aa7258f0..cc19688f 100644 --- a/apps/web/src/components/dash/admin/toggles/RegistrationSettings.tsx +++ b/apps/web/src/components/dash/admin/toggles/RegistrationSettings.tsx @@ -10,16 +10,19 @@ import { toggleRegistrationEnabled, toggleRegistrationMessageEnabled, toggleSecretRegistrationEnabled, + toggleRSVPs, } from "@/actions/admin/registration-actions"; interface RegistrationTogglesProps { defaultRegistrationEnabled: boolean; defaultSecretRegistrationEnabled: boolean; + defaultRSVPsEnabled: boolean; } export function RegistrationToggles({ defaultSecretRegistrationEnabled, defaultRegistrationEnabled, + defaultRSVPsEnabled, }: RegistrationTogglesProps) { const { execute: executeToggleSecretRegistrationEnabled, @@ -31,6 +34,16 @@ export function RegistrationToggles({ return { statusSet: enabled, success: true }; } ); + + const { execute: executeToggleRSVPs, optimisticData: toggleRSVPsOptimisticData } = + useOptimisticAction( + toggleRSVPs, + { success: true, statusSet: defaultRSVPsEnabled }, + (state, { enabled }) => { + return { statusSet: enabled, success: true }; + } + ); + const { execute: executeToggleRegistrationEnabled, optimisticData: ToggleRegistrationEnabledOptimisticData, @@ -43,34 +56,52 @@ export function RegistrationToggles({ ); return ( -
-

Registration

-
-
-

New Registrations

- { - toast.success(`Registration ${checked ? "enabled" : "disabled"} successfully!`); - executeToggleRegistrationEnabled({ enabled: checked }); - }} - /> + <> +
+

Registration

+
+
+

New Registrations

+ { + toast.success(`Registration ${checked ? "enabled" : "disabled"} successfully!`); + executeToggleRegistrationEnabled({ enabled: checked }); + }} + /> +
+
+

Allow Secret Code Sign-up

+ { + toast.success( + `Secret registration ${checked ? "enabled" : "disabled"} successfully!` + ); + executeToggleSecretRegistrationEnabled({ enabled: checked }); + }} + /> +
-
-

Allow Secret Code Sign-up

- { - toast.success( - `Secret registration ${checked ? "enabled" : "disabled"} successfully!` - ); - executeToggleSecretRegistrationEnabled({ enabled: checked }); - }} - /> +
+
+

RSVPs

+
+
+

Allow RSVPs

+ { + toast.success(`RSVPs ${checked ? "enabled" : "disabled"} successfully!`); + executeToggleRSVPs({ enabled: checked }); + }} + /> +
-
+ ); }