Add detail pages, property panels, and restyle list pages

New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Forgotten
2026-02-17 09:57:06 -06:00
parent fad1bd27ce
commit f4339668f3
22 changed files with 1833 additions and 293 deletions

View File

@@ -0,0 +1,79 @@
import type { Agent } from "@paperclip/shared";
import { StatusBadge } from "./StatusBadge";
import { formatCents, formatDate } from "../lib/utils";
import { Separator } from "@/components/ui/separator";
interface AgentPropertiesProps {
agent: Agent;
}
function PropertyRow({ label, children }: { label: string; children: React.ReactNode }) {
return (
<div className="flex items-center justify-between py-1.5">
<span className="text-xs text-muted-foreground">{label}</span>
<div className="flex items-center gap-1.5">{children}</div>
</div>
);
}
export function AgentProperties({ agent }: AgentPropertiesProps) {
return (
<div className="space-y-4">
<div className="space-y-1">
<PropertyRow label="Status">
<StatusBadge status={agent.status} />
</PropertyRow>
<PropertyRow label="Role">
<span className="text-sm">{agent.role}</span>
</PropertyRow>
{agent.title && (
<PropertyRow label="Title">
<span className="text-sm">{agent.title}</span>
</PropertyRow>
)}
<PropertyRow label="Adapter">
<span className="text-sm font-mono">{agent.adapterType}</span>
</PropertyRow>
<PropertyRow label="Context">
<span className="text-sm">{agent.contextMode}</span>
</PropertyRow>
</div>
<Separator />
<div className="space-y-1">
<PropertyRow label="Budget">
<span className="text-sm">
{formatCents(agent.spentMonthlyCents)} / {formatCents(agent.budgetMonthlyCents)}
</span>
</PropertyRow>
<PropertyRow label="Utilization">
<span className="text-sm">
{agent.budgetMonthlyCents > 0
? Math.round((agent.spentMonthlyCents / agent.budgetMonthlyCents) * 100)
: 0}
%
</span>
</PropertyRow>
</div>
<Separator />
<div className="space-y-1">
{agent.lastHeartbeatAt && (
<PropertyRow label="Last Heartbeat">
<span className="text-sm">{formatDate(agent.lastHeartbeatAt)}</span>
</PropertyRow>
)}
{agent.reportsTo && (
<PropertyRow label="Reports To">
<span className="text-sm font-mono">{agent.reportsTo.slice(0, 8)}</span>
</PropertyRow>
)}
<PropertyRow label="Created">
<span className="text-sm">{formatDate(agent.createdAt)}</span>
</PropertyRow>
</div>
</div>
);
}