import React, { useState, useMemo } from 'react'; import { ExcelRow, COLUMNS } from '../types'; import { Search, Filter, Edit2, ChevronDown, ChevronUp, Info, Package } from 'lucide-react'; import { cn } from '../lib/utils'; interface ArticleDetailsProps { data: ExcelRow[]; onEdit: (index: number) => void; } type TabType = 'all' | 'missingDetailsDE' | 'missingDetailsEN' | 'missingAnyDetails' | 'lowStock' | 'missingTariff'; export function ArticleDetails({ data, onEdit }: ArticleDetailsProps) { const [activeTab, setActiveTab] = useState('all'); const [search, setSearch] = useState(''); const [lineFilter, setLineFilter] = useState(''); const [sortCol, setSortCol] = useState(null); const [sortDesc, setSortDesc] = useState(false); const [pageSize, setPageSize] = useState(25); const [page, setPage] = useState(1); const lines = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LINE]).filter(Boolean))), [data]); const filteredData = useMemo(() => { let result = data.map((row, index) => ({ row, index })); // Tab filter if (activeTab === 'missingDetailsDE') result = result.filter(r => !r.row[COLUMNS.DETAILS_DE]); if (activeTab === 'missingDetailsEN') result = result.filter(r => !r.row[COLUMNS.DETAILS_EN]); if (activeTab === 'missingAnyDetails') result = result.filter(r => !r.row[COLUMNS.DETAILS_DE] || !r.row[COLUMNS.DETAILS_EN]); if (activeTab === 'lowStock') result = result.filter(r => Number(r.row[COLUMNS.ITEM_AVAILABLE] || 0) <= 0); if (activeTab === 'missingTariff') result = result.filter(r => !r.row[COLUMNS.TARIFF_CODE]); // Search filter if (search) { const s = search.toLowerCase(); result = result.filter(r => String(r.row[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) || String(r.row[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s) || String(r.row[COLUMNS.BARCODE] || '').toLowerCase().includes(s) ); } // Dropdown filters if (lineFilter) result = result.filter(r => r.row[COLUMNS.LINE] === lineFilter); // Sorting if (sortCol !== null) { result.sort((a, b) => { const valA = a.row[sortCol]; const valB = b.row[sortCol]; if (typeof valA === 'number' && typeof valB === 'number') { return sortDesc ? valB - valA : valA - valB; } const sA = String(valA || ''); const sB = String(valB || ''); return sortDesc ? sB.localeCompare(sA) : sA.localeCompare(sB); }); } return result; }, [data, activeTab, search, lineFilter, sortCol, sortDesc]); const paginatedData = useMemo(() => { const start = (page - 1) * pageSize; return filteredData.slice(start, start + pageSize); }, [filteredData, page, pageSize]); const totalPages = Math.ceil(filteredData.length / pageSize); const handleSort = (col: number) => { if (sortCol === col) { setSortDesc(!sortDesc); } else { setSortCol(col); setSortDesc(false); } }; const getBadge = (val: any, type: 'success' | 'warning' | 'error' | 'info' = 'info') => { if (!val) return Empty; const styles = { success: "bg-green-500/10 text-green-400 border-green-500/20", warning: "bg-yellow-500/10 text-yellow-400 border-yellow-500/20", error: "bg-red-500/10 text-red-400 border-red-500/20", info: "bg-blue-500/10 text-blue-400 border-blue-500/20" }; return {val}; }; const tabs: { id: TabType; label: string }[] = [ { id: 'all', label: 'All Articles' }, { id: 'missingDetailsDE', label: 'No Details DE' }, { id: 'missingDetailsEN', label: 'No Details EN' }, { id: 'missingAnyDetails', label: 'Missing Details' }, { id: 'lowStock', label: 'Out of Stock' }, { id: 'missingTariff', label: 'No Tariff Code' }, ]; return (
{tabs.map(tab => ( ))}
{ setSearch(e.target.value); setPage(1); }} className="w-full pl-9 pr-4 py-2 bg-slate-900/50 border border-slate-700 rounded-md text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500" />
{[ { col: COLUMNS.ARTICLE_NO, label: 'SKU' }, { col: COLUMNS.ARTICLE_NAME, label: 'Name' }, { col: COLUMNS.BARCODE, label: 'Barcode' }, { col: COLUMNS.TARIFF_CODE, label: 'Tariff' }, { col: COLUMNS.COUNTRY_ORIGIN, label: 'Origin' }, { col: COLUMNS.CLASSIFICATION, label: 'Class' }, { col: COLUMNS.ITEM_AVAILABLE, label: 'Stock' }, { col: COLUMNS.DETAILS_DE, label: 'Details DE' }, { col: COLUMNS.DETAILS_EN, label: 'Details EN' }, ].map(({ col, label }) => ( ))} {paginatedData.map(({ row, index }) => ( ))} {paginatedData.length === 0 && ( )}
handleSort(col)} >
{label} {sortCol === col && ( sortDesc ? : )}
Edit
{row[COLUMNS.ARTICLE_NO]} {row[COLUMNS.ARTICLE_NAME]} {row[COLUMNS.BARCODE] || '—'} {row[COLUMNS.TARIFF_CODE] || '—'} {row[COLUMNS.COUNTRY_ORIGIN] || '—'} {row[COLUMNS.CLASSIFICATION] || '—'} {row[COLUMNS.ITEM_AVAILABLE] || 0} {row[COLUMNS.DETAILS_DE] ? (
{row[COLUMNS.DETAILS_DE]}
) : getBadge(null)}
{row[COLUMNS.DETAILS_EN] ? (
{row[COLUMNS.DETAILS_EN]}
) : getBadge(null)}
No articles found.
Showing {paginatedData.length} of {filteredData.length} articles
Page {page} of {totalPages || 1}
); }