import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Layout from '../../components/Layout'; 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([]); // 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); // Set initial owned quantity if available if (cardData.quantity) { setOwnedQuantity(cardData.quantity); } } 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 { // Fetch collections const collectionsResponse = await fetch('/api/collections'); if (collectionsResponse.ok) { const collectionsData = await collectionsResponse.json(); setCollections(collectionsData); } // Fetch decks const decksResponse = await fetch('/api/decks'); 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`); if (cardCollectionsResponse.ok) { const cardCollectionsData = await cardCollectionsResponse.json(); setCardCollections(cardCollectionsData); } const cardDecksResponse = await fetch(`/api/cards/${id}/decks`); 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': 'from-purple-600 via-purple-500 to-indigo-600', 'Pokemon': 'from-blue-600 via-blue-500 to-cyan-600', 'Lorcana': 'from-pink-600 via-pink-500 to-purple-600' }; return gradients[game] || 'from-gray-600 to-gray-700'; }; 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 response = await fetch(`/api/cards/${id}/ownership`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, 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 response = await fetch(`/api/cards/${id}/collections`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ collectionId: selectedCollection }) }); if (response.ok) { // Refresh card collections const cardCollectionsResponse = await fetch(`/api/cards/${id}/collections`); 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 response = await fetch(`/api/cards/${id}/decks`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ deckId: selectedDeck }) }); if (response.ok) { // Refresh card decks const cardDecksResponse = await fetch(`/api/cards/${id}/decks`); 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 response = await fetch(`/api/cards/${id}/favorite`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, 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)}
{/* 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

🃏

TCGPlayer

View on TCGPlayer

🛒

eBay

View on eBay

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

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

{quantity}
)} {/* Collection Modal */} {showCollectionModal && (

Add to Collection

)} {/* Deck Modal */} {showDeckModal && (

Add to Deck

)}
); }