feat(frontend): rewritten stats page with heatmap + progress + due
This commit is contained in:
@@ -1,20 +1,54 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { statsApi } from '../api/stats.js';
|
||||
import { Heatmap } from '../components/Heatmap.js';
|
||||
import { LessonProgressList, type LessonProgressRow } from '../components/LessonProgressList.js';
|
||||
import { DueOverviewCard, type DueOverview } from '../components/DueOverviewCard.js';
|
||||
|
||||
export function StatsPage() {
|
||||
const [heatmap, setHeatmap] = useState<{ day: string; sessions: number; attempts: number }[]>([]);
|
||||
useEffect(() => { statsApi.heatmap(12).then(setHeatmap); }, []);
|
||||
const [progress, setProgress] = useState<LessonProgressRow[]>([]);
|
||||
const [due, setDue] = useState<DueOverview | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
statsApi.heatmap(52).then(setHeatmap).catch(() => {});
|
||||
statsApi.lessonsProgress().then((r) => setProgress(r.rows)).catch(() => {});
|
||||
statsApi.due().then(setDue).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const max = Math.max(1, ...heatmap.map((d) => d.attempts));
|
||||
return (
|
||||
<div className="mx-auto max-w-4xl p-6">
|
||||
<h1 className="mb-4 text-2xl font-semibold">Statistieken</h1>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{heatmap.map((d) => (
|
||||
<div key={d.day} title={`${d.day}: ${d.attempts} pogingen`} className="h-4 w-4 rounded"
|
||||
style={{ backgroundColor: `rgba(34,197,94,${0.15 + 0.85 * (d.attempts / max)})` }} />
|
||||
))}
|
||||
</div>
|
||||
<div className="space-y-8">
|
||||
<header>
|
||||
<h1 className="font-display text-3xl font-bold">Statistieken</h1>
|
||||
<p className="text-sm text-slate-500">Houd zicht op je voortgang en wat er te oefenen valt.</p>
|
||||
</header>
|
||||
|
||||
{due && (
|
||||
<section>
|
||||
<h2 className="mb-3 font-display text-xl font-bold">⏰ Te reviewen</h2>
|
||||
<DueOverviewCard data={due} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section>
|
||||
<h2 className="mb-3 font-display text-xl font-bold">📊 Voortgang per les</h2>
|
||||
<LessonProgressList rows={progress} />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 className="mb-3 font-display text-xl font-bold">🔥 Activiteit</h2>
|
||||
<div className="surface p-4">
|
||||
<Heatmap points={heatmap} />
|
||||
<div className="mt-3 flex items-center gap-2 text-xs text-slate-500">
|
||||
<span>minder</span>
|
||||
<span className="h-3 w-3 rounded-sm bg-slate-100 dark:bg-slate-800" />
|
||||
<span className="h-3 w-3 rounded-sm bg-success-200" />
|
||||
<span className="h-3 w-3 rounded-sm bg-success-400" />
|
||||
<span className="h-3 w-3 rounded-sm bg-success-500" />
|
||||
<span className="h-3 w-3 rounded-sm bg-success-700" />
|
||||
<span>meer</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user