Make /learn the central landing page for parents + students

Non-DE/EN users (parents) see a guide panel explaining:
- What this page is (vocabulary exercises from teacher)
- How each exercise type works (cards, quiz, listen, speak)
- All text in parent's native language (TR/AR/UK/RU/PL)

German/English users see the original layout without the guide.
This is the single entry point — no need to duplicate explanations
in every exercise sub-page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-27 08:46:58 +02:00
parent 7f8743d1e3
commit d8771bb509

View File

@@ -3,6 +3,7 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { useTheme } from '@/lib/ThemeContext' import { useTheme } from '@/lib/ThemeContext'
import { UnitCard } from '@/components/learn/UnitCard' import { UnitCard } from '@/components/learn/UnitCard'
import { useNativeLanguage } from '@/lib/useNativeLanguage'
interface LearningUnit { interface LearningUnit {
id: string id: string
@@ -16,12 +17,87 @@ interface LearningUnit {
created_at: string created_at: string
} }
function getApiBase() { // Parent guide translations
return '' // Same-origin proxy via /api/learning-units/... const guide: Record<string, Record<string, string>> = {
welcome: {
de: 'Willkommen bei den Lernmodulen!',
en: 'Welcome to the learning modules!',
tr: 'Ogrenme modullerine hos geldiniz!',
ar: '\u0645\u0631\u062d\u0628\u0627 \u0628\u0643 \u0641\u064a \u0648\u062d\u062f\u0627\u062a \u0627\u0644\u062a\u0639\u0644\u0645!',
uk: '\u041b\u0430\u0441\u043a\u0430\u0432\u043e \u043f\u0440\u043e\u0441\u0438\u043c\u043e \u0434\u043e \u043d\u0430\u0432\u0447\u0430\u043b\u044c\u043d\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0456\u0432!',
ru: '\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438!',
pl: 'Witamy w modulach do nauki!',
},
what_is_this: {
de: 'Was ist das?',
en: 'What is this?',
tr: 'Bu nedir?',
ar: '\u0645\u0627 \u0647\u0630\u0627\u061f',
uk: '\u0429\u043e \u0446\u0435?',
ru: '\u0427\u0442\u043e \u044d\u0442\u043e?',
pl: 'Co to jest?',
},
explanation: {
de: 'Der Lehrer Ihres Kindes hat Vokabeln zusammengestellt, die Ihr Kind lernen muss. Hier koennen Sie Ihrem Kind beim Ueben helfen — auch wenn Sie selbst kein Deutsch oder Englisch sprechen. Jedes Wort wird in Ihrer Sprache angezeigt.',
en: 'Your child\'s teacher has prepared vocabulary that your child needs to learn. Here you can help your child practice — even if you don\'t speak German or English. Every word is shown in your language.',
tr: 'Cocugunuzun ogretmeni, cocugunuzun ogrenmesi gereken kelimeleri hazirladi. Burada cocugunuzun pratik yapmasina yardimci olabilirsiniz — Almanca veya Ingilizce bilmeseniz bile. Her kelime sizin dilinizde gosterilir.',
ar: '\u0623\u0639\u062f \u0645\u0639\u0644\u0645 \u0637\u0641\u0644\u0643 \u0645\u0641\u0631\u062f\u0627\u062a \u064a\u062d\u062a\u0627\u062c \u0637\u0641\u0644\u0643 \u0644\u062a\u0639\u0644\u0645\u0647\u0627. \u0647\u0646\u0627 \u064a\u0645\u0643\u0646\u0643 \u0645\u0633\u0627\u0639\u062f\u0629 \u0637\u0641\u0644\u0643 \u0639\u0644\u0649 \u0627\u0644\u062a\u062f\u0631\u064a\u0628 \u2014 \u062d\u062a\u0649 \u0644\u043e \u0644\u0645 \u062a\u062a\u062d\u062f\u062b \u0627\u0644\u0623\u0644\u0645\u0627\u0646\u064a\u0629 \u0623\u043e \u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629. \u0643\u0644 \u0643\u0644\u0645\u0629 \u062a\u0638\u0647\u0631 \u0628\u0644\u063a\u062a\u0643.',
uk: '\u0412\u0447\u0438\u0442\u0435\u043b\u044c \u0432\u0430\u0448\u043e\u0457 \u0434\u0438\u0442\u0438\u043d\u0438 \u043f\u0456\u0434\u0433\u043e\u0442\u0443\u0432\u0430\u0432 \u0441\u043b\u043e\u0432\u0430, \u044f\u043a\u0456 \u0434\u0438\u0442\u0438\u043d\u0430 \u043f\u043e\u0432\u0438\u043d\u043d\u0430 \u0432\u0438\u0432\u0447\u0438\u0442\u0438. \u0422\u0443\u0442 \u0432\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0442\u0438 \u0434\u0438\u0442\u0438\u043d\u0456 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u0432\u0430\u0442\u0438 \u2014 \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0432\u0438 \u043d\u0435 \u0440\u043e\u0437\u043c\u043e\u0432\u043b\u044f\u0454\u0442\u0435 \u043d\u0456\u043c\u0435\u0446\u044c\u043a\u043e\u044e \u0447\u0438 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u044e. \u041a\u043e\u0436\u043d\u0435 \u0441\u043b\u043e\u0432\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u0430\u0448\u043e\u044e \u043c\u043e\u0432\u043e\u044e.',
ru: '\u0423\u0447\u0438\u0442\u0435\u043b\u044c \u0432\u0430\u0448\u0435\u0433\u043e \u0440\u0435\u0431\u0435\u043d\u043a\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b \u0441\u043b\u043e\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0431\u0435\u043d\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0443\u0447\u0438\u0442\u044c. \u0417\u0434\u0435\u0441\u044c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043c\u043e\u0447\u044c \u0440\u0435\u0431\u0435\u043d\u043a\u0443 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u2014 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0435 \u043f\u043e-\u043d\u0435\u043c\u0435\u0446\u043a\u0438 \u0438\u043b\u0438 \u043f\u043e-\u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438. \u041a\u0430\u0436\u0434\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u044f\u0437\u044b\u043a\u0435.',
pl: 'Nauczyciel Twojego dziecka przygotowal slowka, ktorych dziecko musi sie nauczyc. Tutaj mozesz pomoc dziecku cwczyc — nawet jesli nie mowisz po niemiecku ani angielsku. Kazde slowo jest pokazane w Twoim jezyku.',
},
exercises_explained: {
de: 'Waehlen Sie eine Uebung:',
en: 'Choose an exercise:',
tr: 'Bir alistirma secin:',
ar: '\u0627\u062e\u062a\u0631 \u062a\u0645\u0631\u064a\u0646\u0627:',
uk: '\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0432\u043f\u0440\u0430\u0432\u0443:',
ru: '\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u0435:',
pl: 'Wybierz cwiczenie:',
},
exercise_cards: {
de: 'Karteikarten — Wort umdrehen und pruefen',
tr: 'Kartlar — Kelimeyi cevir ve kontrol et',
ar: '\u0628\u0637\u0627\u0642\u0627\u062a \u2014 \u0627\u0642\u0644\u0628 \u0627\u0644\u0643\u0644\u0645\u0629 \u0648\u062a\u062d\u0642\u0642',
uk: '\u041a\u0430\u0440\u0442\u043a\u0438 \u2014 \u041f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0456\u0442\u044c \u0441\u043b\u043e\u0432\u043e \u0456 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435',
ru: '\u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u2014 \u041f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0438\u0442\u0435 \u0441\u043b\u043e\u0432\u043e \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435',
pl: 'Fiszki — Odwroc slowo i sprawdz',
en: 'Flashcards — Flip the word and check',
},
exercise_quiz: {
de: 'Quiz — Richtige Uebersetzung aus 4 Optionen waehlen',
tr: 'Quiz — 4 secenekten dogru ceviriyi sec',
ar: '\u0627\u062e\u062a\u0628\u0627\u0631 \u2014 \u0627\u062e\u062a\u0631 \u0627\u0644\u062a\u0631\u062c\u0645\u0629 \u0627\u0644\u0635\u062d\u064a\u062d\u0629 \u0645\u0646 4 \u062e\u064a\u0627\u0631\u0627\u062a',
uk: '\u0422\u0435\u0441\u0442 \u2014 \u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434 \u0437 4 \u0432\u0430\u0440\u0456\u0430\u043d\u0442\u0456\u0432',
ru: '\u0422\u0435\u0441\u0442 \u2014 \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0438\u0437 4 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432',
pl: 'Quiz — Wybierz poprawne tlumaczenie z 4 opcji',
en: 'Quiz — Choose correct translation from 4 options',
},
exercise_listen: {
de: 'Hoeren — Wort hoeren und Uebersetzung waehlen',
tr: 'Dinleme — Kelimeyi dinle ve ceviriyi sec',
ar: '\u0627\u0633\u062a\u0645\u0627\u0639 \u2014 \u0627\u0633\u062a\u0645\u0639 \u0644\u0644\u0643\u0644\u0645\u0629 \u0648\u0627\u062e\u062a\u0631 \u0627\u0644\u062a\u0631\u062c\u0645\u0629',
uk: '\u0421\u043b\u0443\u0445\u0430\u043d\u043d\u044f \u2014 \u041f\u043e\u0441\u043b\u0443\u0445\u0430\u0439 \u0441\u043b\u043e\u0432\u043e \u0456 \u0432\u0438\u0431\u0435\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434',
ru: '\u0421\u043b\u0443\u0448\u0430\u043d\u0438\u0435 \u2014 \u041f\u043e\u0441\u043b\u0443\u0448\u0430\u0439\u0442\u0435 \u0441\u043b\u043e\u0432\u043e \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434',
pl: 'Sluchanie — Posluchaj slowa i wybierz tlumaczenie',
en: 'Listening — Hear the word and choose the translation',
},
exercise_speak: {
de: 'Sprechen — Wort hoeren und nachsprechen',
tr: 'Konusma — Kelimeyi dinle ve tekrar et',
ar: '\u062a\u062d\u062f\u062b \u2014 \u0627\u0633\u062a\u0645\u0639 \u0644\u0644\u0643\u0644\u0645\u0629 \u0648\u0643\u0631\u0631\u0647\u0627',
uk: '\u0413\u043e\u0432\u043e\u0440\u0456\u043d\u043d\u044f \u2014 \u041f\u043e\u0441\u043b\u0443\u0445\u0430\u0439 \u0441\u043b\u043e\u0432\u043e \u0456 \u043f\u043e\u0432\u0442\u043e\u0440\u0438',
ru: '\u0413\u043e\u0432\u043e\u0440\u0435\u043d\u0438\u0435 \u2014 \u041f\u043e\u0441\u043b\u0443\u0448\u0430\u0439\u0442\u0435 \u0441\u043b\u043e\u0432\u043e \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435',
pl: 'Mowienie — Posluchaj slowa i powtorz',
en: 'Speaking — Hear the word and repeat it',
},
} }
function getApiBase() { return '' }
export default function LearnPage() { export default function LearnPage() {
const { isDark } = useTheme() const { isDark } = useTheme()
const { t, nativeLang, isThirdLanguage } = useNativeLanguage()
const [units, setUnits] = useState<LearningUnit[]>([]) const [units, setUnits] = useState<LearningUnit[]>([])
const [isLoading, setIsLoading] = useState(true) const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
@@ -30,17 +106,16 @@ export default function LearnPage() {
? 'bg-white/10 backdrop-blur-xl border border-white/10' ? 'bg-white/10 backdrop-blur-xl border border-white/10'
: 'bg-white/80 backdrop-blur-xl border border-black/5' : 'bg-white/80 backdrop-blur-xl border border-black/5'
useEffect(() => { const g = (key: string) => guide[key]?.[nativeLang] || guide[key]?.['de'] || key
loadUnits()
}, []) useEffect(() => { loadUnits() }, [])
const loadUnits = async () => { const loadUnits = async () => {
setIsLoading(true) setIsLoading(true)
try { try {
const resp = await fetch(`${getApiBase()}/api/learning-units/`) const resp = await fetch(`${getApiBase()}/api/learning-units/`)
if (!resp.ok) throw new Error(`HTTP ${resp.status}`) if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
const data = await resp.json() setUnits(await resp.json())
setUnits(data)
} catch (err: any) { } catch (err: any) {
setError(err.message) setError(err.message)
} finally { } finally {
@@ -51,12 +126,8 @@ export default function LearnPage() {
const handleDelete = async (unitId: string) => { const handleDelete = async (unitId: string) => {
try { try {
const resp = await fetch(`${getApiBase()}/api/learning-units/${unitId}`, { method: 'DELETE' }) const resp = await fetch(`${getApiBase()}/api/learning-units/${unitId}`, { method: 'DELETE' })
if (resp.ok) { if (resp.ok) setUnits(prev => prev.filter(u => u.id !== unitId))
setUnits((prev) => prev.filter((u) => u.id !== unitId)) } catch {}
}
} catch (err) {
console.error('Delete failed:', err)
}
} }
return ( return (
@@ -65,27 +136,48 @@ export default function LearnPage() {
<div className={`${glassCard} border-0 border-b`}> <div className={`${glassCard} border-0 border-b`}>
<div className="max-w-5xl mx-auto px-6 py-4"> <div className="max-w-5xl mx-auto px-6 py-4">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className={`w-12 h-12 rounded-xl flex items-center justify-center ${ <div className={`w-12 h-12 rounded-xl flex items-center justify-center ${isDark ? 'bg-blue-500/30' : 'bg-blue-200'}`}>
isDark ? 'bg-blue-500/30' : 'bg-blue-200'
}`}>
<svg className={`w-6 h-6 ${isDark ? 'text-blue-300' : 'text-blue-600'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className={`w-6 h-6 ${isDark ? 'text-blue-300' : 'text-blue-600'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
</svg> </svg>
</div> </div>
<div> <div>
<h1 className={`text-xl font-bold ${isDark ? 'text-white' : 'text-slate-900'}`}> <h1 className={`text-xl font-bold ${isDark ? 'text-white' : 'text-slate-900'}`}>
Meine Lernmodule {isThirdLanguage ? g('welcome') : 'Meine Lernmodule'}
</h1> </h1>
<p className={`text-sm ${isDark ? 'text-white/60' : 'text-slate-500'}`}> <p className={`text-sm ${isDark ? 'text-white/60' : 'text-slate-500'}`}>
Karteikarten, Quiz und Lueckentexte aus deinen Vokabeln {isThirdLanguage
? g('exercises_explained')
: 'Karteikarten, Quiz und Lueckentexte aus deinen Vokabeln'}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{/* Content */}
<div className="max-w-5xl mx-auto w-full px-6 py-6"> <div className="max-w-5xl mx-auto w-full px-6 py-6">
{/* Parent Guide Panel — only for non-DE/EN users */}
{isThirdLanguage && (
<div className={`${glassCard} rounded-2xl p-6 mb-6`}>
<h3 className={`text-sm font-semibold mb-2 ${isDark ? 'text-cyan-300' : 'text-cyan-700'}`}>
{g('what_is_this')}
</h3>
<p className={`text-sm leading-relaxed mb-4 ${isDark ? 'text-white/70' : 'text-slate-600'}`}>
{g('explanation')}
</p>
<div className={`border-t pt-3 space-y-1.5 ${isDark ? 'border-white/10' : 'border-slate-200'}`}>
<p className={`text-xs ${isDark ? 'text-white/40' : 'text-slate-400'}`}>
{g('exercises_explained')}
</p>
<p className={`text-xs ${isDark ? 'text-white/60' : 'text-slate-500'}`}>🃏 {g('exercise_cards')}</p>
<p className={`text-xs ${isDark ? 'text-white/60' : 'text-slate-500'}`}> {g('exercise_quiz')}</p>
<p className={`text-xs ${isDark ? 'text-white/60' : 'text-slate-500'}`}>🔊 {g('exercise_listen')}</p>
<p className={`text-xs ${isDark ? 'text-white/60' : 'text-slate-500'}`}>🎤 {g('exercise_speak')}</p>
</div>
</div>
)}
{isLoading && ( {isLoading && (
<div className="flex items-center justify-center py-20"> <div className="flex items-center justify-center py-20">
<div className={`w-8 h-8 border-4 ${isDark ? 'border-blue-400' : 'border-blue-600'} border-t-transparent rounded-full animate-spin`} /> <div className={`w-8 h-8 border-4 ${isDark ? 'border-blue-400' : 'border-blue-600'} border-t-transparent rounded-full animate-spin`} />
@@ -94,40 +186,32 @@ export default function LearnPage() {
{error && ( {error && (
<div className={`${glassCard} rounded-2xl p-6 text-center`}> <div className={`${glassCard} rounded-2xl p-6 text-center`}>
<p className={`${isDark ? 'text-red-300' : 'text-red-600'}`}>Fehler: {error}</p> <p className={isDark ? 'text-red-300' : 'text-red-600'}>Fehler: {error}</p>
<button onClick={loadUnits} className="mt-3 px-4 py-2 rounded-xl bg-blue-500 text-white text-sm"> <button onClick={loadUnits} className="mt-3 px-4 py-2 rounded-xl bg-blue-500 text-white text-sm">
Erneut versuchen {t('again')}
</button> </button>
</div> </div>
)} )}
{!isLoading && !error && units.length === 0 && ( {!isLoading && !error && units.length === 0 && (
<div className={`${glassCard} rounded-2xl p-12 text-center`}> <div className={`${glassCard} rounded-2xl p-12 text-center`}>
<div className={`w-16 h-16 mx-auto mb-4 rounded-2xl flex items-center justify-center ${ <div className={`w-16 h-16 mx-auto mb-4 rounded-2xl flex items-center justify-center ${isDark ? 'bg-blue-500/20' : 'bg-blue-100'}`}>
isDark ? 'bg-blue-500/20' : 'bg-blue-100'
}`}>
<svg className={`w-8 h-8 ${isDark ? 'text-blue-300' : 'text-blue-600'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg className={`w-8 h-8 ${isDark ? 'text-blue-300' : 'text-blue-600'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" /> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
</svg> </svg>
</div> </div>
<h3 className={`text-lg font-semibold mb-2 ${isDark ? 'text-white' : 'text-slate-900'}`}> <h3 className={`text-lg font-semibold mb-2 ${isDark ? 'text-white' : 'text-slate-900'}`}>
Noch keine Lernmodule {isThirdLanguage ? g('welcome') : 'Noch keine Lernmodule'}
</h3> </h3>
<p className={`text-sm mb-4 ${isDark ? 'text-white/60' : 'text-slate-500'}`}> <a href="/vocabulary" className="inline-block mt-3 px-6 py-3 rounded-xl bg-gradient-to-r from-blue-500 to-cyan-500 text-white font-medium hover:shadow-lg transition-all">
Scanne eine Schulbuchseite im Vokabel-Arbeitsblatt Generator und klicke &quot;Lernmodule generieren&quot;. {isThirdLanguage ? g('exercises_explained') : 'Zum Woerterbuch'}
</p>
<a
href="/vocab-worksheet"
className="inline-block px-6 py-3 rounded-xl bg-gradient-to-r from-blue-500 to-cyan-500 text-white font-medium hover:shadow-lg transition-all"
>
Zum Vokabel-Scanner
</a> </a>
</div> </div>
)} )}
{!isLoading && units.length > 0 && ( {!isLoading && units.length > 0 && (
<div className="grid gap-4"> <div className="grid gap-4">
{units.map((unit) => ( {units.map(unit => (
<UnitCard key={unit.id} unit={unit} isDark={isDark} glassCard={glassCard} onDelete={handleDelete} /> <UnitCard key={unit.id} unit={unit} isDark={isDark} glassCard={glassCard} onDelete={handleDelete} />
))} ))}
</div> </div>