import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Layout from '../components/Layout'; import PermissionIndicator from '../components/PermissionIndicator'; export default function Collections() { const router = useRouter(); // Mock user data for now const user = { email: 'me@randallstillwell.com', role: 'user' }; const [collections, setCollections] = useState([]); const [loading, setLoading] = useState(true); const [showCreateModal, setShowCreateModal] = useState(false); const [editingCollection, setEditingCollection] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [selectedTCG, setSelectedTCG] = useState('all'); // Sample data - replace with API calls const [sampleCollections] = useState([ { id: 1, name: "Modern Masters 2021", description: "Complete set of Modern Masters 2021", tcg: "MTG", cardCount: 254, value: 2847.50, lastViewed: "2024-01-15", createdAt: "2024-01-10", isPublic: true, tags: ["modern", "masters", "complete"] }, { id: 2, name: "Pokemon Base Set", description: "Original Pokemon base set collection", tcg: "Pokemon", cardCount: 102, value: 1250.00, lastViewed: "2024-01-14", createdAt: "2024-01-05", isPublic: false, tags: ["base", "original", "holographic"] }, { id: 3, name: "Lorcana First Chapter", description: "Disney Lorcana First Chapter collection", tcg: "Lorcana", cardCount: 204, value: 890.00, lastViewed: "2024-01-13", createdAt: "2024-01-08", isPublic: true, tags: ["disney", "first-chapter", "enchanted"] }, { id: 4, name: "Commander Staples", description: "Essential cards for Commander format", tcg: "MTG", cardCount: 156, value: 2100.00, lastViewed: "2024-01-12", createdAt: "2024-01-03", isPublic: true, tags: ["commander", "staples", "multiplayer"] }, { id: 5, name: "Vintage Pokemon", description: "Rare vintage Pokemon cards", tcg: "Pokemon", cardCount: 45, value: 3500.00, lastViewed: "2024-01-11", createdAt: "2024-01-01", isPublic: false, tags: ["vintage", "rare", "holographic"] } ]); const [newCollection, setNewCollection] = useState({ name: '', description: '', visibility: 'private', image: '', tags: [] }); const [showSuccessModal, setShowSuccessModal] = useState(false); const [createdCollection, setCreatedCollection] = useState(null); const fetchCollections = async () => { try { const response = await fetch('/api/collections'); if (response.ok) { const data = await response.json(); setCollections(data); } else { console.error('Failed to fetch collections'); setCollections(sampleCollections); // Fallback to sample data } } catch (error) { console.error('Error fetching collections:', error); setCollections(sampleCollections); // Fallback to sample data } finally { setLoading(false); } }; useEffect(() => { fetchCollections(); }, []); const tcgOptions = [ { value: 'MTG', label: 'Magic: The Gathering', color: 'purple' }, { value: 'Pokemon', label: 'Pokemon', color: 'blue' }, { value: 'Lorcana', label: 'Disney Lorcana', color: 'pink' }, { value: 'YuGiOh', label: 'Yu-Gi-Oh!', color: 'yellow' }, { value: 'Digimon', label: 'Digimon', color: 'orange' } ]; const filteredCollections = collections.filter(collection => { const matchesSearch = collection.name.toLowerCase().includes(searchQuery.toLowerCase()) || collection.description.toLowerCase().includes(searchQuery.toLowerCase()); const matchesTCG = selectedTCG === 'all' || collection.tcg === selectedTCG; return matchesSearch && matchesTCG; }); const groupedCollections = filteredCollections.reduce((acc, collection) => { if (!acc[collection.tcg]) { acc[collection.tcg] = []; } acc[collection.tcg].push(collection); return acc; }, {}); const handleCreateCollection = async () => { try { const response = await fetch('/api/collections', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: newCollection.name, description: newCollection.description, visibility: newCollection.visibility, image: newCollection.image, tags: newCollection.tags }) }); if (response.ok) { const createdCollection = await response.json(); setCreatedCollection(createdCollection); setShowCreateModal(false); setShowSuccessModal(true); // Reset form setNewCollection({ name: '', description: '', visibility: 'private', image: '', tags: [] }); // Refresh collections list fetchCollections(); } else { const error = await response.json(); alert(error.error || 'Failed to create collection'); } } catch (error) { console.error('Error creating collection:', error); alert('Network error. Please try again.'); } }; const handleUpdateCollection = () => { setCollections(collections.map(c => c.id === editingCollection.id ? editingCollection : c )); setEditingCollection(null); }; const handleDeleteCollection = (id) => { if (confirm('Are you sure you want to delete this collection?')) { setCollections(collections.filter(c => c.id !== id)); } }; const getTCGColor = (tcg) => { const tcgOption = tcgOptions.find(option => option.value === tcg); return tcgOption ? tcgOption.color : 'gray'; }; const formatCurrency = (amount) => { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount); }; const formatDate = (dateString) => { return new Date(dateString).toLocaleDateString(); }; if (loading) { return ( ); } return ( {/* Header */} My Collections Organize and manage your card collections setShowCreateModal(true)} className="action-btn-primary flex items-center space-x-2" > Create Collection {/* Filters and Search */} setSearchQuery(e.target.value)} /> setSelectedTCG(e.target.value)} className="input-field w-48" > All TCGs {tcgOptions.map(option => ( {option.label} ))} {/* Collections Grid */} {Object.keys(groupedCollections).length === 0 ? ( 📦 No collections found Create your first collection to get started setShowCreateModal(true)} className="action-btn-primary" > Create Collection ) : ( {Object.entries(groupedCollections).map(([tcg, collections]) => ( {tcg} {tcgOptions.find(opt => opt.value === tcg)?.label || tcg} {collections.length} collection{collections.length !== 1 ? 's' : ''} {collections.map(collection => ( router.push(`/collection/${collection.id}`)} > {collection.name} {collection.description} setEditingCollection(collection)} className="p-2 rounded-lg transition-colors" style={{ backgroundColor: 'var(--bg-tertiary-light)', color: 'var(--text-secondary-light)' }} > handleDeleteCollection(collection.id)} className="p-2 rounded-lg transition-colors" style={{ backgroundColor: 'var(--bg-tertiary-light)', color: '#ef4444' }} > {collection.cardCount} Cards {formatCurrency(collection.value)} Value Created {formatDate(collection.createdAt)} Viewed {formatDate(collection.lastViewed)} {collection.tags.length > 0 && ( {collection.tags.slice(0, 3).map(tag => ( {tag} ))} {collection.tags.length > 3 && ( +{collection.tags.length - 3} )} )} ))} ))} )} {/* Create Collection Modal */} {showCreateModal && ( Create New Collection Collection Name setNewCollection({...newCollection, name: e.target.value})} placeholder="Enter collection name" /> Description setNewCollection({...newCollection, description: e.target.value})} placeholder="Describe your collection" /> Collection Image (Optional) setNewCollection({...newCollection, image: e.target.value})} placeholder="Enter image URL" /> Add a hero image for your collection Visibility setNewCollection({...newCollection, visibility: e.target.value})} > 🔒 Private - Only you can access 👥 Invite Only - Controlled collaboration 🌍 Public - Anyone can view setShowCreateModal(false)} className="flex-1 py-2 px-4 rounded-2xl border transition-colors" style={{ borderColor: 'var(--border-light)', color: 'var(--text-secondary-light)' }} > Cancel Create Collection )} {/* Success Modal */} {showSuccessModal && createdCollection && ( 🎉 Collection Created! Your collection "{createdCollection.name}" has been created successfully. { setShowSuccessModal(false); router.push(`/collection/${createdCollection.id}`); }} className="w-full action-btn-primary" > View Collection setShowSuccessModal(false)} className="w-full py-2 px-4 rounded-2xl border transition-colors" style={{ borderColor: 'var(--border-light)', color: 'var(--text-secondary-light)' }} > Stay on Collections Page )} {/* Edit Collection Modal */} {editingCollection && ( Edit Collection Collection Name setEditingCollection({...editingCollection, name: e.target.value})} /> Description setEditingCollection({...editingCollection, description: e.target.value})} /> Trading Card Game setEditingCollection({...editingCollection, tcg: e.target.value})} > {tcgOptions.map(option => ( {option.label} ))} setEditingCollection({...editingCollection, isPublic: e.target.checked})} className="mr-2" /> Make collection public setEditingCollection(null)} className="flex-1 py-2 px-4 rounded-2xl border transition-colors" style={{ borderColor: 'var(--border-light)', color: 'var(--text-secondary-light)' }} > Cancel Update Collection )} ); }
Organize and manage your card collections
Create your first collection to get started
{collection.description}
Add a hero image for your collection
Your collection "{createdCollection.name}" has been created successfully.