Profil: Begrüßung in Zielsprache, Kategorie-Punkte-Übersicht, ruhigerer Header (kein rotierender Avatar/Online-Dot), Notch-Fix und kompaktere Aktivitäts-Heatmap. Außerdem Capacitor-iOS-Projekt und diverse Auth/Feed/Audio-Verbesserungen aus dem Premium-Redesign. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
npm run dev # Vite dev server (default http://localhost:5173)
npm run build # Production build → dist/
npm run preview # Serve the built dist/ locally
There is no test runner and no linter configured — package.json only defines dev, build, preview. Don't suggest npm test/npm run lint.
Deployment is a two-stage Docker build (Dockerfile): Node builds dist/, then it's served by nginx (nginx.conf) with SPA fallback (try_files … /index.html).
Environment
VITE_API_URL (in .env / .env.production) points at the backend. It's the only runtime config — every API call in src/api/directus.js reads import.meta.env.VITE_API_URL. .env is gitignored.
Architecture
React 19 + Vite SPA, no router package. There are no DB cards/feed entries fetched directly — the app talks to a custom backend, not Directus directly (see below).
Routing is useState-based in src/App.jsx: a PAGES map (feed/game/pro/profil) swaps the active page component, driven by BottomNav. Game and Pro are placeholders.
Auth gating: App.jsx renders <AuthScreen /> unless the user has username, language_native_id, and language_target_id. AuthContext (src/context/AuthContext.jsx) holds the JWT (localStorage key hejyou_token), calls getMe() on mount, and clears the token on failure. Registration is two steps: RegisterStep1 (email+password) → RegisterStep2 (username + native/target language).
The API client is misnamed
src/api/directus.js is not a Directus client anymore — the module name is kept "aus historischen Gründen". It is a thin fetch wrapper around a custom backend (snakkimo-API) exposing /auth/* endpoints:
| Function | Endpoint | Notes |
|---|---|---|
login / registerUser |
POST /auth/login, /auth/register |
return { token, userId, needsProfile } |
getMe |
GET /auth/me |
basis for auth check + progress (EP/streak/level) |
checkUsername |
GET /auth/check-username |
|
createProfile |
POST /auth/profile |
username + native/target lang |
getLanguageOptions |
GET /auth/languages |
merged with local LANG_META (flag + Web Speech code) |
getFeedPairs |
GET /auth/feed?lang=&limit= |
returns "pairs", the feed unit |
saveProgress |
POST /auth/progress |
books EP/streak, returns updated total_ep |
Several content functions (getWords, getQuestions, getActiveLearningPair, assetUrl, …) are stubs returning empty/null — content endpoints are not built yet. Don't assume they fetch anything.
Feed = "pairs" → cards
src/pages/Feed.jsx fetches an array of pairs and maps each to one card by its answer_type:
answer_type |
Component | Points (POINTS map) |
|---|---|---|
text |
PairSentenceCard |
2 |
yes_no |
PairYesNoCard |
2 |
word |
PairWordCard |
3 |
question |
PairWordCard |
3 |
On completion, handleComplete adds the pair id to a local done set (cards are hidden, not removed) and POSTs to saveProgress. Target language comes from user.language_target_short (fallback de).
The Pair* cards (PairSentenceCard, PairYesNoCard, PairWordCard) are the live card components. The other card files (NewWord*, ImagePick/ImageQuiz, AudioQuiz, LetterOrder, SentenceFill, LanguageParentCard) are an earlier card model not wired into the current feed — check Feed.jsx before assuming a component is in use.
Several cards use the browser Web Speech API (SpeechRecognition / speechSynthesis) for the speak/listen flow; src/utils/confetti.js wraps canvas-confetti for correct-answer feedback.
knowledge/directus_struktur.md
A detailed reference for the backend data model (collections, fields, relations) and the original app concept. Useful for understanding the domain and DB schema, but note it predates the custom-backend migration: its "Frontend API-Funktionen" table describes direct Directus calls that no longer exist — trust src/api/directus.js for the actual frontend contract.