Spaces:
Running
Running
File size: 1,957 Bytes
08b6c63 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import { useState } from 'react'
import type { CardSummary } from '../api'
import { findTypedCard } from '../lib/search'
import { CardSearch } from './CardSearch'
interface Props {
/** The commanders' combined color identity, e.g. "BG" ("" = colorless):
* suggestions stay within it. */
colors: string
disabled: boolean
/** Adds the card and returns what to tell the user. */
onAdd: (card: CardSummary) => string
}
// Search for a card and put it in the deck by hand. Suggestions only include
// cards the deck can legally hold (and basic lands).
export function AddCard({ colors, disabled, onAdd }: Props) {
const [query, setQuery] = useState('')
const [message, setMessage] = useState<string | null>(null)
const [adding, setAdding] = useState(false)
const add = (card: CardSummary) => {
setMessage(onAdd(card))
setQuery('')
}
// Same rule as the ban list: the typed text must name exactly one card.
const addTyped = async () => {
if (!query.trim() || disabled) return
setAdding(true)
setMessage(null)
const found = await findTypedCard(query, { colors, basics: true })
setAdding(false)
if ('card' in found) add(found.card)
else setMessage(found.message)
}
return (
<div className="add-card">
<div className="add-card-row">
<CardSearch
label="Add a card"
value={query}
onChange={(v) => {
setQuery(v)
setMessage(null)
}}
onSelect={(card) => !disabled && add(card)}
onEnter={addTyped}
colors={colors}
basics
placeholder="Search cards in your commander's colors"
/>
<button type="button" className="btn btn-secondary" onClick={addTyped} disabled={disabled || adding || !query.trim()}>
Add
</button>
</div>
<p className="hint add-card-message" role="status">
{message ?? ''}
</p>
</div>
)
}
|