import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Link from 'next/link'; 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); const [selectedTCG, setSelectedTCG] = useState('MTG'); // Filter states const [searchQuery, setSearchQuery] = useState(''); const [selectedRarity, setSelectedRarity] = useState('All Rarities'); const [selectedType, setSelectedType] = useState('All Types'); const [groupBy, setGroupBy] = useState('Group by Game'); const [sortBy, setSortBy] = useState('Sort by Name'); const [viewMode, setViewMode] = useState('grid'); 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 handleSearchCards = async (query) => { if (query.length < 2) { setSearchResults([]); setShowSearchResults(false); return; } try { const response = await fetch(`/api/cards/search?q=${encodeURIComponent(query)}&limit=10`); if (response.ok) { const data = await response.json(); setSearchResults(data.cards || []); setShowSearchResults(true); } } catch (error) { console.error('Error searching cards:', error); } }; const handleAddCard = async (card) => { try { const response = await fetch(`/api/collections/${id}/cards`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('auth_token')}` }, body: JSON.stringify({ cardId: card.id, quantity: 1 }) }); if (response.ok) { setSearchCards(''); setShowSearchResults(false); fetchCollectionData(); // Refresh the collection data } } catch (error) { console.error('Error adding card:', error); } }; const handleShare = () => { const url = window.location.href; navigator.clipboard.writeText(url).then(() => { setCopySuccess(true); setTimeout(() => setCopySuccess(false), 2000); }); }; const toggleFavorite = () => { setIsFavorited(!isFavorited); }; const togglePublic = async () => { try { const response = await fetch(`/api/collections/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('auth_token')}` }, body: JSON.stringify({ is_public: !collection.is_public }) }); if (response.ok) { setCollection(prev => ({ ...prev, is_public: !prev.is_public })); } } catch (error) { console.error('Error updating collection:', error); } }; // Group cards by game const groupedCards = cards.reduce((acc, card) => { const game = card.game || 'Other'; if (!acc[game]) acc[game] = []; acc[game].push(card); return acc; }, {}); // Get game display names and counts const gameStats = { 'MTG': groupedCards['MTG']?.length || 0, 'Lorcana': groupedCards['Lorcana']?.length || 0, 'Pokemon': groupedCards['Pokemon']?.length || 0 }; if (loading) { return (
); } if (!collection) { return (

Collection not found

); } return (
{/* Header */}
{/* Back button */}
{/* Action buttons */}
{/* Collection Info */}

{collection.name}

{collection.description}

{/* TCG Tags */}
{Object.entries(gameStats).map(([game, count]) => count > 0 ? ( {game} ) : null )}
{/* Creator and Stats */}
Crafted by
{collection.creator_email?.charAt(0).toUpperCase()}
{collection.creator_email}
Cards: {cards.length}
Cost: ${collection.totalValue || '0'}
Created {new Date(collection.created_at).toLocaleDateString()} Last updated {new Date(collection.updated_at).toLocaleDateString()}
{/* Action Bar */}
Public
Activity 123
{/* Content */}
{/* Search and Filters */}
{ setSearchCards(e.target.value); handleSearchCards(e.target.value); }} className="w-64 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent" style={{ borderColor: 'var(--border)', backgroundColor: 'var(--bg-secondary)' }} />
{/* Game Sections */} {Object.entries(groupedCards).map(([game, gameCards]) => (

{game === 'MTG' ? 'Magic The Gathering' : game} {gameCards.length}

{gameCards.map((card, index) => (
{card.image_url ? ( {card.name} ) : ( 'Card' )}
))} {/* Add empty card slots to fill the row */} {Array.from({ length: Math.max(0, 7 - (gameCards.length % 7)) }, (_, index) => (
Card
))}
))} {cards.length === 0 && (
🃏

Start Building Your Collection

Add cards to get started with your collection

)}
{/* Search Results Dropdown */} {showSearchResults && searchResults.length > 0 && (
{searchResults.map(card => (
handleAddCard(card)} className="flex items-center p-3 hover:bg-gray-50 cursor-pointer" > {card.name} { e.target.src = 'https://via.placeholder.com/48x64/6366f1/ffffff?text=No+Image'; }} />
{card.name}
{card.set_name} • ${card.market_price}
))}
)} {/* Collaboration Manager */}
); }