"use client"; import { useState } from "react"; import { useMutation } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; import { DISPLAY_NAME_MAX_LENGTH } from "@/lib/constants"; import { getSupabaseBrowserClient } from "@/lib/supabase/client"; import { AvatarColorPicker } from "./avatar-color-picker"; function validateDisplayName(name: string): string | null { const trimmed = name.trim(); if (trimmed.length === 0) return "Display name is required"; if (trimmed.length > DISPLAY_NAME_MAX_LENGTH) return `Display name must be ${DISPLAY_NAME_MAX_LENGTH} characters or less`; if (/<|>/.test(trimmed)) return "Display name cannot contain < or >"; return null; } export function DisplayNameForm() { const router = useRouter(); const [displayName, setDisplayName] = useState(""); const [avatarColor, setAvatarColor] = useState(null); const [validationError, setValidationError] = useState(null); const signUpMutation = useMutation({ mutationFn: async ({ name, color }: { name: string; color: string | null }) => { const supabase = getSupabaseBrowserClient(); const { data: authData, error: authError } = await supabase.auth.signInAnonymously(); if (authError) throw authError; if (!authData.user) throw new Error("Sign-in failed: no user returned"); const { error: insertError } = await supabase.from("users").insert({ id: authData.user.id, display_name: name, avatar_color: color, }); if (insertError) throw insertError; return { userId: authData.user.id }; }, onSuccess: () => { router.push("/recovery"); }, }); function handleSubmit(e: React.FormEvent) { e.preventDefault(); const trimmed = displayName.trim(); const error = validateDisplayName(trimmed); if (error) { setValidationError(error); return; } setValidationError(null); signUpMutation.mutate({ name: trimmed, color: avatarColor }); } return (
{ setDisplayName(e.target.value); setValidationError(null); }} maxLength={DISPLAY_NAME_MAX_LENGTH} placeholder="What should we call you?" className="w-full rounded-lg border border-foreground/20 bg-background px-3 py-2 text-foreground placeholder:text-foreground/40 focus:outline-none focus:ring-2 focus:ring-blue-500" autoFocus autoComplete="off" /> {validationError &&

{validationError}

}
{signUpMutation.error && (

{signUpMutation.error instanceof Error ? signUpMutation.error.message : "Something went wrong. Please try again."}

)} ); }