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>
146 lines
6.3 KiB
Markdown
146 lines
6.3 KiB
Markdown
# 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.
|