"use client"; import { Pencil } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { Input } from "@/components/ui/input"; import { DEFAULT_AVATAR_NAME, saveAvatarName, } from "@/lib/avatar-customization-storage"; import { cn } from "@/lib/utils"; type EditablePetNameProps = { name: string; moodLabel?: string; editable?: boolean; onNameChange?: (name: string) => void; /** Frame header above LCD, or floating badge inside the LCD viewport. */ variant?: "frame" | "overlay"; size?: "default" | "landing"; className?: string; }; export function EditablePetName({ name, moodLabel, editable = true, onNameChange, variant = "frame", size = "default", className, }: EditablePetNameProps) { const [displayName, setDisplayName] = useState(name); const [isEditing, setIsEditing] = useState(false); const [draft, setDraft] = useState(name); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const inputRef = useRef(null); const isOverlay = variant === "overlay"; useEffect(() => { setDisplayName(name); if (!isEditing) { setDraft(name); } }, [name, isEditing]); useEffect(() => { if (isEditing) { inputRef.current?.focus(); inputRef.current?.select(); } }, [isEditing]); const beginEdit = () => { if (!editable || isSaving) { return; } setDraft(displayName); setError(null); setIsEditing(true); }; const cancelEdit = () => { setDraft(displayName); setError(null); setIsEditing(false); }; const saveName = async () => { const trimmed = draft.trim() || DEFAULT_AVATAR_NAME; if (trimmed === displayName) { setIsEditing(false); return; } setIsSaving(true); setError(null); try { const saved = await saveAvatarName(trimmed); setDisplayName(saved); onNameChange?.(saved); setIsEditing(false); } catch (saveError) { setError( saveError instanceof Error ? saveError.message : "Could not save bit name.", ); setDraft(displayName); } finally { setIsSaving(false); } }; const overlayNameClass = size === "landing" ? "lcd-readable-name lcd-readable-name-landing" : cn( "lcd-readable-name text-sm sm:text-base md:text-lg", ); const editInput = (
setDraft(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter") { event.preventDefault(); void saveName(); } if (event.key === "Escape") { event.preventDefault(); cancelEdit(); } }} onBlur={() => { void saveName(); }} onClick={(event) => event.stopPropagation()} /> {error ? (

{error}

) : null}
); const displayRow = editable ? (
{isOverlay ? ( {displayName} ) : ( )} {isOverlay ? ( ) : null}
) : (

{displayName}

); return (
{ if (isEditing) { event.stopPropagation(); } }} > {isEditing ? editInput : displayRow} {!isOverlay && moodLabel ? (

{moodLabel}

) : null}
); }