import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Link from 'next/link'; import Layout from '../components/Layout'; import { useAuth } from '../lib/auth-context'; export default function Decks() { const { user } = useAuth(); const router = useRouter(); const [decks, setDecks] = useState([]); const [loading, setLoading] = useState(true); const [showCreateModal, setShowCreateModal] = useState(false); const [editingDeck, setEditingDeck] = useState(null); const [newDeck, setNewDeck] = useState({ name: '', description: '', format: 'Commander', is_public: false }); useEffect(() => { if (user) { fetchDecks(); } }, [user]); const fetchDecks = async () => { try { const token = localStorage.getItem('auth_token'); const response = await fetch('/api/decks', { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); setDecks(data); } else { console.error('Failed to fetch decks'); } } catch (error) { console.error('Error fetching decks:', error); } finally { setLoading(false); } }; const handleCreateDeck = async (e) => { e.preventDefault(); try { const token = localStorage.getItem('auth_token'); const response = await fetch('/api/decks', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(newDeck) }); if (response.ok) { const createdDeck = await response.json(); setDecks([createdDeck, ...decks]); setShowCreateModal(false); setNewDeck({ name: '', description: '', format: 'Commander', is_public: false }); // Navigate to deck builder for the new deck router.push(`/deck-builder?deck=${createdDeck.id}`); } else { console.error('Failed to create deck'); } } catch (error) { console.error('Error creating deck:', error); } }; const handleEditDeck = async (e) => { e.preventDefault(); try { const token = localStorage.getItem('auth_token'); const response = await fetch(`/api/decks/${editingDeck.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(editingDeck) }); if (response.ok) { const updatedDeck = await response.json(); setDecks(decks.map(deck => deck.id === updatedDeck.id ? updatedDeck : deck)); setEditingDeck(null); } else { console.error('Failed to update deck'); } } catch (error) { console.error('Error updating deck:', error); } }; const handleDeleteDeck = async (deckId) => { if (!confirm('Are you sure you want to delete this deck? This action cannot be undone.')) { return; } try { const token = localStorage.getItem('auth_token'); const response = await fetch(`/api/decks/${deckId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { setDecks(decks.filter(deck => deck.id !== deckId)); } else { console.error('Failed to delete deck'); } } catch (error) { console.error('Error deleting deck:', error); } }; const getFormatIcon = (format) => { switch (format) { case 'Commander': return '⚔️'; case 'Standard': return '🏆'; case 'Modern': return '🔥'; case 'Legacy': return '💎'; default: return '🃏'; } }; const getFormatColor = (format) => { switch (format) { case 'Commander': return 'bg-purple-100 text-purple-800'; case 'Standard': return 'bg-blue-100 text-blue-800'; case 'Modern': return 'bg-red-100 text-red-800'; case 'Legacy': return 'bg-yellow-100 text-yellow-800'; default: return 'bg-gray-100 text-gray-800'; } }; if (!user) { return ( Please log in to view your decks Go to Login ); } if (loading) { return ( ); } return ( {/* Header */} My Decks Build and manage your MTG decks setShowCreateModal(true)} className="bg-accent-ember text-white px-6 py-3 rounded-lg hover:bg-accent-ember-dark transition-colors" > Create New Deck {/* Stats */} {decks.length} Total Decks {decks.filter(d => d.format === 'Commander').length} Commander {decks.filter(d => d.is_public).length} Public {decks.reduce((sum, deck) => sum + (deck.card_count || 0), 0)} Total Cards {/* Decks Grid */} {decks.length === 0 ? ( 🃏 No decks yet Create your first deck to get started setShowCreateModal(true)} className="bg-accent-ember text-white px-6 py-3 rounded-lg hover:bg-accent-ember-dark transition-colors" > Create Your First Deck ) : ( {decks.map((deck) => ( {getFormatIcon(deck.format)} {deck.format} setEditingDeck({...deck})} className="text-text-secondary hover:text-accent-ember transition-colors" > ✏️ handleDeleteDeck(deck.id)} className="text-text-secondary hover:text-red-500 transition-colors" > 🗑️ {deck.name} {deck.description && ( {deck.description} )} {deck.card_count || 0} cards {deck.is_public && Public} Edit Deck View ))} )} {/* Create Deck Modal */} {showCreateModal && ( Create New Deck Deck Name * setNewDeck({...newDeck, name: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" placeholder="Enter deck name" /> Format setNewDeck({...newDeck, format: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" > Commander Standard Modern Legacy Description setNewDeck({...newDeck, description: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" rows="3" placeholder="Describe your deck strategy..." /> setNewDeck({...newDeck, is_public: e.target.checked})} className="mr-2" /> Make deck public setShowCreateModal(false)} className="flex-1 px-4 py-2 border border-border rounded-lg text-text-secondary hover:bg-bg-secondary transition-colors" > Cancel Create Deck )} {/* Edit Deck Modal */} {editingDeck && ( Edit Deck Deck Name * setEditingDeck({...editingDeck, name: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" /> Format setEditingDeck({...editingDeck, format: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" > Commander Standard Modern Legacy Description setEditingDeck({...editingDeck, description: e.target.value})} className="w-full px-3 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-ember bg-bg-secondary text-text-primary" rows="3" /> setEditingDeck({...editingDeck, is_public: e.target.checked})} className="mr-2" /> Make deck public setEditingDeck(null)} className="flex-1 px-4 py-2 border border-border rounded-lg text-text-secondary hover:bg-bg-secondary transition-colors" > Cancel Save Changes )} ); }
Build and manage your MTG decks
Create your first deck to get started
{deck.description}