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: 'name', label: 'Name', width: '35%' }, { key: 'game', label: 'Game', width: '8%' }, { key: 'set_name', label: 'Set', width: '15%' }, { 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 getRarityBadge(rarity) { if (!rarity) return null; 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)' } }; const style = colors[rarity.toLowerCase()] || colors.common; return ( {rarity.charAt(0).toUpperCase() + rarity.slice(1)} ); } function getGameBadge(game) { if (!game) return null; 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' } }; const style = styles[game.toLowerCase()] || { bg: 'var(--bg-tertiary)', text: 'var(--text-secondary)', border: 'var(--border)', label: game }; return ( {style.label} ); } export default function AdminCatalogTable({ cards, loading, sortColumn, sortDirection, onSort, hasMore, loadingMore }) { 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); return ( ); })} {cards.map((card, index) => ( ))}
sortable && onSort(col.key)} >
{col.label} {sortable && sortColumn === col.key && ( )}
{card.image_url && ( // eslint-disable-next-line @next/next/no-img-element )}

{card.name}

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

{getGameBadge(card.game)}

{card.set_name}

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