Files
sexy/components/stats/SessionsSummaryCards.tsx
T
valknarandClaude Sonnet 5 e459ccd0ed Polish replays stat into the summary card grid
The replay count was a lone plain-text bar below the three stat cards,
and read oddly as "Replayed 0x" when nothing had been replayed yet.
Fold it into the same 4-tile grid with the same styling, and show "-"
at zero instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
2026-08-30 20:31:31 +02:00

68 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
export interface SessionsSummary {
count: number;
totalDurationMs: number;
avgDurationMs: number;
totalReplays: number;
durationPerDevice: { deviceId: number; displayName: string | null; bleName: string; totalActiveMs: number }[];
}
function formatHours(ms: number): string {
return `${(ms / 3_600_000).toFixed(1)}h`;
}
function formatReplays(count: number): string {
return count === 0 ? "-" : `${count}×`;
}
export function SessionsSummaryCards({ summary }: { summary: SessionsSummary }) {
return (
<div className="flex flex-col gap-4">
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<Card className="bp-glass">
<CardHeader>
<CardTitle className="text-sm text-muted-foreground">Completed sessions</CardTitle>
</CardHeader>
<CardContent className="bp-readout text-3xl">{summary.count}</CardContent>
</Card>
<Card className="bp-glass">
<CardHeader>
<CardTitle className="text-sm text-muted-foreground">Total time</CardTitle>
</CardHeader>
<CardContent className="bp-readout text-3xl">{formatHours(summary.totalDurationMs)}</CardContent>
</Card>
<Card className="bp-glass">
<CardHeader>
<CardTitle className="text-sm text-muted-foreground">Avg session length</CardTitle>
</CardHeader>
<CardContent className="bp-readout text-3xl">
{Math.round(summary.avgDurationMs / 60_000)}m
</CardContent>
</Card>
<Card className="bp-glass">
<CardHeader>
<CardTitle className="text-sm text-muted-foreground">Replays</CardTitle>
</CardHeader>
<CardContent className="bp-readout text-3xl">{formatReplays(summary.totalReplays)}</CardContent>
</Card>
</div>
{summary.durationPerDevice.length > 0 && (
<Card className="bp-glass">
<CardHeader>
<CardTitle className="text-base">Duration per device</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-2">
{summary.durationPerDevice.map((d) => (
<div key={d.deviceId} className="flex items-center justify-between text-sm">
<span>{d.displayName ?? d.bleName}</span>
<span className="text-muted-foreground">{formatHours(d.totalActiveMs)}</span>
</div>
))}
</CardContent>
</Card>
)}
</div>
);
}