feat(case-ui): full-width tabs + parties popover + subject on title line #378

Merged
chaim merged 1 commits from worktree-header-tabs-tweaks into main 2026-06-30 19:03:25 +00:00
2 changed files with 55 additions and 31 deletions

View File

@@ -80,10 +80,12 @@ export default function CaseDetailPage({
];
// V2 "segmented" tab strip (X17): each tab a pill, active = raised white card.
// Spread full-width via justify-between (chair request) — wide gaps with few
// tabs, tightening as more are added; gap-2 is the no-overlap floor.
const tabsList = (
<TabsList
variant="line"
className="!h-auto gap-1.5 p-0 flex-wrap justify-start"
className="!h-auto w-full gap-2 p-0 justify-between"
>
{tabDefs.map(([value, label, Icon]) => (
<TabsTrigger

View File

@@ -10,17 +10,14 @@ import {
APPEAL_SUBTYPE_LABELS,
isBlamSubtype,
} from "@/lib/practice-area";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Users } from "lucide-react";
import type { CaseDetail } from "@/lib/api/cases";
function partiesLine(data?: CaseDetail): string | null {
const appellant = data?.appellants?.filter(Boolean) ?? [];
const respondent = data?.respondents?.filter(Boolean) ?? [];
const parts: string[] = [];
if (appellant.length) parts.push(`עוררת: ${appellant.join(", ")}`);
if (respondent.length) parts.push(`משיבה: ${respondent.join(", ")}`);
return parts.length ? parts.join(" · ") : null;
}
/**
* Case header — parchment band (IA-redesign mockup 17): full-bleed band with
* the case title + status/type chips inline, a parties line, the case actions
@@ -38,7 +35,9 @@ export function CaseHeader({
actions?: ReactNode;
tabs?: ReactNode;
}) {
const parties = partiesLine(data);
const appellants = data?.appellants?.filter(Boolean) ?? [];
const respondents = data?.respondents?.filter(Boolean) ?? [];
const hasParties = appellants.length > 0 || respondents.length > 0;
const isBlam =
data?.proceeding_type === 'בל"מ' || isBlamSubtype(data?.appeal_subtype);
@@ -61,6 +60,12 @@ export function CaseHeader({
<span className="tabular-nums">
{data?.proceeding_type ?? "ערר"} {data?.case_number ?? "—"}
</span>
{/* case subject on the same line, smaller font (chair request) */}
{data?.title && (
<span className="text-navy/75 text-lg font-semibold leading-snug">
{data.title}
</span>
)}
{data?.status && <StatusBadge status={data.status} />}
{data?.archived_at && (
<Badge
@@ -92,27 +97,44 @@ export function CaseHeader({
)}
</h1>
{/* case title / subject under the heading */}
{data?.title && (
<p className="text-navy/90 text-base font-semibold mt-2 max-w-3xl leading-snug">
{data.title}
</p>
)}
{/* parties line (mockup .parties) — clamped to 2 lines so a long list
of appellants/respondents doesn't grow the band; full text on hover. */}
{parties ? (
<p className="text-ink-soft text-sm mt-1.5 max-w-3xl line-clamp-2" title={parties}>
{parties}
</p>
) : data?.subject ? (
<p className="text-ink-soft text-sm mt-1.5 max-w-3xl leading-relaxed line-clamp-2"
title={data.subject}>
{data.subject}
</p>
) : null}
{/* case actions — kept verbatim, moved into the band */}
{/* case actions — parties now live in a popover (chair request) so
they don't push the tab content down the page. */}
<div className="flex items-center gap-2 flex-wrap mt-3">
{hasParties && (
<Popover>
<PopoverTrigger asChild>
<button
type="button"
className="inline-flex items-center gap-1.5 rounded-md border border-rule bg-surface px-3 py-1.5 text-[0.82rem] font-semibold text-ink-soft hover:bg-parchment transition-colors"
>
<Users className="w-3.5 h-3.5" />
צדדים
</button>
</PopoverTrigger>
<PopoverContent align="start" className="w-72 p-3 space-y-2.5 text-sm">
{appellants.length > 0 && (
<div>
<div className="text-[0.7rem] font-bold text-gold-deep uppercase tracking-wider mb-1">
עוררים
</div>
<ul className="space-y-0.5 text-ink-soft">
{appellants.map((a, i) => <li key={`a${i}`}>{a}</li>)}
</ul>
</div>
)}
{respondents.length > 0 && (
<div>
<div className="text-[0.7rem] font-bold text-gold-deep uppercase tracking-wider mb-1">
משיבים
</div>
<ul className="space-y-0.5 text-ink-soft">
{respondents.map((r, i) => <li key={`r${i}`}>{r}</li>)}
</ul>
</div>
)}
</PopoverContent>
</Popover>
)}
{data?.case_number && (
<CaseArchiveAction
caseNumber={data.case_number}