From 7f8743d1e35abb00e3d296634a1e77c8dde30b11 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 27 Apr 2026 08:16:30 +0200 Subject: [PATCH] Redesign Parent Quiz: explanation panel + trilingual buttons Major improvements for non-DE/EN speaking parents: 1. Right panel: Explains in parent's native language what this exercise is about and how it works (TR/AR/UK/RU/PL translations) 2. Trilingual buttons: "Dogru" (primary) with "Richtig / Correct" subtitle so parents understand even if language detection is wrong 3. Native word shown prominently: "= elma" next to "apple" 4. Audio buttons labeled EN/DE/TR with language codes 5. Answer card shows all 3 languages: English, Deutsch, native 6. Progress tracker in the explanation panel Co-Authored-By: Claude Opus 4.6 (1M context) --- studio-v2/app/parent/quiz/[unitId]/page.tsx | 215 +++++++++++++------- 1 file changed, 146 insertions(+), 69 deletions(-) diff --git a/studio-v2/app/parent/quiz/[unitId]/page.tsx b/studio-v2/app/parent/quiz/[unitId]/page.tsx index 38c74ca..f90ba34 100644 --- a/studio-v2/app/parent/quiz/[unitId]/page.tsx +++ b/studio-v2/app/parent/quiz/[unitId]/page.tsx @@ -12,7 +12,27 @@ interface QAItem { translations?: Record } -// UI translations now come from useNativeLanguage() hook + exerciseTranslations.ts +// Context explanations in all languages +const parentGuide: Record> = { + title: { + de: 'Vokabelabfrage fuer Ihr Kind', + en: 'Vocabulary quiz for your child', + tr: 'Cocugunuz icin kelime sorgusu', + ar: '\u0627\u062e\u062a\u0628\u0627\u0631 \u0645\u0641\u0631\u062f\u0627\u062a \u0644\u0637\u0641\u0644\u0643', + uk: '\u041e\u043f\u0438\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u043b\u0456\u0432 \u0434\u043b\u044f \u0432\u0430\u0448\u043e\u0457 \u0434\u0438\u0442\u0438\u043d\u0438', + ru: '\u041e\u043f\u0440\u043e\u0441 \u0441\u043b\u043e\u0432 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0440\u0435\u0431\u0435\u043d\u043a\u0430', + pl: 'Test slowek dla Twojego dziecka', + }, + how_it_works: { + de: 'So funktioniert es: Druecken Sie den Lautsprecher — Ihr Kind hoert das englische Wort und sagt die deutsche Uebersetzung. Sie sehen die richtige Antwort und koennen pruefen ob Ihr Kind richtig liegt.', + en: 'How it works: Press the speaker — your child hears the English word and says the German translation. You see the correct answer and can check.', + tr: 'Nasil calisir: Hoparlore basin — cocugunuz Ingilizce kelimeyi duyar ve Almanca cevirisini soyler. Siz dogru cevabi gorursunuz ve kontrol edebilirsiniz.', + ar: '\u0643\u064a\u0641 \u064a\u0639\u0645\u0644: \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0645\u0643\u0628\u0631 \u2014 \u0637\u0641\u0644\u0643 \u064a\u0633\u0645\u0639 \u0627\u0644\u0643\u0644\u0645\u0629 \u0628\u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629 \u0648\u064a\u0642\u0648\u0644 \u0627\u0644\u062a\u0631\u062c\u0645\u0629 \u0628\u0627\u0644\u0623\u0644\u0645\u0627\u0646\u064a\u0629. \u062a\u0631\u0649 \u0627\u0644\u0625\u062c\u0627\u0628\u0629 \u0627\u0644\u0635\u062d\u064a\u062d\u0629 \u0648\u064a\u0645\u0643\u0646\u0643 \u0627\u0644\u062a\u062d\u0642\u0642.', + uk: '\u042f\u043a \u0446\u0435 \u043f\u0440\u0430\u0446\u044e\u0454: \u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u043d\u0430 \u0434\u0438\u043d\u0430\u043c\u0456\u043a \u2014 \u0434\u0438\u0442\u0438\u043d\u0430 \u043f\u043e\u0447\u0443\u0454 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u0435 \u0441\u043b\u043e\u0432\u043e \u0456 \u043a\u0430\u0436\u0435 \u043d\u0456\u043c\u0435\u0446\u044c\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434. \u0412\u0438 \u0431\u0430\u0447\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u044c.', + ru: '\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442: \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u043a \u2014 \u0440\u0435\u0431\u0435\u043d\u043e\u043a \u0443\u0441\u043b\u044b\u0448\u0438\u0442 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0438 \u0441\u043a\u0430\u0436\u0435\u0442 \u043d\u0435\u043c\u0435\u0446\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434. \u0412\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.', + pl: 'Jak to dziala: Nacisnij glosnik — dziecko slyszy angielskie slowo i mowi niemiecki odpowiednik. Widzisz poprawna odpowiedz i mozesz sprawdzic.', + }, +} export default function ParentQuizPage() { const { unitId } = useParams<{ unitId: string }>() @@ -27,11 +47,14 @@ export default function ParentQuizPage() { const [isLoading, setIsLoading] = useState(true) const [stats, setStats] = useState({ correct: 0, incorrect: 0 }) const [isComplete, setIsComplete] = useState(false) + const [showGuide, setShowGuide] = useState(true) const glassCard = isDark ? 'bg-white/10 backdrop-blur-xl border border-white/10' : 'bg-white/80 backdrop-blur-xl border border-black/5' + const pg = (key: string) => parentGuide[key]?.[nativeLang] || parentGuide[key]?.['de'] || key + useEffect(() => { fetch(`/api/learning-units/${unitId}/qa`) .then(r => r.ok ? r.json() : { qa_items: [] }) @@ -46,34 +69,33 @@ export default function ParentQuizPage() { incorrect: prev.incorrect + (correct ? 0 : 1), })) setShowAnswer(false) - if (currentIndex + 1 >= items.length) { setIsComplete(true) } - else { setCurrentIndex(i => i + 1) } + if (currentIndex + 1 >= items.length) setIsComplete(true) + else setCurrentIndex(i => i + 1) }, [currentIndex, items.length]) const currentItem = items[currentIndex] - const nativeTranslation = wordInNative(currentItem?.translations) + const nativeWord = wordInNative(currentItem?.translations) if (isLoading) { - return ( -
-
-
- ) + return
+
+
} return ( -
- +
{/* Header */}
-
+
{t('question')} {currentIndex + 1}/{items.length} - +
@@ -82,9 +104,9 @@ export default function ParentQuizPage() {
-
+
{isComplete ? ( -
+
{stats.correct > stats.incorrect ? '\uD83C\uDF89' : '\uD83D\uDCAA'}

{t('done')}

@@ -92,74 +114,129 @@ export default function ParentQuizPage() {

+ className="flex-1 py-3 rounded-xl bg-gradient-to-r from-blue-500 to-cyan-500 text-white font-medium"> + {t('again')} + + className={`flex-1 py-3 rounded-xl border font-medium ${isDark ? 'border-white/20 text-white/80' : 'border-slate-300 text-slate-700'}`}> + {t('back')} +
) : currentItem ? ( -
- {/* Instruction for parent */} -

- {t('ask_child')} -

+
+ {/* Left: Quiz Card */} +
+ {/* Instruction */} +

+ {t('ask_child')} +

- {/* Word to ask */} -
- - {currentItem.question} - - {nativeTranslation && ( -

- ({nativeTranslation}) + {/* Word Card */} +

+ {/* English word */} + ENGLISH +

+ {currentItem.question}

- )} -
- - {nativeTranslation && ( - + + {/* Native translation */} + {nativeWord && ( +

+ = {nativeWord} +

)} + + {/* Audio buttons */} +
+
+ + EN +
+ {nativeWord && ( +
+ + {nativeLang.toUpperCase()} +
+ )} +
+
+ + {/* Show/Hide Answer */} + + + {/* Answer */} + {showAnswer && ( +
+

{t('correct_answer')}

+ DEUTSCH +

+ {currentItem.answer} +

+ {nativeWord && ( +

+ = {nativeWord} +

+ )} +
+
+ + DE +
+
+
+ )} + + {/* Trilingual Buttons */} +
+ +
- {/* Show/Hide Answer */} - - - {showAnswer && ( -
-

{t('correct_answer')}

- - {currentItem.answer} - - {nativeTranslation && ( -

- ({nativeTranslation}) + {/* Right: Explanation Card (in parent's native language) */} + {showGuide && ( +

+
+

+ {pg('title')} +

+

+ {pg('how_it_works')}

- )} -
- + +
+

+ {items.length} {t('cards').toLowerCase()} · {t('question')} {currentIndex + 1} +

+
+
+
+ {stats.correct + stats.incorrect > 0 && ( +

+ ✅ {stats.correct}   ❌ {stats.incorrect} +

+ )} +
)} - - {/* Right/Wrong Buttons */} -
- - -
) : null}