feat(frontend): apply UI/UX design system - purple/green palette, gradient buttons, 3D flip, polished pages

Applied ui-ux-pro-max design system recommendations:
- Tailwind theme: study purple primary + correct green accent
- Inter + Plus Jakarta Sans typography
- Glassmorphic surfaces with soft shadows and mesh background
- Real 3D card flip with spring physics + answer feedback flash
- Gradient stat cards, progress bar, animated done screen with score ring
- Polished Layout, Dashboard, Admin, AdminLesson, CardTable, ImportDialog, PracticeSetup, Practice, PracticeDone
- E2E smoke updated for new accessible names
This commit is contained in:
2026-05-20 21:48:47 +02:00
parent 9300af2820
commit b984e83e2b
16 changed files with 977 additions and 200 deletions

View File

@@ -15,16 +15,36 @@ export function AdminLessonPage() {
useEffect(() => { refresh(); }, [lessonId]);
return (
<div className="mx-auto max-w-4xl p-6">
<Link to="/admin" className="text-sm text-blue-600"> Lessen</Link>
<h1 className="my-3 text-2xl font-semibold">Kaarten</h1>
<div className="mb-4 flex gap-2">
<button className="rounded bg-slate-200 px-3 py-1 dark:bg-slate-800" onClick={() => setShowImport(true)}>Importeer Excel</button>
<a className="rounded bg-slate-200 px-3 py-1 dark:bg-slate-800" href={cardsApi.exportUrl(lessonId, false)}>Exporteer Excel</a>
<a className="rounded bg-slate-200 px-3 py-1 dark:bg-slate-800" href={cardsApi.exportUrl(lessonId, true)}>Exporteer + sublessen</a>
<Link to={`/practice/${lessonId}/setup`} className="ml-auto rounded bg-green-600 px-3 py-1 text-white">Start oefenen </Link>
<div className="mx-auto max-w-5xl space-y-6">
<Link to="/admin" className="inline-flex items-center gap-1 text-sm font-medium text-brand-600 hover:text-brand-700 dark:text-brand-300">
Terug naar lessen
</Link>
<header className="surface flex flex-col gap-3 p-5 sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 className="font-display text-2xl font-bold">Kaartenbeheer</h1>
<p className="mt-1 text-xs text-slate-500">{cards.length} {cards.length === 1 ? 'kaart' : 'kaarten'} in deze les</p>
</div>
<div className="flex flex-wrap gap-2">
<button className="btn-ghost" onClick={() => setShowImport(true)}>
📥 Importeer
</button>
<a className="btn-ghost" href={cardsApi.exportUrl(lessonId, false)}>
📤 Exporteer
</a>
<a className="btn-ghost" href={cardsApi.exportUrl(lessonId, true)}>
📤 + sublessen
</a>
<Link to={`/practice/${lessonId}/setup`} className="btn-success">
Start oefenen
</Link>
</div>
</header>
<div className="surface overflow-hidden p-1">
<CardTable lessonId={lessonId} cards={cards} onChange={refresh} />
</div>
<CardTable lessonId={lessonId} cards={cards} onChange={refresh} />
{showImport && <ImportDialog lessonId={lessonId} onClose={() => setShowImport(false)} onDone={refresh} />}
</div>
);