import { GlassSurface } from './ui'; const SORTABLE_COLUMNS = [ { key: 'name', label: 'Name' }, { key: 'game', label: 'Game' }, { key: 'set_name', label: 'Set' }, { key: 'card_number', label: '#' }, { key: 'rarity', label: 'Rarity' }, { key: 'current_price', label: 'Current $' }, { key: 'market_price', label: 'Market $' }, { key: 'prices_updated_at', label: 'Price Updated' }, { key: 'verified', label: 'Verified' } ]; const COLUMNS = [ { key: 'select', label: '', width: '40px' }, { key: 'name', label: 'Name', width: '32%' }, { key: 'game', label: 'Game', width: '8%' }, { key: 'set_name', label: 'Set', width: '14%' }, { key: 'card_number', label: '#', width: '5%' }, { key: 'rarity', label: 'Rarity', width: '8%' }, { key: 'current_price', label: 'Current $', width: '8%' }, { key: 'market_price', label: 'Market $', width: '8%' }, { key: 'prices_updated_at', label: 'Price Updated', width: '10%' }, { key: 'verified', label: 'Verified', width: '5%' } ]; function formatPrice(price) { if (price === null || price === undefined || price === '') return '—'; const num = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(num)) return '—'; return '$' + num.toFixed(2); } function formatDate(dateStr) { if (!dateStr) return '—'; try { const date = new Date(dateStr); if (isNaN(date.getTime())) return '—'; return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); } catch { return '—'; } } function rarityColors(rarity) { if (!rarity) return { bg: 'var(--bg-tertiary)', text: 'var(--text-secondary)', border: 'var(--border)' }; const colors = { common: { bg: 'var(--bg-tertiary)', text: 'var(--text-secondary)', border: 'var(--border)' }, uncommon: { bg: 'rgba(34, 197, 94, 0.15)', text: '#22c55e', border: 'rgba(34, 197, 94, 0.3)' }, rare: { bg: 'rgba(59, 130, 246, 0.15)', text: '#3b82f6', border: 'rgba(59, 130, 246, 0.3)' }, mythic: { bg: 'rgba(168, 85, 247, 0.15)', text: '#a855f7', border: 'rgba(168, 85, 247, 0.3)' }, special: { bg: 'rgba(249, 115, 22, 0.15)', text: '#f97316', border: 'rgba(249, 115, 22, 0.3)' }, bonus: { bg: 'rgba(234, 179, 8, 0.15)', text: '#eab308', border: 'rgba(234, 179, 8, 0.3)' } }; return colors[rarity.toLowerCase()] || colors.common; } function gameColors(game) { if (!game) return { bg: 'var(--bg-tertiary)', text: 'var(--text-secondary)', border: 'var(--border)', label: game }; const styles = { mtg: { bg: 'rgba(59, 130, 246, 0.15)', text: '#3b82f6', border: 'rgba(59, 130, 246, 0.3)', label: 'MTG' }, pokemon: { bg: 'rgba(249, 115, 22, 0.15)', text: '#f97316', border: 'rgba(249, 115, 22, 0.3)', label: 'Pokémon' }, lorcana: { bg: 'rgba(168, 85, 247, 0.15)', text: '#a855f7', border: 'rgba(168, 85, 247, 0.3)', label: 'Lorcana' } }; return styles[game.toLowerCase()] || { bg: 'var(--bg-tertiary)', text: 'var(--text-secondary)', border: 'var(--border)', label: game }; } function RarityBadge({ rarity }) { if (!rarity) return null; const style = rarityColors(rarity); return ( {rarity.charAt(0).toUpperCase() + rarity.slice(1)} ); } function GameBadge({ game }) { if (!game) return null; const style = gameColors(game); return ( {style.label} ); } function VerifiedIcon({ verified }) { const path = "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"; if (verified) { return ( ); } return ( ); } export default function AdminCatalogTable({ cards, loading, sortColumn, sortDirection, onSort, hasMore, loadingMore, selectedCardIds, onToggleSelect, onSelectAll, allSelected }) { if (loading && cards.length === 0) { return (

Loading card catalog...

); } if (cards.length === 0) { return (

No cards found matching your filters.

); } return (
{COLUMNS.map(col => { const sortable = SORTABLE_COLUMNS.some(sc => sc.key === col.key); if (col.key === 'select') { return ( ); } return ( ); })} {cards.map((card, index) => { const checked = selectedCardIds.has(card.id); const rowClass = (index % 2 === 0 ? 'bg-[rgba(255,255,255,0.02)]' : '') + ' border-b transition-colors ' + (checked ? 'bg-[rgba(var(--text-accent),0.03)]' : ''); return ( ); })}
0} onChange={onSelectAll} aria-label="Select all cards on this page" className="w-4 h-4 rounded border-2 cursor-pointer" style={{ borderColor: 'var(--border)', accentColor: 'var(--accent-ember)', '--tw-ring-color': 'var(--accent-ember)' }} /> sortable && onSort(col.key)} >
{col.label} {sortable && sortColumn === col.key && ( )}
onToggleSelect(card.id)} aria-label={'Select ' + card.name} className="w-4 h-4 rounded border-2 cursor-pointer" style={{ borderColor: 'var(--border)', accentColor: 'var(--accent-ember)', '--tw-ring-color': 'var(--accent-ember)' }} />
{card.image_url && ( )}

{card.name}

{card.set_code?.toUpperCase() + ' ' + (card.card_number || '')} {card.oracle_id && [' + card.oracle_id.slice(0, 8) + ']}

{card.set_name}

{card.card_number || '—'} {formatPrice(card.current_price)} {formatPrice(card.market_price)} {formatDate(card.prices_updated_at)}
{loadingMore && hasMore && (
Loading more cards...
)} ); }