Show session status as a badge on the detail page
Reuses SessionsTable's STATUS_VARIANT mapping (now exported) so the detail page's status matches the table's badge instead of plain text. Also drops the now-stale px-1.5 alignment padding on the meta lines now that the title input carries no horizontal padding of its own. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzyfRyA7h5rs5SCAahLAWd
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import Link from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import type { Metadata } from "next";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { SessionTimelineChart } from "@/components/sessions/SessionTimelineChart";
|
||||
import { SessionTitleEditor } from "@/components/sessions/SessionTitleEditor";
|
||||
import { STATUS_VARIANT } from "@/components/sessions/SessionsTable";
|
||||
import { getSessionDetail, getSessionName } from "@/lib/db/queries/sessions";
|
||||
import { getSessionTimeline } from "@/lib/db/queries/stats";
|
||||
import { Play } from "lucide-react";
|
||||
@@ -36,8 +38,9 @@ export default async function SessionDetailPage({ params }: { params: Promise<{
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="min-w-0 flex-1">
|
||||
<SessionTitleEditor sessionId={detail.session.id} initialName={detail.session.name} />
|
||||
<p className="mt-1 px-1.5 text-sm text-muted-foreground">
|
||||
{detail.session.status} · {formatDuration(detail.session.durationMs)}
|
||||
<p className="mt-1 flex flex-wrap items-center gap-x-1 text-sm text-muted-foreground">
|
||||
<Badge variant={STATUS_VARIANT[detail.session.status]}>{detail.session.status}</Badge>
|
||||
· {formatDuration(detail.session.durationMs)}
|
||||
{detail.session.kind === "replay" && detail.replayedFromName !== undefined && (
|
||||
<> · replayed from {detail.replayedFromName ?? `session #${detail.session.replayedSessionId}`}</>
|
||||
)}
|
||||
@@ -50,7 +53,7 @@ export default async function SessionDetailPage({ params }: { params: Promise<{
|
||||
)}
|
||||
</p>
|
||||
{detail.session.description && (
|
||||
<p className="mt-1 px-1.5 text-sm text-muted-foreground">{detail.session.description}</p>
|
||||
<p className="mt-1 text-sm text-muted-foreground">{detail.session.description}</p>
|
||||
)}
|
||||
</div>
|
||||
{canReplay && (
|
||||
|
||||
@@ -46,13 +46,13 @@ export function SessionTitleEditor({ sessionId, initialName }: { sessionId: numb
|
||||
}, [status]);
|
||||
|
||||
return (
|
||||
<div className="-ml-1.5 flex items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
placeholder={`Session #${sessionId}`}
|
||||
aria-label="Session name"
|
||||
className="min-w-0 max-w-full border-b-2 border-transparent bg-transparent px-1.5 py-0.5 font-heading text-2xl font-semibold text-foreground outline-none transition-colors placeholder:text-muted-foreground/70 hover:border-b-border focus:border-b-primary [field-sizing:content]"
|
||||
className="min-w-0 max-w-full border-b-2 border-transparent bg-transparent font-heading text-2xl font-semibold text-foreground outline-none transition-colors placeholder:text-muted-foreground/70 hover:border-b-border focus:border-b-primary [field-sizing:content]"
|
||||
/>
|
||||
<div className="relative flex size-4 shrink-0 items-center justify-center">
|
||||
<Loader2
|
||||
|
||||
@@ -25,7 +25,7 @@ export interface SessionRow {
|
||||
durationMs: number | null;
|
||||
}
|
||||
|
||||
const STATUS_VARIANT = {
|
||||
export const STATUS_VARIANT = {
|
||||
active: "default",
|
||||
completed: "secondary",
|
||||
aborted: "destructive",
|
||||
|
||||
Reference in New Issue
Block a user