Files
lang-quiz/README.md
Victor Giers 1d9e7cbcbb auto-git:
[add] README.md
 [add] client/.gitignore
 [add] client/README.md
 [add] client/eslint.config.js
 [add] client/index.html
 [add] client/package.json
 [add] client/public/vite.svg
 [add] client/src/App.css
 [add] client/src/App.tsx
 [add] client/src/api.ts
 [add] client/src/assets/react.svg
 [add] client/src/components/EntryCard.tsx
 [add] client/src/components/ItemPanels.tsx
 [add] client/src/components/QuizRunner.tsx
 [add] client/src/components/VideoPlayer.tsx
 [add] client/src/index.css
 [add] client/src/main.tsx
 [add] client/src/pages/EntryPage.tsx
 [add] client/src/pages/OverviewPage.tsx
 [add] client/src/pages/QuizPage.tsx
 [add] client/src/types.ts
 [add] client/tsconfig.app.json
 [add] client/tsconfig.json
 [add] client/tsconfig.node.json
 [add] client/vite.config.ts
 [add] gemini_replicate_batch.py
 [add] package.json
 [add] prompt.txt
 [add] server/package.json
 [add] server/src/index.ts
 [add] server/tsconfig.json
2026-01-07 18:35:20 +01:00

2.3 KiB
Raw Blame History

IG Japanese Quizzer

A full-stack web app for drilling Japanese grammar, vocabulary, and phrases from locally stored Instagram posts. The server indexes every *.mp4 + matching *.json pair under data/ and exposes them to a React/Vite frontend with a quiz wizard.

Quick start

  1. Install dependencies (root workspace):
    npm install
    
  2. Run both servers (frontend on 5173, backend on 5174):
    npm run dev
    
    • Vite proxies /api and /data to the Express server, so the client can use relative URLs.
  3. Open the app at http://localhost:5173.

Scripts

  • npm run dev concurrently runs server (Express + ts-node-dev) and client (Vite dev server).
  • npm run build builds the server TypeScript and Vite client.
  • npm run dev --workspace server / npm run dev --workspace client run either side individually.

Data layout

Files live under data/ (scanned recursively):

data/<POST_ID>/<FILENAME>.mp4
\_ <FILENAME>.json   # quiz payload for that video
  • Base filenames must match. Extra sidecars (.raw.txt, .mp4.json, images) are ignored.
  • The JSON structure is tolerant but expects keys: meta, items, quiz, ui_hints (additional fields are ignored).
  • entry_id is the path from data/ to the mp4 without the .mp4 extension (e.g., C1abc/12345). It is URL-encoded in routes/query params.
  • Videos are served statically at /data/... by the backend; JSON is only accessible through the API.

API

  • GET /api/entries → list of entries { id, title, mode, type, counts, video_url }, sorted by title.
  • GET /api/entry?id=<entry_id> → full entry JSON plus derived fields { id, title, video_url, counts }.

Frontend features

  • Overview grid of all entries with counts and metadata.
  • Entry detail page with embedded video and learning panels.
  • Quiz Wizard with three modes:
    • All entries (random 10 questions)
    • Selected entries (checkbox picker)
    • Single entry (linked from detail page)
  • Quiz types: cloze input, multiple-choice variants, match pairs, and best reply. Wrong answers reveal explanations and the source video.

Notes

  • The server prevents path traversal by validating resolved paths against the data root and only serving scanned entries.
  • Update or add new posts by dropping files into data/ and restarting the server to rescan.