Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
assignment-dispatch-button.tsxassignment-status-badge.tsxassignments-panel.tsxcreate-mission-form.tsxgovernance-panels.tsxmission-dispatch.tsxmission-edit.tsxmission-state-actions.tsxmission-status-badge.tsxobjective-edit.tsxobjective-status-badge.tsxobjective-status-select.tsxobjectives-panel.tsxreport-list.tsxwork-orders-panel.tsx
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/components/sessions/session-card.tsx
2.8 KB
import Link from "next/link";
import { FolderGit2, GitBranch, Target, Clock } from "lucide-react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { SessionStatusBadge } from "./session-status-badge";
import { RuntimeClock } from "./runtime-clock";
import { StopButton } from "./stop-button";
import type { Session } from "@/lib/sessions/types";
/**
* A single session card on the dashboard — mirrors the briefed layout:
* executive name, status, mission, runtime, repository, branch, and the
* Open / Stop actions.
*/
function repoLabel(workingDirectory: string): string {
const parts = workingDirectory.split("/").filter(Boolean);
return parts[parts.length - 1] ?? workingDirectory;
}
export function SessionCard({ session }: { session: Session }) {
const running = session.status === "running" || session.status === "starting";
return (
<Card className="flex flex-col p-5">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<div className="truncate text-[15px] font-semibold tracking-tight text-foreground">
{session.name}
</div>
<div className="mt-0.5 truncate font-mono text-[11px] text-muted-foreground">
{session.executive}
</div>
</div>
<SessionStatusBadge status={session.status} />
</div>
<dl className="mt-4 grid grid-cols-2 gap-x-4 gap-y-3 text-[13px]">
<Field icon={Target} label="Mission">
{session.mission_id ?? "—"}
</Field>
<Field icon={Clock} label="Runtime">
<RuntimeClock
startedAt={session.started_at}
endedAt={session.stopped_at}
running={running}
className="tabular-nums"
/>
</Field>
<Field icon={FolderGit2} label="Repository">
{repoLabel(session.working_directory)}
</Field>
<Field icon={GitBranch} label="Branch">
{session.branch ?? "—"}
</Field>
</dl>
<div className="mt-5 flex items-center gap-2">
<Link href={`/sessions/${session.id}`} className="flex-1">
<Button variant="default" size="sm" className="w-full">
Open
</Button>
</Link>
<StopButton id={session.id} running={running} />
</div>
</Card>
);
}
function Field({
icon: Icon,
label,
children,
}: {
icon: typeof Target;
label: string;
children: React.ReactNode;
}) {
return (
<div className="min-w-0">
<dt className="flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-[0.1em] text-muted-foreground">
<Icon className="h-3 w-3" />
{label}
</dt>
<dd className="mt-0.5 truncate font-medium text-foreground">{children}</dd>
</div>
);
}
root · /srv/aaf