Files
magikarp-collection/README.md
Foohoo 1612834577 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>
2026-10-18 13:14:25 +00:00

146 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Magikarp Collection
A Next.js web app to browse every English Magikarp Pokémon card with images, set symbols, search, set filter, and a personal checklist stored in your browser.
## Features
- **Checklist (variants-aware)**: Track base, holofoil, and reverse holofoil per card. Local persistence with migration from v1 to v2.
- **Card images**: Card scans from `assets.tcgdex.net` (a placeholder is shown for cards TCGdex has no scan for).
- **Set badges**: Displays series and set name.
- **Search & filter**: Search by name/number/rarity/set and filter by set.
- **Totals include variants**: The header and tab badges use variant totals (base + available variants) for collected/uncollected counts.
- **Sort by release date**: Cards are ordered by set release date (oldest first).
- **Caching with TTL**: Server route caches card data to `data/cards.json` with a 24h TTL and a manual refresh button.
- **Cached/Live indicator**: Header shows whether data came from cache or a live fetch, with last updated timestamp.
- **Non-blocking error toast**: Refresh errors show a short-lived toast without disrupting the current view.
- **Responsive UI**: Tailwind CSS, mobile-friendly grid.
## Tech Stack
- **Next.js 15** (App Router)
- **React 19**
- **TypeScript**
- **Tailwind CSS v4**
- **Axios** for HTTP
## Quick Start
### 1) Prerequisites
- Node.js 18+ and npm
### 2) Install dependencies
```bash
npm install
```
### 3) Environment variables
No API key is needed. Card data comes from the free [TCGdex](https://tcgdex.dev/) API.
To enable the optional single-user Basic Auth, create `.env.local` (or `.env`) in the project root:
```bash
# .env.local
BASIC_AUTH_USER=your_user
BASIC_AUTH_PASS=your_password
```
An example is provided in `.env.local.example`.
### 4) Run the dev server
```bash
npm run dev
```
By default: http://localhost:3000
If you see a server already running on port 3000, you can use another port:
```bash
PORT=3001 npm run dev
```
## Scripts
- `npm run dev` – start Next.js in development
- `npm run build` – production build
- `npm run start` – start production server
- `npm run lint` – lint project
## Project Structure
```
magikarp-collection/
├─ src/
│ ├─ app/
│ │ ├─ api/
│ │ │ ├─ magikarp/route.ts # API route with 24h TTL cache (data/cards.json)
│ │ │ └─ checklist/route.ts # Server-backed checklist persistence (optional)
│ │ ├─ layout.tsx # Root layout and global wrapper
│ │ ├─ page.tsx # Main page: search, set filter, grid, checklist
│ │ └─ globals.css # Tailwind entry + global styles
│ ├─ components/
│ │ ├─ CardGrid.tsx # Grid for card list
│ │ ├─ CardItem.tsx # Card tile with image, rarity, set badge, checklist toggle
│ │ ├─ Header.tsx # Title, search, stats
│ │ ├─ SetBadge.tsx # Shows set symbol and name
│ │ └─ SetFilter.tsx # Dropdown to filter by set
│ ├─ lib/
│ │ ├─ api.ts # Axios client for Pokémon TCG API
│ │ ├─ checklist.ts # Checklist utils (local + server-backed)
│ │ └─ currency.ts # Price formatting + exchange rate hook
│ └─ types/
│ └─ pokemon.ts # TypeScript types for cards/sets
├─ data/ # Local cache for cards/checklist JSON (gitignored)
├─ next.config.ts # Remote image domains, turbopack settings
├─ tsconfig.json # TS config with path alias '@/*'
├─ postcss.config.cjs # Tailwind v4 PostCSS plugin config
├─ Dockerfile # Multi-stage Docker build (standalone output)
├─ docker-compose.yml # Compose with APP_PORT and data volume
├─ .dockerignore # Reduce build context
├─ package.json
└─ .env.local.example # Example env file
```
## Data Source
- TCGdex REST API v2: https://api.tcgdex.net/v2/en (no key required)
- `GET /cards?name=magikarp` lists matching cards; each card (`/cards/{id}`) and each set (`/sets/{id}`) is then fetched for details.
- Pokémon TCG Pocket cards are skipped.
- Cards whose TCGdex ID differs from the old pokemontcg.io ID keep the old ID (see `LEGACY_CARDS` in `src/lib/api.ts`) so saved checklists stay valid.
- The previous source, the Pokémon TCG API (pokemontcg.io), is deprecated.
## How It Works
- The client loads data from `GET /api/magikarp` (`src/app/api/magikarp/route.ts`).
- The route fetches from TCGdex using `fetchMagikarpCards()` (`src/lib/api.ts`), caches the full response in `data/cards.json`, and serves cached data when fresh (<24h) unless `?refresh=1` is provided. If a refresh fails, the last cached data is served and marked `stale`.
- Cards render in `CardGrid`/`CardItem`, ordered by set release date.
- Checklist persists locally (v2 supports variant-level tracking). A server-backed route exists at `api/checklist` if you enable it.
## Docker
Build and run using Docker/Compose. The container listens on port 3000 internally; pick a host port via `APP_PORT`.
### Build and run
```bash
# Default host port 3000
docker compose up --build
# Custom host port
APP_PORT=8080 docker compose up --build
```
Open: http://localhost:3000 (or your chosen `APP_PORT`).
### Volumes and data
- The `./data` directory is mounted to `/app/data` in the container so cached JSON persists between restarts.
- `data/cards.json` and `data/checklist.json` are gitignored by default.
## Deployment
- **Vercel**: Zero-config for Next.js. No API key is required.
- **Netlify/Other**: Build command `npm run build`, publish `.next` with a Next adapter or use Next on Node; make sure environment vars are set.
## Troubleshooting
- "Cannot find module '@tailwindcss/postcss'": install the Tailwind v4 PostCSS plugin and ensure CommonJS config.
```bash
npm i -D @tailwindcss/postcss
# Ensure postcss.config.cjs exists with:
# module.exports = { plugins: { '@tailwindcss/postcss': {} } }
```
- Images not loading: confirm `next.config.ts` allows `assets.tcgdex.net` and restart the dev server.
- No cards shown: check the server log for `Error fetching cards`; if TCGdex is unreachable the app serves the last cached data.
## License
This project is provided as-is for personal collection tracking.