"use client"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Field, FieldDescription, FieldGroup, FieldLabel, FieldSeparator, } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import Link from "next/link"; import { useState } from "react"; import { authClient } from "@/lib/auth-session/auth-client"; import { toast } from "sonner"; import { Loader2 } from "lucide-react"; export function SignupForm({ className, ...props }: React.ComponentProps<"form">) { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [showPassword, setShowPassword] = useState(false); const [showConfirm, setShowConfirm] = useState(false); const [isLoading, setIsLoading] = useState(false); const [isGoogleLoading, setIsGoogleLoading] = useState(false); const [showVerifyNotice, setShowVerifyNotice] = useState(false); const [resendLoading, setResendLoading] = useState(false); const [resendSuccess, setResendSuccess] = useState(false); function togglePassword(e: React.MouseEvent) { e.preventDefault(); setShowPassword((s) => !s); } function toggleConfirm(e: React.MouseEvent) { e.preventDefault(); setShowConfirm((s) => !s); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setIsLoading(true); // Validate passwords match if (password !== confirmPassword) { toast.error("Passwords don't match", { description: "Please make sure both passwords are the same.", }); setIsLoading(false); return; } if (!/[^A-Za-z0-9]/.test(password)) { toast.error("Password must contain at least one special character", { description: "Please include at least one special character in your password.", }); setIsLoading(false); return; } // Validate password length if (password.length < 8) { toast.error("Password too short", { description: "Password must be at least 8 characters long.", }); setIsLoading(false); return; } try { const { error } = await authClient.signUp.email({ email, password, name, }); if (error) { if (error.status === 403) { setShowVerifyNotice(true); toast.error("Please verify your email address", { description: "Check your inbox for the verification link.", }); } else { setShowVerifyNotice(false); toast.error("Sign up failed", { description: error.message || "Unable to create account. Please try again.", }); } } else { setShowVerifyNotice(false); toast.success("Account created successfully!", { description: "Please check your email to verify your account.", }); // Redirect to login page after successful signup using full page reload setTimeout(() => { window.location.href = "/sign-in"; }, 2000); } } catch { toast.error("An unexpected error occurred", { description: "Please try again later.", }); } finally { setIsLoading(false); } } async function handleResendVerification( e: React.MouseEvent ) { e.preventDefault(); setResendLoading(true); setResendSuccess(false); try { const res = await fetch("/api/auth/resend-verification", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }), }); if (res.ok) { setResendSuccess(true); toast.success("Verification email sent!", { description: "Check your inbox for the verification link.", }); } else { toast.error("Failed to resend verification email."); } } catch { toast.error("Failed to resend verification email."); } finally { setResendLoading(false); } } async function handleGoogleSignUp() { try { setIsGoogleLoading(true); // Google OAuth will redirect to Google, then back to callback // The onAfterSignUp hook in auth.ts assigns "patient" role to new users // After callback, the auth layout redirects to the role-specific dashboard await authClient.signIn.social({ provider: "google", }); } catch (error) { console.error("Google sign-up failed:", error); toast.error("Google sign-up failed", { description: "Please try again.", }); setIsGoogleLoading(false); } } return (
{showVerifyNotice && (
Your email is not verified. Please check your inbox for the verification link.
)}

Create your account

Fill in the form below to create your account

Full Name setName(e.target.value)} disabled={isLoading} required /> Email setEmail(e.target.value)} disabled={isLoading} required className="h-9" /> We'll use this to contact you. Password
setPassword(e.target.value)} disabled={isLoading} minLength={8} required className="h-9" />
Must be at least 8 characters long.
Confirm Password
setConfirmPassword(e.target.value)} disabled={isLoading} minLength={8} required className="h-9" />
Please confirm your password.
Or continue with Already have an account? Sign in
); }