import { useState } from 'react'; import { AtSign, Plus, X, Loader2, BadgeCheck, AlertTriangle } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { useCrewNip05 } from '@/hooks/useCrewNip05'; import { useTranslation } from '@/contexts/language'; import { cn } from '@/lib/utils'; import { MAX_PROFILE_HANDLES, normalizeHandle } from '@/lib/profileHandles'; /** * Editable list of NIP-05 handles (add / remove / live-verify) for a profile, * crew or shop. Each handle is verified against the owner `pubkey`. */ export function Nip05HandlesEditor({ handles, onChange, pubkey, inputId, accent = 'teal', className, }: { handles: string[]; onChange: (next: string[]) => void; pubkey?: string; inputId?: string; accent?: 'teal' | 'lime'; className?: string; }) { const { t } = useTranslation(); const [input, setInput] = useState(''); const [error, setError] = useState(null); const accentText = accent === 'lime' ? 'text-[#ccff00]' : 'text-teal-400'; const addBtn = accent === 'lime' ? 'bg-[#ccff00] text-black hover:bg-[#ccff00]/90' : 'bg-teal-500 text-white hover:bg-teal-600'; const add = () => { const value = normalizeHandle(input); setInput(''); if (!value) return setError(t('socialUi.form.nip05Invalid')); if (handles.includes(value)) return setError(null); if (handles.length >= MAX_PROFILE_HANDLES) { return setError(t('socialUi.form.nip05TooMany', { count: MAX_PROFILE_HANDLES })); } setError(null); onChange([...handles, value]); }; const remove = (handle: string) => onChange(handles.filter((h) => h !== handle)); return (
{ setInput(e.target.value); if (error) setError(null); }} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); add(); } }} spellCheck={false} autoCapitalize="none" className="bg-gray-800 border-gray-700 font-mono text-sm" />
{error &&

{error}

} {handles.length > 0 && (
{handles.map((handle) => ( remove(handle)} accentText={accentText} /> ))}
)}
); } function HandleRow({ handle, pubkey, onRemove, accentText, }: { handle: string; pubkey?: string; onRemove: () => void; accentText: string; }) { const { t } = useTranslation(); const { data, isLoading } = useCrewNip05(handle, pubkey); const status = data?.status ?? (isLoading ? 'loading' : 'unreachable'); const icon = status === 'verified' ? ( ) : status === 'mismatch' ? ( ) : status === 'loading' ? ( ) : ( ); const label = status === 'verified' ? t('socialUi.nip05.verified') : status === 'mismatch' ? t('socialUi.nip05.mismatch') : t('socialUi.form.nip05Unverified'); return (
{icon} {handle} {label}
); }