Files
shadow-gunbuilder-ai-proto/app/register/page.tsx
T

164 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// app/register/page.tsx
"use client";
import { FormEvent, useState, Suspense } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import { useAuth } from "@/context/AuthContext";
import { Button, Field, Input } from "@/components/ui/form";
const TOS_VERSION = "2025-12-27";
function RegisterPageContent() {
const router = useRouter();
const searchParams = useSearchParams();
const { register, loading } = useAuth();
const [email, setEmail] = useState("");
const [displayName, setDisplayName] = useState("");
const [password, setPassword] = useState("");
const [accepted, setAccepted] = useState(false);
const [error, setError] = useState<string | null>(null);
const next = searchParams.get("next") || "/builder";
async function handleSubmit(e: FormEvent) {
e.preventDefault();
setError(null);
if (!accepted) {
setError(
"You must accept the Terms and confirm youre responsible for safe/legal assembly."
);
return;
}
try {
await register({
email,
password,
displayName,
acceptedTos: accepted,
tosVersion: TOS_VERSION,
});
router.push(next);
} catch (err: any) {
setError(
typeof err === "string"
? err
: err?.message ?? "Failed to create account"
);
}
}
return (
<main className="min-h-screen bg-black text-zinc-50">
<div className="mx-auto flex max-w-md flex-col px-4 py-10">
<h1 className="text-2xl font-semibold tracking-tight">
Join the <span className="text-amber-300">Battl Builder</span> Beta
</h1>
<p className="mt-2 text-sm text-zinc-400">
Create an account so we can save your builds, watch price drops, and
roll out new features to you first.
</p>
<form onSubmit={handleSubmit} className="mt-6 space-y-4">
{error && (
<div className="rounded-md border border-red-500/40 bg-red-500/10 px-3 py-2 text-sm text-red-200">
{error}
</div>
)}
<Field label="Display Name (optional)" htmlFor="displayName">
<Input
id="displayName"
type="text"
value={displayName}
onChange={(e) => setDisplayName(e.target.value)}
/>
</Field>
<Field label="Email" htmlFor="email">
<Input
id="email"
type="email"
autoComplete="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</Field>
<Field label="Password" htmlFor="password">
<Input
id="password"
type="password"
autoComplete="new-password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</Field>
<div className="rounded-md border border-zinc-800 bg-zinc-950/40 px-3 py-3">
<label className="flex items-start gap-2 text-[11px] text-zinc-400">
<input
type="checkbox"
checked={accepted}
onChange={(e) => setAccepted(e.target.checked)}
className="mt-0.5 h-4 w-4 rounded border-zinc-700 bg-zinc-950 text-amber-400 focus:ring-2 focus:ring-amber-500/40"
required
/>
<span>
I agree to the{" "}
<Link
href="/tos"
className="text-amber-300 hover:text-amber-200 underline"
>
Terms of Service
</Link>{" "}
and{" "}
<Link
href="/privacy"
className="text-amber-300 hover:text-amber-200 underline"
>
Privacy Policy
</Link>
. I understand Battl Builders is informational only and I'm
solely responsible for legality, compatibility, and safe
assembly/use of any firearm or components.
</span>
</label>
</div>
<Button type="submit" disabled={loading || !accepted}>
{loading ? "Creating account…" : "Join Beta"}
</Button>
</form>
<p className="mt-4 text-xs text-zinc-500">
Already have an account?{" "}
<Link href="/login" className="text-amber-300 hover:text-amber-200">
Log in
</Link>
.
</p>
</div>
</main>
);
}
export default function RegisterPage() {
return (
<Suspense fallback={
<main className="min-h-screen bg-black text-zinc-50">
<div className="mx-auto flex max-w-md flex-col px-4 py-10">
<div className="h-8 w-64 animate-pulse bg-zinc-800 rounded" />
</div>
</main>
}>
<RegisterPageContent />
</Suspense>
);
}