accesscodes/src/app/auth/page.tsx
2026-03-01 12:59:51 +00:00

284 lines
14 KiB
TypeScript

"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import Link from "next/link";
import localFont from "next/font/local";
import { useUser, useClerk } from "@clerk/nextjs";
import * as Clerk from "@clerk/elements/common";
import * as SignIn from "@clerk/elements/sign-in";
import * as SignUp from "@clerk/elements/sign-up";
const makeSans = localFont({
src: "../../../public/font/makesans.ttf",
})
export default function AuthPage() {
const { isSignedIn, user } = useUser();
const { signOut } = useClerk();
const [showSignIn, setShowSignIn] = useState(false);
const [showSignUp, setShowSignUp] = useState(false);
const inputClassName =
"bg-input/20 dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-7 rounded-md border px-2 py-0.5 text-sm transition-colors file:h-6 file:text-xs/relaxed file:font-medium focus-visible:ring-[2px] aria-invalid:ring-[2px] md:text-xs/relaxed file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50";
if (showSignIn) {
return (
<main>
<div className="font-mona min-w-screen gap-2 min-h-screen flex flex-col items-center p-2 justify-center">
<div className="w-full max-w-md">
<div className="text-center mb-6">
<Link href="/auth" className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground mb-4">
← Back
</Link>
<h1 className={makeSans.className + " text-2xl text-primary font-extrabold lowercase"}>
sign in
</h1>
</div>
<SignIn.Root routing="virtual">
<Card>
<CardContent className="p-6 space-y-4">
<SignIn.Step name="start" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<Clerk.Field name="identifier" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Email</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignIn.Action submit asChild>
<Button className="w-full">Continue</Button>
</SignIn.Action>
<div className="text-center text-xs text-muted-foreground">
Don&apos;t have an account?{" "}
<button
type="button"
className="text-primary hover:underline"
onClick={() => {
setShowSignUp(true);
setShowSignIn(false);
}}
>
Create an account
</button>
</div>
</SignIn.Step>
<SignIn.Step name="verifications" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<SignIn.Strategy name="email_code" className="space-y-4">
<p className="text-sm text-muted-foreground text-center">
Enter the code sent to <SignIn.SafeIdentifier />
</p>
<Clerk.Field name="code" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Verification code</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignIn.Action submit asChild>
<Button className="w-full">Verify</Button>
</SignIn.Action>
</SignIn.Strategy>
<SignIn.Strategy name="password" className="space-y-4">
<Clerk.Field name="password" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Password</Clerk.Label>
<Clerk.Input className={inputClassName} type="password" />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignIn.Action submit asChild>
<Button className="w-full">Continue</Button>
</SignIn.Action>
<SignIn.Action navigate="forgot-password" asChild>
<Button variant="outline" className="w-full">Forgot password?</Button>
</SignIn.Action>
</SignIn.Strategy>
</SignIn.Step>
<SignIn.Step name="forgot-password" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<p className="text-sm text-muted-foreground text-center">
We&apos;ll email you a code to reset your password.
</p>
<SignIn.SupportedStrategy name="reset_password_email_code" asChild>
<Button className="w-full">Send reset code</Button>
</SignIn.SupportedStrategy>
<SignIn.Action navigate="start" asChild>
<Button variant="outline" className="w-full">Back to sign in</Button>
</SignIn.Action>
</SignIn.Step>
<SignIn.Step name="reset-password" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<Clerk.Field name="code" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Reset code</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<Clerk.Field name="password" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">New password</Clerk.Label>
<Clerk.Input className={inputClassName} type="password" />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<Clerk.Field name="confirmPassword" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Confirm password</Clerk.Label>
<Clerk.Input className={inputClassName} type="password" />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignIn.Action submit asChild>
<Button className="w-full">Reset password</Button>
</SignIn.Action>
</SignIn.Step>
</CardContent>
</Card>
</SignIn.Root>
</div>
</div>
</main>
);
}
if (showSignUp) {
return (
<main>
<div className="font-mona min-w-screen gap-2 min-h-screen flex flex-col items-center p-2 justify-center">
<div className="w-full max-w-md">
<div className="text-center mb-6">
<Link href="/auth" className="inline-flex items-center text-sm text-muted-foreground hover:text-foreground mb-4">
← Back
</Link>
<h1 className={makeSans.className + " text-2xl text-primary font-extrabold lowercase"}>
create account
</h1>
</div>
<SignUp.Root routing="virtual">
<Card>
<CardContent className="p-6 space-y-4">
<SignUp.Step name="start" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<Clerk.Field name="emailAddress" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Email</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<Clerk.Field name="password" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Password</Clerk.Label>
<Clerk.Input className={inputClassName} type="password" />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignUp.Captcha />
<SignUp.Action submit asChild>
<Button className="w-full">Create account</Button>
</SignUp.Action>
<div className="text-center text-xs text-muted-foreground">
Already have an account?{" "}
<button
type="button"
className="text-primary hover:underline"
onClick={() => {
setShowSignIn(true);
setShowSignUp(false);
}}
>
Sign in
</button>
</div>
</SignUp.Step>
<SignUp.Step name="verifications" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<SignUp.Strategy name="email_code" className="space-y-4">
<p className="text-sm text-muted-foreground text-center">
Enter the code sent to your email.
</p>
<Clerk.Field name="code" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Verification code</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignUp.Action submit asChild>
<Button className="w-full">Verify email</Button>
</SignUp.Action>
</SignUp.Strategy>
</SignUp.Step>
<SignUp.Step name="continue" className="space-y-4">
<Clerk.GlobalError className="text-sm text-destructive" />
<p className="text-sm text-muted-foreground text-center">
Finish setting up your account.
</p>
<Clerk.Field name="username" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Username</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<Clerk.Field name="firstName" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">First name</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<Clerk.Field name="lastName" className="space-y-1">
<Clerk.Label className="text-sm text-muted-foreground">Last name</Clerk.Label>
<Clerk.Input className={inputClassName} />
<Clerk.FieldError className="text-xs text-destructive" />
</Clerk.Field>
<SignUp.Action submit asChild>
<Button className="w-full">Continue</Button>
</SignUp.Action>
</SignUp.Step>
</CardContent>
</Card>
</SignUp.Root>
</div>
</div>
</main>
);
}
return (
<main>
<div className="font-mona min-w-screen gap-2 min-h-screen flex flex-col items-center p-2 justify-center">
<span className="text-muted-foreground font-medium">Account for</span>
<h1 className={makeSans.className + " text-2xl text-primary font-extrabold lowercase"}>
FRG Network
</h1>
<p className="text-muted-foreground mb-8">Create your FRG account to access all features</p>
{isSignedIn ? (
<div className="w-full max-w-md space-y-6">
<Card>
<CardContent className="p-6">
<h2 className="text-lg font-medium mb-4 lowercase">welcome back</h2>
<p className="text-sm text-muted-foreground mb-4">
Welcome back, <span className="font-medium">{user?.firstName || user?.emailAddresses[0]?.emailAddress}</span>!
</p>
<div className="space-y-3">
<Button variant="outline" onClick={() => signOut()} className="w-full">
Sign out
</Button>
</div>
</CardContent>
</Card>
</div>
) : (
<div className="w-full max-w-md space-y-6">
<Card>
<CardContent className="p-6">
<h2 className="text-lg font-medium mb-4 lowercase">get started</h2>
<div className="space-y-3">
<Button onClick={() => setShowSignIn(true)} className="w-full">
Sign in
</Button>
<Button variant="outline" onClick={() => setShowSignUp(true)} className="w-full">
Create account
</Button>
</div>
</CardContent>
</Card>
<Link href="/" className="text-primary hover:underline">Looking for server access?</Link>
</div>
)}
</div>
</main>
);
}