diff --git a/public/mana-color/forest.png b/public/mana-color/forest.png new file mode 100644 index 0000000..59b42bd Binary files /dev/null and b/public/mana-color/forest.png differ diff --git a/public/mana-color/island.png b/public/mana-color/island.png new file mode 100644 index 0000000..1851529 Binary files /dev/null and b/public/mana-color/island.png differ diff --git a/public/mana-color/moutain.png b/public/mana-color/moutain.png new file mode 100644 index 0000000..216df6a Binary files /dev/null and b/public/mana-color/moutain.png differ diff --git a/public/mana-color/plains.png b/public/mana-color/plains.png new file mode 100644 index 0000000..2b7650d Binary files /dev/null and b/public/mana-color/plains.png differ diff --git a/public/mana-color/swamp.png b/public/mana-color/swamp.png new file mode 100644 index 0000000..ea51d4a Binary files /dev/null and b/public/mana-color/swamp.png differ diff --git a/src/components/CardSearch.tsx b/src/components/CardSearch.tsx index 5552e73..7ea18dc 100644 --- a/src/components/CardSearch.tsx +++ b/src/components/CardSearch.tsx @@ -4,6 +4,7 @@ import { searchCards, getUserCollection, addCardToCollection } from '../services import { Card } from '../types'; import { useAuth } from '../contexts/AuthContext'; import MagicCard from './MagicCard'; +import { getManaIconPath } from './ManaCost'; const CardSearch = () => { const { user } = useAuth(); @@ -296,20 +297,27 @@ const CardSearch = () => { {/* Mana Cost */}
- {Object.entries(manaCost).map(([color, count]) => ( -
- - {color === 'W' ? '⚪' : color === 'U' ? '🔵' : color === 'B' ? '⚫' : color === 'R' ? '🔴' : color === 'G' ? '🟢' : '🟤'} - - setManaCost({ ...manaCost, [color]: parseInt(e.target.value) })} - className="w-14 sm:w-16 px-2 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white" - min="0" - /> -
- ))} + {Object.entries(manaCost).map(([color, count]) => { + const iconPath = getManaIconPath(color); + return ( +
+ {iconPath ? ( + {color} + ) : ( + + {color} + + )} + setManaCost({ ...manaCost, [color]: parseInt(e.target.value) })} + className="w-14 sm:w-16 px-2 py-2 bg-gray-800 border border-gray-700 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white" + min="0" + /> +
+ ); + })}
{/* Stats */} diff --git a/src/components/DeckManager.tsx b/src/components/DeckManager.tsx index 661a702..eeb15ef 100644 --- a/src/components/DeckManager.tsx +++ b/src/components/DeckManager.tsx @@ -6,6 +6,7 @@ import { useAuth } from '../contexts/AuthContext'; import { supabase } from '../lib/supabase'; import { validateDeck } from '../utils/deckValidation'; import MagicCard from './MagicCard'; +import { ManaCost } from './ManaCost'; interface DeckManagerProps { initialDeck?: Deck; @@ -580,7 +581,7 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {

{displayName}

{card.mana_cost && ( -
{card.mana_cost}
+ )} {card.prices?.usd && (
${card.prices.usd}
@@ -729,110 +730,43 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) {

Cards ({selectedCards.reduce((acc, curr) => acc + curr.quantity, 0)})

- {!isLoadingCollection && getMissingCards().length > 0 && ( -
- - {getMissingCards().length} missing -
- )}
- {!isLoadingCollection && getMissingCards().length > 0 && ( - - )} - - {selectedCards.map(({ card, quantity }) => { - const ownedQuantity = userCollection.get(card.id) || 0; - const isMissing = !isCardInCollection(card.id, quantity); - const neededQuantity = Math.max(0, quantity - ownedQuantity); - - return ( -
- {card.name} -
-

- {card.name} - {isMissing && ( - - - Missing {neededQuantity} - - )} - {!isMissing && ownedQuantity > 0 && ( - - - Owned ({ownedQuantity}) - - )} -

- {card.prices?.usd && ( -
${card.prices.usd}
- )} -
-
- {isMissing && ( - - )} - - updateCardQuantity(card.id, parseInt(e.target.value)) - } - min="1" - className="w-16 px-2 py-1 bg-gray-600 border border-gray-500 rounded text-center" - /> - -
+ {card.name} +
+

{card.name}

+ {card.prices?.usd && ( +
${card.prices.usd}
+ )}
- ); - })} +
+ + updateCardQuantity(card.id, parseInt(e.target.value)) + } + min="1" + className="w-14 px-2 py-1 bg-gray-600 border border-gray-500 rounded text-center text-sm" + /> + +
+
+ ))}
@@ -860,25 +794,44 @@ export default function DeckManager({ initialDeck, onSave }: DeckManagerProps) { )} - )} - + +
diff --git a/src/components/ManaCost.tsx b/src/components/ManaCost.tsx new file mode 100644 index 0000000..23c1eac --- /dev/null +++ b/src/components/ManaCost.tsx @@ -0,0 +1,71 @@ +import React from 'react'; + +// Map mana symbols to their icon paths +const MANA_ICONS: Record = { + W: '/mana-color/plains.png', + U: '/mana-color/island.png', + B: '/mana-color/swamp.png', + R: '/mana-color/moutain.png', // Note: filename has typo "moutain" + G: '/mana-color/forest.png', +}; + +interface ManaSymbolProps { + symbol: string; + size?: number; +} + +// Renders a single mana symbol (either as an icon or as text for numbers/other) +export function ManaSymbol({ symbol, size = 16 }: ManaSymbolProps) { + const iconPath = MANA_ICONS[symbol]; + + if (iconPath) { + return ( + {symbol} + ); + } + + // For numbers and other symbols, show as a circle with the symbol + return ( + + {symbol} + + ); +} + +interface ManaCostProps { + cost: string; + size?: number; +} + +// Parses and renders a full mana cost string like "{2}{W}{U}" +export function ManaCost({ cost, size = 16 }: ManaCostProps) { + if (!cost) return null; + + // Parse mana cost string: {2}{W}{U} -> ['2', 'W', 'U'] + const symbols = cost.match(/\{([^}]+)\}/g)?.map(s => s.slice(1, -1)) || []; + + if (symbols.length === 0) return null; + + return ( + + {symbols.map((symbol, index) => ( + + ))} + + ); +} + +// Helper to get icon path for a color (for use in filters, etc.) +export function getManaIconPath(color: string): string | null { + return MANA_ICONS[color] || null; +} + +export default ManaCost;