58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
import type { Dictionary } from "@/lib/i18n";
|
|
import { formatElapsed } from "@/lib/time";
|
|
import type { GlobalStats } from "@/lib/types";
|
|
|
|
type StatsPanelProps = {
|
|
stats: GlobalStats;
|
|
t: Dictionary;
|
|
};
|
|
|
|
export default function StatsPanel({ stats, t }: StatsPanelProps) {
|
|
const maxDistribution = Math.max(...Object.values(stats.winDistribution), 1);
|
|
|
|
return (
|
|
<section className="rounded-lg border border-white/10 bg-white/[0.06] p-4">
|
|
<div>
|
|
<h3 className="text-sm font-black uppercase text-white/55">{t.stats}</h3>
|
|
<p className="mt-1 text-sm text-emerald-100">{t.statsLead}</p>
|
|
</div>
|
|
|
|
<div className="mt-4 grid grid-cols-2 gap-2 sm:grid-cols-3">
|
|
<Stat label={t.streak} value={stats.currentStreak.toString()} />
|
|
<Stat label={t.maxStreak} value={stats.maxStreak.toString()} />
|
|
<Stat label={t.played} value={stats.gamesPlayed.toString()} />
|
|
<Stat label={t.perfectDays} value={stats.perfectDays.toString()} />
|
|
<Stat label={t.averageTime} value={formatElapsed(stats.averageSeconds)} />
|
|
<Stat label={t.bestTime} value={stats.bestSeconds === null ? "0:00" : formatElapsed(stats.bestSeconds)} />
|
|
</div>
|
|
|
|
<div className="mt-4">
|
|
<p className="text-xs font-black uppercase text-white/55">{t.distribution}</p>
|
|
<div className="mt-2 space-y-1.5">
|
|
{Object.entries(stats.winDistribution).map(([bucket, value]) => (
|
|
<div key={bucket} className="grid grid-cols-[24px_1fr_28px] items-center gap-2 text-xs text-white/65">
|
|
<span className="font-black">{bucket === "7" ? "X" : bucket}</span>
|
|
<span className="h-2 overflow-hidden rounded-full bg-white/10">
|
|
<span
|
|
className="block h-full origin-left animate-[grow_700ms_ease-out] rounded-full bg-emerald-400"
|
|
style={{ width: `${Math.max(8, (value / maxDistribution) * 100)}%` }}
|
|
/>
|
|
</span>
|
|
<span className="text-right font-bold">{value}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function Stat({ label, value }: { label: string; value: string }) {
|
|
return (
|
|
<div className="rounded-lg bg-black/25 p-3 text-center">
|
|
<p className="text-2xl font-black text-white">{value}</p>
|
|
<p className="mt-1 text-[10px] font-bold uppercase text-white/45">{label}</p>
|
|
</div>
|
|
);
|
|
}
|