import { notFound } from "next/navigation"; import type { Metadata } from "next"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { SessionTimelineChart } from "@/components/sessions/SessionTimelineChart"; import { getPlaySessionDetail, getPlaySessionName } from "@/lib/db/queries/play-sessions"; import { getSessionTimeline } from "@/lib/db/queries/stats"; export const dynamic = "force-dynamic"; export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise { const { id } = await params; const name = await getPlaySessionName(Number(id)); return { title: name ?? `Session #${id}` }; } function formatDuration(ms: number | null): string { if (ms === null) return "-"; const totalSeconds = Math.round(ms / 1000); return `${Math.floor(totalSeconds / 60)}:${(totalSeconds % 60).toString().padStart(2, "0")}`; } export default async function SessionDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const sessionId = Number(id); const [detail, timeline] = await Promise.all([getPlaySessionDetail(sessionId), getSessionTimeline(sessionId)]); if (!detail) notFound(); return (

{detail.session.name ?? `Session #${detail.session.id}`}

{detail.session.kind} · {detail.session.status} · {formatDuration(detail.session.durationMs)}

Intensity timeline Devices {detail.devices.map((d) => (
{d.slotLabel} ({d.deviceDisplayName ?? d.deviceBleName})
))}
); }