'use client'; import React, { useState } from 'react'; import Papa from 'papaparse'; import { XMLParser } from 'fast-xml-parser'; import { ProductItem } from '@/types/newsletter'; import { Upload, Check, AlertCircle, FileText, X } from 'lucide-react'; import { supabase } from '@/lib/supabase'; interface ImportModalProps { isOpen: boolean; onClose: () => void; onImportProducts: (products: ProductItem[]) => void; } export const ProductImportModal: React.FC = ({ isOpen, onClose, onImportProducts }) => { const [file, setFile] = useState(null); const [fileType, setFileType] = useState<'csv' | 'json' | 'xml'>('csv'); const [parsedRows, setParsedRows] = useState([]); const [columns, setColumns] = useState([]); // Mapovanie stĺpcov const [mapping, setMapping] = useState<{ title: string; priceMain: string; priceSub: string; unitPrice: string; discountText: string; imageUrl: string; validity: string; }>({ title: '', priceMain: '', priceSub: '', unitPrice: '', discountText: '', imageUrl: '', validity: '' }); const [presetName, setPresetName] = useState(''); const [savedPresets, setSavedPresets] = useState([]); if (!isOpen) return null; const handleFileUpload = (e: React.ChangeEvent) => { const uploaded = e.target.files?.[0]; if (!uploaded) return; setFile(uploaded); const ext = uploaded.name.split('.').pop()?.toLowerCase(); const reader = new FileReader(); if (ext === 'csv') { setFileType('csv'); reader.onload = (event) => { const text = event.target?.result as string; Papa.parse(text, { header: true, skipEmptyLines: true, complete: (results) => { if (results.data.length > 0) { setParsedRows(results.data); const headers = Object.keys(results.data[0] as object); setColumns(headers); autoGuessMapping(headers); } } }); }; reader.readAsText(uploaded); } else if (ext === 'json') { setFileType('json'); reader.onload = (event) => { try { const json = JSON.parse(event.target?.result as string); const arrayData = Array.isArray(json) ? json : json.products || [json]; setParsedRows(arrayData); if (arrayData.length > 0) { const headers = Object.keys(arrayData[0]); setColumns(headers); autoGuessMapping(headers); } } catch (err) { alert('Chyba pri parsovaní JSON súboru.'); } }; reader.readAsText(uploaded); } else if (ext === 'xml') { setFileType('xml'); reader.onload = (event) => { try { const parser = new XMLParser({ ignoreAttributes: false }); const jsonObj = parser.parse(event.target?.result as string); // Hľadáme pole produktov const possibleArray = jsonObj.products?.product || jsonObj.items?.item || Object.values(jsonObj)[0]; const arrayData = Array.isArray(possibleArray) ? possibleArray : [possibleArray]; setParsedRows(arrayData); if (arrayData.length > 0) { const headers = Object.keys(arrayData[0]); setColumns(headers); autoGuessMapping(headers); } } catch (err) { alert('Chyba pri parsovaní XML súboru.'); } }; reader.readAsText(uploaded); } }; const autoGuessMapping = (headers: string[]) => { const newMapping = { ...mapping }; headers.forEach((h) => { const lower = h.toLowerCase(); if (lower.includes('nazov') || lower.includes('title') || lower.includes('name')) newMapping.title = h; if (lower.includes('hlavna') || lower.includes('euro') || lower.includes('price_main')) newMapping.priceMain = h; if (lower.includes('cent') || lower.includes('sub') || lower.includes('price_sub')) newMapping.priceSub = h; if (lower.includes('merna') || lower.includes('unit') || lower.includes('kg')) newMapping.unitPrice = h; if (lower.includes('zlava') || lower.includes('discount')) newMapping.discountText = h; if (lower.includes('obrazok') || lower.includes('image') || lower.includes('foto')) newMapping.imageUrl = h; if (lower.includes('platnost') || lower.includes('valid')) newMapping.validity = h; }); setMapping(newMapping); }; const applyImport = () => { if (!mapping.title) { alert('Prosím vyberte stĺpec pre Názov produktu.'); return; } const importedProducts: ProductItem[] = parsedRows.map((row, idx) => { let pMain = String(row[mapping.priceMain] || '0').trim(); let pSub = String(row[mapping.priceSub] || '00').trim(); // Ak je cena v jednom stĺpci napr. "1.99" alebo "1,99" if (!mapping.priceSub && mapping.priceMain) { const fullPrice = String(row[mapping.priceMain] || '0').replace(',', '.'); const parts = fullPrice.split('.'); pMain = parts[0] || '0'; pSub = parts[1] || '00'; if (pSub.length === 1) pSub += '0'; } return { id: `imported-${Date.now()}-${idx}`, title: String(row[mapping.title] || 'Nový produkt'), imageUrl: row[mapping.imageUrl] || 'https://dqexxfspkylqttrtxsww.supabase.co/storage/v1/object/public/newsletter-assets/produkt_1.png', priceMain: pMain, priceSub: pSub, unitPrice: row[mapping.unitPrice] || '', discountText: row[mapping.discountText] ? `${row[mapping.discountText]}%` : '', badgeText: 'zľava', cardBgColor: '#feeaea', stores: { potraviny: true, supermarket: true, tempo: true }, validityOverride: row[mapping.validity] || undefined }; }); onImportProducts(importedProducts); onClose(); }; return (
{/* Header */}

Hromadný import produktov

{/* Content */}
{/* File Upload Box */}
{/* Mapping Table */} {columns.length > 0 && (

Vizuálny Data Mapper (Párovanie stĺpcov)

{/* Živý náhľad prvých 2 riadkov */} {parsedRows.length > 0 && (
Živý náhľad prvých položiek ({parsedRows.length} nájdených záznamov)
{parsedRows.slice(0, 2).map((row, idx) => (
{row[mapping.title] || 'Bez názvu'} {row[mapping.priceMain] || '0'},{row[mapping.priceSub] || '00'} €
))}
)}
)}
{/* Footer */}
); };