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:
2026-04-11 16:06:27 +00:00
parent 51064f3a03
commit d0daa0efe8
5 changed files with 367 additions and 1 deletions

View File

@@ -74,10 +74,34 @@ export function useCase(caseNumber: string | undefined) {
return useQuery({
queryKey: casesKeys.detail(caseNumber ?? ""),
queryFn: ({ signal }) =>
apiRequest<CaseDetail>(`/api/cases/${caseNumber}`, { signal }),
apiRequest<CaseDetail>(`/api/cases/${caseNumber}/details`, { signal }),
enabled: Boolean(caseNumber),
/* Replaces the old 5s polling from vanilla index.html */
staleTime: 5_000,
refetchInterval: 5_000,
});
}
export type WorkflowStatus = {
case_number?: string;
status?: CaseStatus | string;
current_step?: string;
steps?: Array<{
key: string;
label?: string;
status: "done" | "current" | "pending" | string;
}>;
/* FastAPI returns free-form JSON; keep it permissive */
[key: string]: unknown;
};
export function useWorkflowStatus(caseNumber: string | undefined) {
return useQuery({
queryKey: [...casesKeys.all, "workflow", caseNumber ?? ""] as const,
queryFn: ({ signal }) =>
apiRequest<WorkflowStatus>(`/api/cases/${caseNumber}/status`, { signal }),
enabled: Boolean(caseNumber),
staleTime: 5_000,
refetchInterval: 5_000,
});
}