"use client"; import { useRef, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { Loader2 } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { signUp } from "@/lib/auth/auth-client"; import { GoogleButton } from "./google-button"; import { Turnstile, type TurnstileHandle } from "./turnstile"; export function SignUpForm({ googleEnabled, turnstileSiteKey, }: { googleEnabled: boolean; turnstileSiteKey: string | null; }) { const router = useRouter(); const [loading, setLoading] = useState(false); // See sign-in-form: rendered only when configured, verified server-side. const [captchaToken, setCaptchaToken] = useState(""); const turnstileRef = useRef(null); const captchaRequired = !!turnstileSiteKey; async function onSubmit(e: React.FormEvent) { e.preventDefault(); setLoading(true); const form = new FormData(e.currentTarget); const { error } = await signUp.email( { name: String(form.get("name")), email: String(form.get("email")), password: String(form.get("password")), }, captchaRequired ? { headers: { "x-captcha-response": captchaToken } } : undefined ); if (error) { // Single-use token: re-challenge so the retry fails on its real cause. turnstileRef.current?.reset(); // Accepted tradeoff (L8): the raw Better Auth message can reveal that an // email is already registered (account enumeration). We keep the specific // message for UX clarity; the signup endpoint is rate-limited server-side. toast.error(error.message ?? "Could not create account"); setLoading(false); return; } toast.success("Account created! Welcome to Podcast Distribution AI."); router.push("/dashboard"); router.refresh(); } return ( Create your account Start producing podcasts with AI — free, no card required. {googleEnabled && ( <>
or
)}

At least 8 characters.

{turnstileSiteKey && ( toast.error("Could not load the security check. Please refresh.")} className="flex justify-center" /> )}

Already have an account?{" "} Sign in

); }