import { useEffect, useId, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { CloseIcon } from './icons/CloseIcon'; import { DownloadIcon } from './icons/DownloadIcon'; import { SpinnerIcon } from './icons/SpinnerIcon'; export type ExportMode = 'filters' | 'list'; interface ExportMenuProps { open: boolean; exporting: boolean; onClose: () => void; onExport: (options?: { postcodes?: string[] }) => void; } const EMPTY_LIST: string[] = ['']; export default function ExportMenu({ open, exporting, onClose, onExport }: ExportMenuProps) { const { t } = useTranslation(); const [mode, setMode] = useState('filters'); const [postcodes, setPostcodes] = useState(EMPTY_LIST); const titleId = useId(); const inputRefs = useRef>([]); const focusIndexRef = useRef(null); useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, [open, onClose]); useEffect(() => { if (focusIndexRef.current == null) return; inputRefs.current[focusIndexRef.current]?.focus(); focusIndexRef.current = null; }, [postcodes.length]); if (!open) return null; const cleaned = postcodes.map((p) => p.trim()).filter(Boolean); const canSubmit = !exporting && (mode === 'filters' || cleaned.length > 0); const handleSubmit = () => { if (!canSubmit) return; if (mode === 'list') { onExport({ postcodes: cleaned }); } else { onExport(); } }; const updateAt = (idx: number, value: string) => { setPostcodes((prev) => prev.map((p, i) => (i === idx ? value : p))); }; const addRow = () => { setPostcodes((prev) => { focusIndexRef.current = prev.length; return [...prev, '']; }); }; const removeAt = (idx: number) => { setPostcodes((prev) => { if (prev.length <= 1) return ['']; return prev.filter((_, i) => i !== idx); }); }; const handleInputKeyDown = (e: React.KeyboardEvent, idx: number) => { if (e.key === 'Enter') { e.preventDefault(); if (idx === postcodes.length - 1 && postcodes[idx].trim()) { addRow(); } else { inputRefs.current[idx + 1]?.focus(); } } else if ( e.key === 'Backspace' && postcodes[idx] === '' && postcodes.length > 1 ) { e.preventDefault(); focusIndexRef.current = Math.max(0, idx - 1); removeAt(idx); } }; const cardClass = (selected: boolean) => `w-full text-left cursor-pointer rounded-lg border p-3 transition-colors ${ selected ? 'border-teal-500 bg-teal-50 dark:bg-teal-900/20' : 'border-warm-200 dark:border-warm-700 hover:border-warm-300 dark:hover:border-warm-600 bg-white dark:bg-warm-800' }`; return ( <>