Phase 3b: Case Detail view with workflow timeline
New dynamic route /cases/[caseNumber] wired to the FastAPI details endpoint, using Next 16's async params pattern with React's use() hook. TanStack Query handles 5s refetchInterval so the page self-updates during long-running processing without manual polling. New components: CaseHeader (breadcrumb + meta), WorkflowTimeline (5-phase RTL pipeline view), DocumentsPanel (categorized list). Tabs split overview/documents/actions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
67
web-ui/src/components/cases/case-header.tsx
Normal file
67
web-ui/src/components/cases/case-header.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import Link from "next/link";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { StatusBadge } from "@/components/cases/status-badge";
|
||||
import type { CaseDetail } from "@/lib/api/cases";
|
||||
|
||||
function formatDate(iso?: string | null) {
|
||||
if (!iso) return "—";
|
||||
try {
|
||||
return new Date(iso).toLocaleDateString("he-IL", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
});
|
||||
} catch {
|
||||
return iso ?? "—";
|
||||
}
|
||||
}
|
||||
|
||||
export function CaseHeader({ data }: { data?: CaseDetail }) {
|
||||
return (
|
||||
<Card className="bg-surface border-rule shadow-sm">
|
||||
<CardContent className="px-6 py-5">
|
||||
<nav className="text-[0.78rem] text-ink-muted mb-3 flex items-center gap-2">
|
||||
<Link href="/" className="hover:text-gold-deep">בית</Link>
|
||||
<span aria-hidden>·</span>
|
||||
<span>תיקי ערר</span>
|
||||
<span aria-hidden>·</span>
|
||||
<span className="text-navy tabular-nums">{data?.case_number ?? "…"}</span>
|
||||
</nav>
|
||||
|
||||
<div className="flex items-start justify-between gap-6 flex-wrap">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-display text-[2rem] font-black text-navy leading-none tabular-nums">
|
||||
ערר {data?.case_number ?? "—"}
|
||||
</span>
|
||||
{data?.status && <StatusBadge status={data.status} />}
|
||||
</div>
|
||||
<h1 className="text-navy text-xl font-bold leading-snug max-w-2xl mb-0">
|
||||
{data?.title ?? "טוען…"}
|
||||
</h1>
|
||||
{data?.subject && (
|
||||
<p className="text-ink-muted text-sm max-w-2xl leading-relaxed">
|
||||
{data.subject}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<dl className="grid grid-cols-2 gap-x-6 gap-y-1 text-sm">
|
||||
<dt className="text-ink-muted text-[0.72rem] uppercase tracking-wider">
|
||||
תאריך דיון
|
||||
</dt>
|
||||
<dd className="text-ink-soft tabular-nums">{formatDate(data?.hearing_date)}</dd>
|
||||
<dt className="text-ink-muted text-[0.72rem] uppercase tracking-wider">
|
||||
עודכן
|
||||
</dt>
|
||||
<dd className="text-ink-soft tabular-nums">{formatDate(data?.updated_at)}</dd>
|
||||
<dt className="text-ink-muted text-[0.72rem] uppercase tracking-wider">
|
||||
ועדה
|
||||
</dt>
|
||||
<dd className="text-ink-soft">{data?.committee_type ?? "—"}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user