import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Layout from '../../components/Layout'; import { useIsAdmin } from '../../lib/admin-auth'; import CollectionSelectionModal from '../../components/CollectionSelectionModal'; export default function CardDetail() { const router = useRouter(); const { id } = router.query; const user = { email: 'me@randallstillwell.com', role: 'user' }; const [card, setCard] = useState(null); const [loading, setLoading] = useState(true); const [activeTab, setActiveTab] = useState('details'); const [ownedQuantity, setOwnedQuantity] = useState(0); const [showQuantityModal, setShowQuantityModal] = useState(false); const [showCollectionModal, setShowCollectionModal] = useState(false); const [showDeckModal, setShowDeckModal] = useState(false); const [selectedCollection, setSelectedCollection] = useState(''); const [selectedDeck, setSelectedDeck] = useState(''); const [quantity, setQuantity] = useState(1); const [isFavorited, setIsFavorited] = useState(false); const [collections, setCollections] = useState([]); const [decks, setDecks] = useState([]); const [cardCollections, setCardCollections] = useState([]); const [cardDecks, setCardDecks] = useState([]); // Check admin status const { isAdmin, loading: adminLoading } = useIsAdmin(); // Fetch card data from API useEffect(() => { const fetchCard = async () => { if (!id) return; try { const response = await fetch(`/api/cards/${id}`); if (response.ok) { const cardData = await response.json(); setCard(cardData); // Fetch user's ownership of this card const token = localStorage.getItem('auth_token'); if (token) { try { const ownershipResponse = await fetch(`/api/cards/${id}/ownership`, { headers: { 'Authorization': `Bearer ${token}` } }); if (ownershipResponse.ok) { const ownershipData = await ownershipResponse.json(); setOwnedQuantity(ownershipData.quantity || 0); } } catch (error) { console.error('Error fetching ownership:', error); } // Check if card is favorited try { const favoritesResponse = await fetch(`/api/favorites?type=card`, { headers: { 'Authorization': `Bearer ${token}` } }); if (favoritesResponse.ok) { const favoritesData = await favoritesResponse.json(); const isCardFavorited = favoritesData.favorites.some(fav => fav.item_id == id); setIsFavorited(isCardFavorited); } } catch (error) { console.error('Error checking favorites:', error); } } } else { console.error('Failed to fetch card'); } } catch (error) { console.error('Error fetching card:', error); } finally { setLoading(false); } }; fetchCard(); }, [id]); // Fetch user's collections and decks useEffect(() => { const fetchUserData = async () => { try { const token = localStorage.getItem('auth_token'); const headers = { 'Authorization': `Bearer ${token}` }; // Fetch collections const collectionsResponse = await fetch('/api/collections', { headers }); if (collectionsResponse.ok) { const collectionsData = await collectionsResponse.json(); setCollections(collectionsData); } // Fetch decks const decksResponse = await fetch('/api/decks', { headers }); if (decksResponse.ok) { const decksData = await decksResponse.json(); setDecks(decksData); } // Fetch card's current collections and decks if (card) { const cardCollectionsResponse = await fetch(`/api/cards/${id}/collections`, { headers }); if (cardCollectionsResponse.ok) { const cardCollectionsData = await cardCollectionsResponse.json(); setCardCollections(cardCollectionsData); } const cardDecksResponse = await fetch(`/api/cards/${id}/decks`, { headers }); if (cardDecksResponse.ok) { const cardDecksData = await cardDecksResponse.json(); setCardDecks(cardDecksData); } } } catch (error) { console.error('Error fetching user data:', error); } }; if (card) { fetchUserData(); } }, [card, id]); const getTCGGradient = (game) => { const gradients = { 'MTG': '#9333ea, #8b5cf6, #4f46e5', 'Pokemon': '#2563eb, #3b82f6, #0891b2', 'Lorcana': '#db2777, #ec4899, #a855f7' }; return gradients[game] || '#4b5563, #374151'; }; const getTCGIcon = (game) => { const icons = { 'MTG': '🔮', 'Pokemon': '⚡', 'Lorcana': '✨' }; return icons[game] || '🃏'; }; const formatCurrency = (amount) => { if (!amount) return '$0.00'; return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount); }; const getRarityLabel = (rarity) => { const rarityMap = { 'common': 'Common', 'uncommon': 'Uncommon', 'rare': 'Rare', 'mythic': 'Mythic', 'holographic': 'Holographic', 'enchanted': 'Enchanted', 'super rare': 'Super Rare', 'legendary': 'Legendary' }; return rarityMap[rarity?.toLowerCase()] || rarity; }; const getRarityColor = (rarity) => { const colors = { 'common': '#6B7280', 'uncommon': '#10B981', 'rare': '#F59E0B', 'mythic': '#FFD700', 'holographic': '#FF6B6B', 'enchanted': '#A855F7', 'super rare': '#3B82F6', 'legendary': '#FFD700' }; return colors[rarity?.toLowerCase()] || '#6B7280'; }; const handleOwnershipUpdate = async (newQuantity) => { try { const token = localStorage.getItem('auth_token'); const response = await fetch(`/api/cards/${id}/ownership`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ quantity: newQuantity }) }); if (response.ok) { setOwnedQuantity(newQuantity); setShowQuantityModal(false); } else { console.error('Failed to update ownership'); } } catch (error) { console.error('Error updating ownership:', error); } }; const handleAddToCollection = async () => { try { const token = localStorage.getItem('auth_token'); const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }; const response = await fetch(`/api/cards/${id}/collections`, { method: 'POST', headers, body: JSON.stringify({ collectionId: selectedCollection }) }); if (response.ok) { // Refresh card collections const cardCollectionsResponse = await fetch(`/api/cards/${id}/collections`, { headers: { 'Authorization': `Bearer ${token}` } }); if (cardCollectionsResponse.ok) { const cardCollectionsData = await cardCollectionsResponse.json(); setCardCollections(cardCollectionsData); } setShowCollectionModal(false); setSelectedCollection(''); } else { console.error('Failed to add to collection'); } } catch (error) { console.error('Error adding to collection:', error); } }; const handleAddToDeck = async () => { try { const token = localStorage.getItem('auth_token'); const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }; const response = await fetch(`/api/cards/${id}/decks`, { method: 'POST', headers, body: JSON.stringify({ deckId: selectedDeck }) }); if (response.ok) { // Refresh card decks const cardDecksResponse = await fetch(`/api/cards/${id}/decks`, { headers: { 'Authorization': `Bearer ${token}` } }); if (cardDecksResponse.ok) { const cardDecksData = await cardDecksResponse.json(); setCardDecks(cardDecksData); } setShowDeckModal(false); setSelectedDeck(''); } else { console.error('Failed to add to deck'); } } catch (error) { console.error('Error adding to deck:', error); } }; const handleToggleFavorite = async () => { try { const token = localStorage.getItem('auth_token'); const response = await fetch(`/api/cards/${id}/favorite`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ favorited: !isFavorited }) }); if (response.ok) { setIsFavorited(!isFavorited); } else { console.error('Failed to toggle favorite'); } } catch (error) { console.error('Error toggling favorite:', error); } }; if (loading) { return (
); } if (!card) { return (
🃏

Card Not Found

The card you're looking for doesn't exist.

); } return (
{/* Hero Section with Card Image and Basic Info */}
{/* Background Pattern */}
{/* Card Image */}
{card.image_url ? ( {card.name} ) : (
{getTCGIcon(card.game)}

{card.name}

{card.set_name}

{getRarityLabel(card.rarity)}
)}
{/* Card Info */}

{card.name}

{card.oracle_text || card.card_type}

{/* Ownership Status and Actions */}
Ownership Status
{ownedQuantity > 0 && ( Owned ({ownedQuantity}) )}
{getTCGIcon(card.game)} {card.game} {getRarityLabel(card.rarity)}
{formatCurrency(card.current_price || 0)}
{/* Admin Edit Button */} {isAdmin && !adminLoading && (
)}
{/* Current Collections and Decks */} {(cardCollections.length > 0 || cardDecks.length > 0) && (

Currently In:

{cardCollections.map(collection => (
📁 {collection.name}
))} {cardDecks.map(deck => (
🎴 {deck.name}
))}
)}
{/* Content Tabs */}
{['details', 'price-history', 'purchase'].map((tab) => ( ))}
{/* Tab Content */}
{activeTab === 'details' && (
{/* Card Metadata */}

Card Information

TCG {card.game}
Set {card.set_name}
Card Number {card.card_number}
Type {card.card_type}
Rarity {getRarityLabel(card.rarity)}
{card.mana_cost && (
Cost to Play {card.mana_cost}
)} {card.power && (
Power {card.power}
)} {card.toughness && (
Toughness {card.toughness}
)} {card.current_price && (
Current Price {formatCurrency(card.current_price)}
)}
{/* Card Text */}

Card Text

{card.oracle_text && (

{card.oracle_text}

)}
)} {activeTab === 'price-history' && (

Price History

{/* Price Graph Placeholder */}

Price Trend

Price history data will be available soon

{/* Price Statistics Cards */}
{/* Current Price */}
💰
Current Price
{formatCurrency(card.current_price || 0)}
)} {activeTab === 'purchase' && (

Where to Buy

)}
{/* Quantity Modal */} {showQuantityModal && (

{ownedQuantity > 0 ? 'Update Quantity' : 'Mark as Owned'}

{quantity}
)} {/* Collection Selection Modal */} setShowCollectionModal(false)} cards={card ? [card] : []} onAddToCollections={(results, selectedCollectionIds, cards) => { const successCount = results.filter(r => r.success).length; if (successCount > 0) { // Refresh card collections const fetchCardCollections = async () => { try { const token = localStorage.getItem('auth_token'); const response = await fetch(`/api/cards/${id}/collections`, { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); setCardCollections(data); } } catch (error) { console.error('Error refreshing card collections:', error); } }; fetchCardCollections(); } }} /> {/* Deck Modal */} {showDeckModal && (

Add to Deck

)}
); }