Switch card data source from pokemontcg.io to TCGdex

The Pokémon TCG API is deprecated (no new keys, existing keys end 2027-03-01)
and was returning 5xx errors. TCGdex is free and needs no API key.

- src/lib/api.ts: fetch the card list, then each card and set, with retries
  and limited concurrency; map to the existing TcgCard shape. Pokémon TCG
  Pocket cards are skipped.
- Keep the old card IDs for the 10 cards whose TCGdex ID differs, so saved
  checklists stay valid (verified by name, set and number).
- Fall back to the old image host for cards TCGdex has no scan for, and to a
  placeholder if an image fails to load.
- route.ts: serve the last cached data (marked stale) when a refresh fails;
  drop the API key handling.
- Remove the API key variables from compose and the env example; update README.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 13:14:25 +00:00
parent d13a4f1463
commit 1612834577
8 changed files with 166 additions and 61 deletions

View File

@@ -9,6 +9,7 @@ import { dispatchReverseOverride, loadOverridesClient } from '@/lib/overrides';
export default function CardItem({ card, checked, onToggle }:{ card: TcgCard; checked: VariantState; onToggle: (id:string, key: VariantKey)=>void }) {
const rate = useUsdGbpRate();
const [imageFailed, setImageFailed] = React.useState<boolean>(false);
const hasHolo = !!(card.variants?.holofoil || (card.tcgplayer as any)?.prices?.holofoil);
const hasReverseDetected = !!(card.variants?.reverseHolofoil || (card.tcgplayer as any)?.prices?.reverseHolofoil);
const [reverseOverride, setReverseOverride] = React.useState<boolean>(false);
@@ -77,7 +78,8 @@ export default function CardItem({ card, checked, onToggle }:{ card: TcgCard; ch
<div className="group relative overflow-hidden rounded-lg border border-slate-200 bg-white shadow-sm hover:shadow-md transition">
<div className="relative aspect-[3/4] w-full bg-slate-100">
<Image
src={card.images.small}
src={imageFailed ? '/card-placeholder.svg' : card.images.small}
onError={() => setImageFailed(true)}
alt={`${card.name} #${card.number}`}
fill
className="object-contain p-3"