---
estimated_steps: 40
estimated_files: 11
skills_used: []
---

# T02: Bootstrap React + Vite + TypeScript frontend with API client

Replace the placeholder frontend with a real React + Vite + TypeScript application. Install dependencies, configure Vite with API proxy for development, create the app shell with React Router, and build a typed API client module for the review endpoints. Verify `npm run build` produces `dist/index.html` compatible with the existing Docker build pipeline.

## Steps

1. Initialize the React app in `frontend/`. Replace `package.json` with proper dependencies:
   - `react`, `react-dom`, `react-router-dom` for the app
   - `typescript`, `@types/react`, `@types/react-dom` for types
   - `vite`, `@vitejs/plugin-react` for build tooling
   - Scripts: `dev` → `vite`, `build` → `tsc -b && vite build`, `preview` → `vite preview`

2. Create `frontend/vite.config.ts` with React plugin and dev server proxy (`/api` → `http://localhost:8001`) so the frontend dev server can reach the backend during development.

3. Create `frontend/tsconfig.json` and `frontend/tsconfig.app.json` with strict TypeScript config targeting ES2020+ and JSX.

4. Create `frontend/index.html` — Vite entry point with `<div id="root">` and `<script type="module" src="/src/main.tsx">`.

5. Create app shell files:
   - `frontend/src/main.tsx` — ReactDOM.createRoot, render App with BrowserRouter
   - `frontend/src/App.tsx` — Routes: `/admin/review` → ReviewQueue page, `/admin/review/:momentId` → MomentDetail page, `/` → redirect to `/admin/review`. Simple nav header with "Chrysopedia Admin" title.
   - `frontend/src/App.css` — Minimal admin styles: clean sans-serif typography, card-based layout, status badge colors (pending=amber, approved=green, edited=blue, rejected=red)

6. Create `frontend/src/api/client.ts` — Typed API client with functions for all review endpoints:
   - `fetchQueue(params)` → GET /api/v1/review/queue
   - `fetchStats()` → GET /api/v1/review/stats
   - `approveMoment(id)` → POST /api/v1/review/moments/{id}/approve
   - `rejectMoment(id)` → POST /api/v1/review/moments/{id}/reject
   - `editMoment(id, data)` → PUT /api/v1/review/moments/{id}
   - `splitMoment(id, splitTime)` → POST /api/v1/review/moments/{id}/split
   - `mergeMoments(id, targetId)` → POST /api/v1/review/moments/{id}/merge
   - `getReviewMode()` → GET /api/v1/review/mode
   - `setReviewMode(enabled)` → PUT /api/v1/review/mode
   All functions use fetch() with proper error handling. TypeScript interfaces for all request/response types.

7. Create placeholder page components (just enough to verify routing works):
   - `frontend/src/pages/ReviewQueue.tsx` — renders "Review Queue" heading + "Loading..." text
   - `frontend/src/pages/MomentDetail.tsx` — renders "Moment Detail" heading + shows moment ID from URL params

8. Run `npm install` and `npm run build` to verify the build produces `dist/index.html`. Verify the output directory structure matches what `docker/Dockerfile.web` expects.

## Must-Haves

- [ ] `npm run build` succeeds and produces `dist/index.html`
- [ ] `npm run dev` starts Vite dev server
- [ ] React Router routes `/admin/review` and `/admin/review/:momentId` render correctly
- [ ] API client module exports typed functions for all 9 review endpoints
- [ ] TypeScript compilation passes with no errors
- [ ] Build output is compatible with existing `docker/Dockerfile.web` (files in `dist/`)

## Verification

- `cd frontend && npm run build && test -f dist/index.html` — build succeeds
- `cd frontend && npx tsc --noEmit` — TypeScript has no errors
- `grep -q 'fetchQueue\|approveMoment\|getReviewMode' frontend/src/api/client.ts` — API client has key functions

## Inputs

- ``frontend/package.json` — existing placeholder to replace`
- ``docker/Dockerfile.web` — Docker build expects npm ci + npm run build → dist/`
- ``docker/nginx.conf` — SPA serving with /api/ proxy`
- ``backend/routers/review.py` — API endpoint signatures to match in client`

## Expected Output

- ``frontend/package.json` — updated with React, Vite, TypeScript dependencies`
- ``frontend/vite.config.ts` — Vite config with React plugin and API proxy`
- ``frontend/tsconfig.json` — TypeScript project config`
- ``frontend/tsconfig.app.json` — TypeScript app config`
- ``frontend/index.html` — SPA entry point`
- ``frontend/src/main.tsx` — React app entry`
- ``frontend/src/App.tsx` — App shell with React Router`
- ``frontend/src/App.css` — Admin UI styles`
- ``frontend/src/api/client.ts` — Typed API client for review endpoints`
- ``frontend/src/pages/ReviewQueue.tsx` — Queue page placeholder`
- ``frontend/src/pages/MomentDetail.tsx` — Moment detail page placeholder`

## Verification

cd frontend && npm run build && test -f dist/index.html && npx tsc --noEmit
