'use client'; import { useState, useRef, useEffect, useCallback } from 'react'; import { Loader2, AlertCircle, ChevronDown, Check, ArrowRightLeft } from 'lucide-react'; import { useI18n } from '@/lib/i18n'; import { cn } from '@/lib/utils'; import type { Language } from './types'; interface LanguageSelectorProps { sourceLang: string; targetLang: string; languages: Language[]; isLoading?: boolean; error?: string | null; onSourceChange: (value: string) => void; onTargetChange: (value: string) => void; } /* ── Combobox dropdown with search ──────────────────────────────── */ function Combobox({ value, options, includeAuto, autoLabel, placeholder, onChange, }: { value: string; options: Language[]; includeAuto: boolean; autoLabel: string; placeholder: string; onChange: (code: string) => void; }) { const { t } = useI18n(); const [open, setOpen] = useState(false); const [query, setQuery] = useState(''); const ref = useRef(null); const inputRef = useRef(null); useEffect(() => { if (open) inputRef.current?.focus(); }, [open]); useEffect(() => { const handler = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); }; if (open) document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, [open]); const allOptions = includeAuto ? [{ code: 'auto', name: autoLabel }, ...options] : options; const q = query.toLowerCase().trim(); const filtered = q ? allOptions.filter(l => l.name.toLowerCase().includes(q) || l.code.toLowerCase().includes(q)) : allOptions; const label = value === 'auto' ? autoLabel : allOptions.find(l => l.code === value)?.name ?? value; return (
{open && (
setQuery(e.target.value)} placeholder={t('langSelector.search')} className="w-full bg-transparent px-1 py-1 text-xs outline-none placeholder:text-brand-dark/30 dark:placeholder:text-white/30 text-brand-dark dark:text-white" />
{filtered.length === 0 && (
{t('langSelector.noResults')}
)} {filtered.map(lang => ( ))}
)}
); } /* ── Main component ─────────────────────────────────────────────── */ export default function LanguageSelector({ sourceLang, targetLang, languages, isLoading, error, onSourceChange, onTargetChange, }: LanguageSelectorProps) { const { t } = useI18n(); if (error) { return (
{t('dashboard.translate.language.loadErrorPrefix')} {error}
); } if (isLoading) { return (
{t('dashboard.translate.language.loading')}
); } const canSwap = sourceLang !== 'auto'; return (
{/* Source */}
{t('langSelector.source')}
{/* Swap Button */}
{/* Target */}
{t('langSelector.target')}
); }