import { useEffect, useRef, useState } from 'react'; import { IconUpload, IconFileText, IconAlertCircle, IconCheck, IconX } from '@tabler/icons-react'; /** * ImportModal - модальное окно импорта данных * Простой подход со встроенным backdrop (как в HistoryModal) */ function ImportModal({ show, title = 'Импорт', description = 'Вставьте текст или перетащите файл TXT/CSV. Формат: VALUE COMMUNITY', parseLine, validateItem, onConfirm, onClose, sampleHeader = ['value', 'community'], placeholder = 'value community\nvalue community', }) { const [text, setText] = useState(''); const [dragOver, setDragOver] = useState(false); const [parsed, setParsed] = useState({ items: [], invalid: [] }); const [fileName, setFileName] = useState(''); const textAreaRef = useRef(null); useEffect(() => { if (show) { setText(''); setParsed({ items: [], invalid: [] }); setFileName(''); setDragOver(false); setTimeout(() => textAreaRef.current?.focus(), 100); } }, [show]); if (!show) return null; const parseText = (raw) => { const lines = String(raw || '') .split(/\r?\n/) .map(l => l.trim()) .filter(Boolean); const items = []; const invalid = []; for (const line of lines) { const obj = parseLine(line); if (obj && validateItem(obj)) { items.push(obj); } else { invalid.push(line); } } setParsed({ items, invalid }); }; const handleDrop = async (e) => { e.preventDefault(); setDragOver(false); const file = e.dataTransfer?.files?.[0]; if (!file) return; setFileName(file.name); const content = await file.text(); setText(content); parseText(content); }; const handleChange = (value) => { setText(value); parseText(value); }; const handleConfirm = () => { if (parsed.items.length === 0) return; onConfirm?.(parsed.items); }; const downloadSample = () => { const csv = [sampleHeader, ['example', '65000:100']] .map(r => r.map(x => `"${String(x ?? '').replace(/"/g, '""')}"`).join(',')) .join('\n'); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'sample.csv'; a.click(); URL.revokeObjectURL(url); }; const handleBackdropClick = (e) => { if (e.target === e.currentTarget) { onClose?.(); } }; return ( <> {/* Modal Backdrop */}
{/* Modal */}
{ if (e.key === 'Escape') onClose?.(); }} >
{title}
{/* Description */}
{description}
{/* Drop zone */}
{ e.preventDefault(); setDragOver(true); }} onDragLeave={() => setDragOver(false)} onDrop={handleDrop} >
{fileName ? (
Файл: {fileName}
) : ( 'Перетащите TXT/CSV сюда или вставьте текст ниже' )}
{/* Textarea */}