Commit Graph

26 Commits

Author SHA1 Message Date
0e51fd8847 docs: CLAUDE.md – Fortschritts-/Feier-System + erweiterter API-Vertrag
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:17:04 +02:00
14fb0dcbe9 feat: Streak-Reminder – In-App-Nudge + lokale Tages-Erinnerung
- streak.js: Zustand aus last_practice_at (safe/at_risk/broken/none)
- Feed: Loss-Aversion-Bar "X-Tage-Serie – nur noch Y Std heute!" wenn die Serie heute abläuft
- Profil-Streak-Zeile zeigt Status (heute gesichert ✓ / noch X Std)
- Lokale Tages-Erinnerung via @capacitor/local-notifications (kein APNs nötig),
  geplant bei Login, abgebrochen sobald heute geübt – nativ; web no-op

Hinweis: nativ erst nach 'npx cap sync ios' + Rebuild aktiv.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:14:26 +02:00
98543979db feat: Erfolge im Feed-Overlay + Profil-Sektion
- getAchievements() im API-Client
- unlocked_achievements aus saveProgress als Overlay-Typ 'achievement'
- ERFOLGE-Sektion im Profil (freigeschaltet/gesperrt), degradiert lautlos ohne Endpoint

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 21:54:02 +02:00
039d2cbbf4 feat: Fortschritt spürbar machen – Momente, Momentum & Storytelling
- +EP-Float am Button + hochzählendes EP-Badge (EpFloat, useCountUp)
- Level-/Streak-/Tagesziel-Overlay (MilestoneOverlay), getriggert aus der saveProgress-Response
- Combo-Zähler + variables Lob, ermutigendes Fehler-Feedback statt stillem Verschwinden
- Session-Summary mit Story-Zeilen statt End-Sackgasse
- Profil führt mit %-bis-Level + Capability-Satz; Kategorie-Stufen, Wochenvergleich, Sound-Toggle
- Level-Kurve gespiegelt (utils/leveling.js); Level deploy-unabhängig aus EP abgeleitet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 21:43:56 +02:00
9e8af27d51 docs: CLAUDE.md – getStats/categories + Profil-Greeting ergänzen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:48:25 +02:00
c998242cc6 fix: Zoom/Scroll auf iOS unterbinden (Viewport-Scale gesperrt)
WebView öffnete zoomed-in → Inhalt größer als Viewport → scrollbar.
maximum-scale/user-scalable=no im Viewport-Meta + text-size-adjust
und touch-action: manipulation sperren Pinch-/Auto-Zoom.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 13:49:56 +02:00
e7b4ec571e feat: persönlichere Profilseite + iOS-App-Setup
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>
2026-06-15 12:55:13 +02:00
712f9a243c feat: Premium-Redesign + Fortschritts-UI
- Zentrales Design-Token-System in index.css (Farben/Spacing/Radien/Schatten/Fonts)
- Alle Live-Screens auf Tokens: Karten, BottomNav (aktiver Pill), Feed, Auth
- Auth: DM Sans entfernt, Akzent vereinheitlicht (Braun), Tokens gescoped
- Profil neu: Tagesziel-Ring, Streak-Heatmap, Wochen-Graph, echter Skills-Radar, Eckdaten
- Feed-EP-Badge mit Tagesziel-Ring (ProgressRing-Komponente)
- Game/Pro als gestaltetes 'Bald verfügbar' (ComingSoon)
- Konsumiert neue API: getStats/setDailyGoal, degradiert sauber bei 404

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:41:09 +02:00
8154f08e04 fix: index.html nicht cachen + unaufgelöste ⟦PHn:wort⟧-Tokens defensiv anzeigen
- nginx: Cache-Control no-cache für index.html — Browser hingen sonst auf
  alten JS-Bundles (gehashte Assets bleiben immutable gecacht)
- Karten: Pipeline-Tokens ⟦PHn:wort⟧ aus der Übersetzung werden als blankes
  Wort gerendert/gesprochen statt roh angezeigt (Datenfix gehört ins Backend)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:58:28 +02:00
acfd57ee87 feat: echte Pair-Audios statt TTS, Klick auf Satz spielt Audio (preloaded)
- usePairAudio-Hook: preload beim Kachel-Mount, nur eine Stimme gleichzeitig
- PairSentenceCard: audio_url statt speechSynthesis (TTS nur noch Fallback)
- PairYesNoCard/PairWordCard: Frage klickbar + Speaker-Button (vorher kein Audio)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 21:49:21 +02:00
e7dbb9d0a7 feat: EP-Fortschritt speichern + echtes Profil
- saveProgress/getUserProgress (POST /auth/progress, /auth/me)
- Feed: onComplete bucht EP, EP-Zähler oben
- Profil: echte total_ep/level/streak statt hartkodiert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 21:30:11 +02:00
6b31fddb27 PairWordCard: partial correct selection counts as correct
A subset of correct words with no wrong selections now triggers confetti and marks the card as solved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 10:46:49 +02:00
1b44e004bd PairWordCard: multi-select — toggle multiple words before confirming
Selected IDs tracked in a Set; correct only if all right words
chosen and no wrong ones. Missed correct answers shown green after
confirm; wrong picks shown red.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:36:42 +02:00
75bb75853e PairWordCard: two-step select then confirm flow
Tapping an option now highlights it (warm gold border); a
"Bestätigen" button activates once something is selected.
Answer is only evaluated on confirmation, not on tap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:23:42 +02:00
49f9953342 fix: remove FRAGE/SATZ/ANTWORT/VOKABELN section labels from all cards
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:13:48 +02:00
a0572c928b feat: remove header row, add unlock gate + ring animation to Satz card
- Remove lang/points header from all 3 card types
- PairSentenceCard: Verstanden button locked until audio played OR
  translate button held for 2 seconds
- Hold button shows circular gold ring filling up over 2s while held
- TTS button highlights gold when unlocked
- .pair-btn-locked style for disabled state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:04:38 +02:00
f299769ee9 fix: restore 1:1 image ratio — remove max-height constraint
The max-height broke the square aspect ratio needed for object coordinate
overlays. Layout fix in App.jsx already ensures correct heights; the
image constraint was unnecessary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 12:56:36 +02:00
ea3a309b2d fix: fix nav scrolling and card layout on mobile
- App.jsx: use flex column layout so BottomNav stays at bottom and
  never scrolls away; Feed gets a proper definite height for scroll-snap
- Feed.css: feed-slot uses min-height so long cards can grow, align top
- PairCards.css: cap image at 40dvh so card always fits on screen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:35:31 +02:00
025b677257 fix: remove /languparent path prefix and align auth/feed flow with API
- Remove /languparent prefix from all API calls (routes are at /auth/* now)
- Align register/login token handling (JWT returned directly, no registration token)
- Feed rewritten to use new getFeedPairs endpoint with PairSentenceCard/YesNoCard/WordCard
- App.jsx: check language_native_id / language_target_id for profile completeness
- Profil.jsx: add logout button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 15:04:20 +02:00
f86f42526f fix: point production API URL to snakkimo endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 14:40:05 +02:00
b674178771 feat: card redesign with new placeholder format, confetti & layout
- New placeholder format {{label.w/o:uuid}} parsed in all card types
- 1:1 image ratio, header below image, section labels (Satz/Frage/Vokabeln)
- Chips styled as underline-italic in sentences
- Vocabulary pill chips (Lora italic, rounded)
- TTS + hold-to-translate buttons in PairSentenceCard
- Confetti on correct answers (canvas-confetti)
- Picture loaded via object_pairs join in feed API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 13:47:52 +02:00
fb71af5f1d Redesign pair cards + add chip image highlight
- Complete CSS overhaul: refined typography, warm palette, 4:3 images, elegant chips
- Word chip click → popup badge with word + translation
- Object chip click → SVG bbox overlay dims image outside object bounds, draws amber outline
- All three card types (Sentence, YesNo, Word) updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 21:30:38 +02:00
520d0d139c security: K2 fix — registration token flow
registerUser() returns { registrationToken } (10-Min JWT)
createProfile() sends it as X-Registration-Token header
userId nie mehr aus Browser-Body — kommt aus signiertem Token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 22:55:53 +02:00
bccec179a4 feat: migrate from Directus direct → API server (api.hejyou.com)
- directus.js: all calls now go to /languparent/* on api.hejyou.com
- Admin token and Directus URL no longer in the browser
- JWT issued by API server (30 days), stored in localStorage
- register: single call returns userId, profile step gets fresh JWT
- login: handles needsProfile flag (403) cleanly
- assetUrl: proxy via /languparent/assets/:fileId (no token in URL)
- .env.production: VITE_DIRECTUS_URL → VITE_API_URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 22:43:36 +02:00
0730fe6e8e chore: add .env.production and simplify Dockerfile
Bake VITE_DIRECTUS_URL into production build via .env.production
so no Coolify build-arg configuration is needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 22:19:15 +02:00
a708152fc1 init: HejYou Language Learning App (React + Vite)
React SPA with Vite, Directus backend, canvas-confetti.
Includes Dockerfile (multi-stage Node → nginx) for Coolify deployment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 22:15:51 +02:00