import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import CollaborationManager from '../../components/CollaborationManager'; import Layout from '../../components/Layout'; export default function CollectionView() { const router = useRouter(); const { id } = router.query; // Get user from auth context - for now using admin user const user = { email: 'admin@tcgvault.com', role: 'admin' }; const [collection, setCollection] = useState(null); const [cards, setCards] = useState([]); const [loading, setLoading] = useState(true); const [isFavorited, setIsFavorited] = useState(false); const [showShareModal, setShowShareModal] = useState(false); const [copySuccess, setCopySuccess] = useState(false); // Filter states const [searchQuery, setSearchQuery] = useState(''); const [selectedRarity, setSelectedRarity] = useState('all'); const [selectedType, setSelectedType] = useState('all'); const [sortBy, setSortBy] = useState('name'); const [viewMode, setViewMode] = useState('grid'); // grid or list const [searchCards, setSearchCards] = useState(''); const [searchResults, setSearchResults] = useState([]); const [showSearchResults, setShowSearchResults] = useState(false); useEffect(() => { if (id) { fetchCollectionData(); } }, [id]); const fetchCollectionData = async () => { try { const response = await fetch(`/api/collections/${id}`); if (response.ok) { const data = await response.json(); setCollection(data.collection); setCards(data.cards || []); } else { console.error('Failed to fetch collection'); setCollection(null); setCards([]); } } catch (error) { console.error('Error fetching collection:', error); setCollection(null); setCards([]); } finally { setLoading(false); } }; const handleCopyLink = async () => { try { await navigator.clipboard.writeText(window.location.href); setCopySuccess(true); setTimeout(() => setCopySuccess(false), 2000); } catch (err) { console.error('Failed to copy link:', err); } }; const handleFavorite = () => { setIsFavorited(!isFavorited); // Here you would typically make an API call }; const handleSaveCopy = () => { // Logic to save a copy to user's collections console.log('Saving copy of collection'); }; const handleSearchCards = async (query) => { if (!query.trim()) { setSearchResults([]); setShowSearchResults(false); return; } try { const response = await fetch(`/api/cards/search?q=${encodeURIComponent(query)}&limit=10`); if (response.ok) { const results = await response.json(); setSearchResults(results); setShowSearchResults(true); } } catch (error) { console.error('Error searching cards:', error); } }; const handleAddCard = async (card, quantity = 1) => { try { const response = await fetch(`/api/collections/${id}/cards`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ cardId: card.id, quantity }) }); if (response.ok) { // Refresh collection data fetchCollectionData(); setSearchCards(''); setSearchResults([]); setShowSearchResults(false); } else { const error = await response.json(); alert(error.error || 'Failed to add card'); } } catch (error) { console.error('Error adding card:', error); alert('Network error. Please try again.'); } }; const filteredCards = cards.filter(card => { const matchesSearch = card.name.toLowerCase().includes(searchQuery.toLowerCase()); const matchesRarity = selectedRarity === 'all' || card.rarity === selectedRarity; const matchesType = selectedType === 'all' || card.card_type === selectedType; return matchesSearch && matchesRarity && matchesType; }); const sortedCards = [...filteredCards].sort((a, b) => { switch (sortBy) { case 'name': return a.name.localeCompare(b.name); case 'cost': return b.market_price - a.market_price; case 'rarity': return a.rarity.localeCompare(b.rarity); case 'type': return a.card_type.localeCompare(b.card_type); default: return 0; } }); const totalValue = cards.reduce((sum, card) => sum + (card.market_price * card.quantity), 0); const totalCards = cards.reduce((sum, card) => sum + card.quantity, 0); if (loading) { return ( ); } if (!collection) { return ( Collection not found router.push('/collections')} className="px-6 py-3 rounded-lg font-medium gradient-bg-purple text-white hover:shadow-lg transform hover:scale-105 transition-all duration-200" > Back to Collections ); } return ( {/* Hero Section with Collection Info */} 🃏 {collection.name} 👤 Created by {collection.creator_email} • TCG: {collection.tcg} • Value: ${totalValue.toFixed(2)} • Cards: {totalCards} Created {new Date(collection.created_at).toLocaleDateString()} • Last updated {new Date(collection.updated_at).toLocaleDateString()} {collection.is_public && ( <> • 🌍 Public > )} {/* Action Buttons */} {copySuccess ? 'Copied!' : 'Copy link'} setShowShareModal(true)} className="flex items-center space-x-2 px-4 py-2 rounded-lg border transition-all duration-200 hover:shadow-md" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} > Copy list Print proxies Save deck {/* Stats and Filters */} {/* Collection Stats */} {totalCards} Total Cards ${totalValue.toFixed(2)} Total Value {collection.tcg} Game {collection.is_public ? 'Public' : 'Private'} Visibility {/* Collaboration Manager */} {/* Filters */} setSearchQuery(e.target.value)} /> setSelectedRarity(e.target.value)} className="px-4 py-3 rounded-lg border transition-all duration-200" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} > All Rarities Common Uncommon Rare Ultra Rare Rainbow Rare setSelectedType(e.target.value)} className="px-4 py-3 rounded-lg border transition-all duration-200" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} > All Types Electric Trainer Energy setSortBy(e.target.value)} className="px-4 py-3 rounded-lg border transition-all duration-200" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} > Sort by Name Sort by Price Sort by Rarity Sort by Type setViewMode('grid')} className={`p-3 rounded-l-lg transition-all duration-200 ${ viewMode === 'grid' ? 'gradient-bg-purple text-white' : 'bg-transparent' }`} style={viewMode !== 'grid' ? { color: 'var(--text-secondary)' } : {}} > setViewMode('list')} className={`p-3 rounded-r-lg transition-all duration-200 ${ viewMode === 'list' ? 'gradient-bg-purple text-white' : 'bg-transparent' }`} style={viewMode !== 'list' ? { color: 'var(--text-secondary)' } : {}} > {/* Cards Display */} Cards ({sortedCards.length}) {viewMode === 'grid' ? ( {sortedCards.map(card => ( router.push(`/card/${card.id}`)} > { e.target.src = 'https://via.placeholder.com/250x350/6366f1/ffffff?text=No+Image'; }} /> {card.quantity > 1 && ( {card.quantity}x )} {card.name} ${card.market_price} ))} ) : ( {sortedCards.map(card => ( router.push(`/card/${card.id}`)} > { e.target.src = 'https://via.placeholder.com/64x88/6366f1/ffffff?text=No+Image'; }} /> {card.name} {card.set_name} • {card.rarity} • {card.card_type} ${card.market_price} Qty: {card.quantity} ))} )} {cards.length === 0 ? ( // Empty collection state 🃏 Start Building Your Collection This collection is empty. Add your first cards to get started! router.push('/cards')} className="inline-flex items-center space-x-2 px-8 py-4 rounded-xl font-medium gradient-bg-purple text-white hover:shadow-lg transform hover:scale-105 transition-all duration-200" > Browse Cards to Add Or search for specific cards to add to your collection {/* Quick add section */} Quick Add { setSearchCards(e.target.value); handleSearchCards(e.target.value); }} className="w-full px-4 py-3 rounded-lg border transition-all duration-200" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} /> {/* Search Results */} {showSearchResults && searchResults.length > 0 && ( {searchResults.map((card) => ( handleAddCard(card)} > { e.target.src = 'https://via.placeholder.com/40x56/6366f1/ffffff?text=?'; }} /> {card.name} {card.set_name} • {card.rarity} ${card.market_price} {card.game} ))} )} ) : sortedCards.length === 0 ? ( // No results for current filters 🔍 No cards match your filters Try adjusting your search or filter criteria { setSearchQuery(''); setSelectedRarity('all'); setSelectedType('all'); }} className="mt-4 px-4 py-2 rounded-lg border transition-all duration-200" style={{ backgroundColor: 'var(--bg-primary)', borderColor: 'var(--border)', color: 'var(--text-primary)' }} > Clear All Filters ) : null} {/* Share Modal */} {showShareModal && ( Share Collection Collection URL Copy setShowShareModal(false)} className="flex-1 py-2 px-4 rounded-xl border transition-colors" style={{ borderColor: 'var(--border)', color: 'var(--text-secondary)' }} > Close )} ); }
This collection is empty. Add your first cards to get started!
Try adjusting your search or filter criteria