feat(case-ui): full-width tabs + parties popover + subject on title line
Chair-requested refinements to the case banner: - Tabs now span the full band width via justify-between — wide gaps with the current 6 tabs, tightening as more are added (gap-2 no-overlap floor). - Parties moved out of the always-on header line into a "צדדים" Popover, so the band is shorter and the tab content sits higher on the page. - Case subject (title) moved up onto the case-number line in a smaller font, instead of its own line below. tsc --noEmit + eslint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user