"use client"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { createClient } from "@/lib/supabase/client"; import { formatAuthNetworkError } from "@/lib/supabase/env"; import { formatAuthError, formatSignupError } from "@/lib/supabase/auth-errors"; import { ensureUserProfile } from "@/lib/auth/resolve-portal-role"; import type { PortalRole } from "@/lib/auth/roles"; import { loginPathForRole, PORTAL_ROUTES } from "@/lib/auth/roles"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { PasswordInput } from "@/components/ui/password-input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; async function signupViaApi( email: string, password: string, displayName: string, portalRole: PortalRole ) { const res = await fetch("/api/auth/signup", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password, displayName, portalRole }), }); const json = (await res.json()) as { success: boolean; error?: string; useClient?: boolean; needsEmailConfirmation?: boolean; }; return { ok: res.ok && json.success, status: res.status, ...json }; } export function SignupForm({ portalRole, title, description, }: { portalRole: PortalRole; title: string; description: string; }) { const router = useRouter(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [displayName, setDisplayName] = useState(""); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const loginHref = loginPathForRole(portalRole); const portalLabel = portalRole === "league_master" ? "League Master" : "Team Manager"; async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setLoading(true); setError(null); try { const trimmedEmail = email.trim(); const api = await signupViaApi( trimmedEmail, password, displayName, portalRole ); if (api.ok) { if (api.needsEmailConfirmation) { setError( `Confirm your email, then sign in at ${portalLabel} login.` ); return; } const supabase = createClient(); const { error: signInError } = await supabase.auth.signInWithPassword({ email: trimmedEmail, password, }); if (signInError) { setError( `Account created. Sign in at ${loginHref} (${signInError.message})` ); return; } router.push(PORTAL_ROUTES[portalRole]); router.refresh(); return; } if (api.status !== 503 && !api.useClient) { setError(formatSignupError(api.error ?? "Signup failed")); return; } const supabase = createClient(); const { data, error: authError } = await supabase.auth.signUp({ email: trimmedEmail, password, options: { data: { display_name: displayName, portal_role: portalRole }, }, }); if (authError) { setError(formatAuthError(authError)); return; } if (data.user && !data.session) { setError( `Confirm your email, then sign in at ${portalLabel} login.` ); return; } if (data.user) { const sync = await ensureUserProfile( supabase, data.user, portalRole, displayName ); if (sync.error === "schema") { setError( "Account created but database needs an update. Run: npm run db:push — then sign in." ); return; } if (!sync.ok && sync.error) { setError(formatSignupError(sync.error)); return; } } router.push(PORTAL_ROUTES[portalRole]); router.refresh(); } catch (err) { setError(formatAuthNetworkError(err)); } finally { setLoading(false); } } return (

Yaltopia FIFA

{title} {description}
setDisplayName(e.target.value)} />
setEmail(e.target.value)} required autoComplete="email" />
setPassword(e.target.value)} required minLength={6} autoComplete="new-password" />
{error && (

{error}

)}

Sign in {portalRole === "manager" && ( <> {" · "} Home )}

); }