diff --git a/src/components/Collection.tsx b/src/components/Collection.tsx index c000b53..c5abf54 100644 --- a/src/components/Collection.tsx +++ b/src/components/Collection.tsx @@ -1,17 +1,16 @@ import React, { useState, useEffect } from 'react'; -import { Search, Plus, Loader2, Trash2, CheckCircle, XCircle } from 'lucide-react'; +import { Search, Loader2, Trash2, CheckCircle, XCircle } from 'lucide-react'; import { Card } from '../types'; -import { searchCards, getUserCollection, addCardToCollection, getCardsByIds } from '../services/api'; +import { getUserCollection, getCardsByIds } from '../services/api'; import { useAuth } from '../contexts/AuthContext'; -import MagicCard from './MagicCard'; export default function Collection() { const { user } = useAuth(); const [searchQuery, setSearchQuery] = useState(''); - const [searchResults, setSearchResults] = useState([]); const [collection, setCollection] = useState<{ card: Card; quantity: number }[]>([]); + const [filteredCollection, setFilteredCollection] = useState<{ card: Card; quantity: number }[]>([]); const [isLoadingCollection, setIsLoadingCollection] = useState(true); - const [isAddingCard, setIsAddingCard] = useState(null); + const [hoveredCard, setHoveredCard] = useState(null); const [snackbar, setSnackbar] = useState<{ message: string; type: 'success' | 'error' } | null>(null); // Load user's collection from Supabase on mount @@ -43,6 +42,7 @@ export default function Collection() { })); setCollection(collectionWithCards); + setFilteredCollection(collectionWithCards); } catch (error) { console.error('Error loading collection:', error); setSnackbar({ message: 'Failed to load collection', type: 'error' }); @@ -54,131 +54,49 @@ export default function Collection() { loadCollection(); }, [user]); - const handleSearch = async (e: React.FormEvent) => { - e.preventDefault(); - if (!searchQuery.trim()) return; - - try { - const cards = await searchCards(searchQuery); - setSearchResults(cards); - } catch (error) { - console.error('Failed to search cards:', error); - setSnackbar({ message: 'Failed to search cards', type: 'error' }); - } - }; - - const addToCollection = async (card: Card) => { - if (!user) { - setSnackbar({ message: 'Please log in to add cards to your collection', type: 'error' }); + // Filter collection based on search query + useEffect(() => { + if (!searchQuery.trim()) { + setFilteredCollection(collection); return; } - try { - setIsAddingCard(card.id); + const query = searchQuery.toLowerCase(); + const filtered = collection.filter(({ card }) => { + return ( + card.name.toLowerCase().includes(query) || + card.type_line?.toLowerCase().includes(query) || + card.oracle_text?.toLowerCase().includes(query) || + card.colors?.some(color => color.toLowerCase().includes(query)) + ); + }); - // Add card to Supabase - await addCardToCollection(user.id, card.id, 1); - - // Update local state - setCollection(prev => { - const existing = prev.find(c => c.card.id === card.id); - if (existing) { - return prev.map(c => - c.card.id === card.id - ? { ...c, quantity: c.quantity + 1 } - : c - ); - } - return [...prev, { card, quantity: 1 }]; - }); - - setSnackbar({ message: 'Card added to collection!', type: 'success' }); - } catch (error) { - console.error('Error adding card to collection:', error); - setSnackbar({ message: 'Failed to add card to collection', type: 'error' }); - } finally { - setIsAddingCard(null); - setTimeout(() => setSnackbar(null), 3000); - } - }; + setFilteredCollection(filtered); + }, [searchQuery, collection]); return (

My Collection

- {/* Search */} -
-
+ {/* Search within collection */} +
+
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" - placeholder="Search cards to add..." + placeholder="Search your collection by name, type, or text..." />
- - - - {/* Search Results */} - {searchResults.length > 0 && ( -
-

Search Results

-
- {searchResults.map(card => { - const inCollection = collection.find(c => c.card.id === card.id); - - return ( -
- -
-

{card.name}

- {inCollection && ( -
- - In collection (x{inCollection.quantity}) -
- )} - {card.prices?.usd && ( -
${card.prices.usd}
- )} - -
-
- ); - })} -
-
- )} +
{/* Collection */}

- My Cards ({collection.length} unique cards, {collection.reduce((acc, c) => acc + c.quantity, 0)} total) + {searchQuery ? `Found ${filteredCollection.length} card(s)` : `My Cards (${collection.length} unique, ${collection.reduce((acc, c) => acc + c.quantity, 0)} total)`}

{isLoadingCollection ? ( @@ -188,28 +106,38 @@ export default function Collection() { ) : collection.length === 0 ? (

Your collection is empty

-

Search for cards above to add them to your collection

+

Add cards from the Deck Manager to build your collection

+
+ ) : filteredCollection.length === 0 ? ( +
+

No cards found

+

Try a different search term

) : ( -
- {collection.map(({ card, quantity }) => ( -
- -
-
-

{card.name}

- - x{quantity} - +
+ {filteredCollection.map(({ card, quantity }) => ( +
setHoveredCard(card)} + onMouseLeave={() => setHoveredCard(null)} + > + {/* Small card thumbnail */} +
+ {card.name} + {/* Quantity badge */} +
+ x{quantity}
- {card.prices?.usd && ( -
- ${card.prices.usd} each - - (${(parseFloat(card.prices.usd) * quantity).toFixed(2)} total) - -
- )} +
+ + {/* Card name below thumbnail */} +
+ {card.name}
))} @@ -218,12 +146,39 @@ export default function Collection() {
+ {/* Hover Card Preview */} + {hoveredCard && ( +
+
+ {hoveredCard.name} +
+

{hoveredCard.name}

+

{hoveredCard.type_line}

+ {hoveredCard.oracle_text && ( +

+ {hoveredCard.oracle_text} +

+ )} + {hoveredCard.prices?.usd && ( +
+ ${hoveredCard.prices.usd} +
+ )} +
+
+
+ )} + {/* Snackbar */} {snackbar && (