"use client"; import * as React from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { MailCheck } from "lucide-react"; import { authClient } from "@/lib/auth-client"; import { recordLegalAcceptance } from "@/actions/legal"; import { AuthCard } from "@/components/auth/auth-card"; import { PasswordInput, PasswordRequirements, passwordStrong } from "@/components/auth/password-input"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Field, FieldError, Label } from "@/components/ui/label"; import { Alert } from "@/components/ui/alert"; const ACCESS_DENIED = "This email is not on the access list. Ask your Fetcha administrator to invite you."; export function SignupForm({ next, initialEmail }: { next?: string; initialEmail?: string }) { const router = useRouter(); const [name, setName] = React.useState(""); const [email, setEmail] = React.useState(initialEmail ?? ""); const [password, setPassword] = React.useState(""); const [confirm, setConfirm] = React.useState(""); const [agree, setAgree] = React.useState(false); const [error, setError] = React.useState(null); const [loading, setLoading] = React.useState(false); const [done, setDone] = React.useState(false); const mismatch = confirm.length > 0 && confirm !== password; async function onSubmit(e: React.FormEvent) { e.preventDefault(); setError(null); if (!passwordStrong(password)) return setError("Choose a stronger password."); if (password !== confirm) return setError("Passwords do not match."); if (!agree) return setError("You must accept the Terms of Service and Privacy Policy."); setLoading(true); const { error } = await authClient.signUp.email({ name: name.trim() || email.split("@")[0]!, email: email.trim().toLowerCase(), password, callbackURL: "/dashboard?verified=1" }); if (error) { setLoading(false); const msg = error.message ?? ""; if (error.status === 403 || /access list/i.test(msg)) setError(ACCESS_DENIED); else if (error.status === 422 || /exist/i.test(msg)) setError("An account with this email already exists. Try logging in."); else setError(msg || "Could not create the account."); return; } await recordLegalAcceptance().catch(() => {}); setLoading(false); setDone(true); setTimeout(() => { router.push(next && next.startsWith("/") ? next : "/dashboard"); router.refresh(); }, 2500); } if (done) { return ( We sent a verification link to {email}. Verify it to unlock API access — the Playground is available right away.}>
Redirecting you to the dashboard…
); } return ( Fetcha is invitation-only. Use the address your administrator approved.{" "} Request access {" "} if you have not been invited yet. } footer={ <> Already have an account?{" "} Log in } >
{error ? {error} : null} setName(e.target.value)} placeholder="Ada Lovelace" /> setEmail(e.target.value)} placeholder="you@company.com" readOnly={Boolean(initialEmail) && email === initialEmail} aria-describedby="email-hint" />

{initialEmail && email === initialEmail ? ( <> Pre-filled from your invitation.{" "} ) : ( "Must match the address on the access list exactly." )}

setPassword(e.target.value)} /> setConfirm(e.target.value)} aria-invalid={mismatch || undefined} /> {mismatch ? "Passwords do not match." : null}
); }