refactor(claim-drawer): mount on shared DrillDrawerHeader shell
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { useState } from "react";
|
||||
import { Download, X } from "lucide-react";
|
||||
import { Download } from "lucide-react";
|
||||
import { Badge, type BadgeProps } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DrillDrawerHeader } from "@/components/drill/DrillDrawerHeader";
|
||||
import { api } from "@/lib/api";
|
||||
import { downloadTextFile } from "@/lib/download";
|
||||
import { fmt } from "@/lib/format";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ClaimDetail } from "@/types";
|
||||
|
||||
type ClaimDrawerHeaderProps = {
|
||||
@@ -47,12 +47,19 @@ function badgeVariantFor(state: string): BadgeProps["variant"] {
|
||||
}
|
||||
|
||||
/**
|
||||
* Header band for the claim detail drawer (SP4).
|
||||
* Header band for the claim detail drawer (SP4 → refactored SP21
|
||||
* Phase 5 Task 5.10).
|
||||
*
|
||||
* Top-left: instrument-style "Claim" eyebrow + large mono ID.
|
||||
* Top-right: state badge + total billed amount + close button. The
|
||||
* badge color encodes state so the user can read the drawer's status
|
||||
* at a glance without scrolling.
|
||||
* The shell is now the shared `DrillDrawerHeader` (same as
|
||||
* `ProviderDrawer` / `AckDrawer`) — eyebrow + title on the left,
|
||||
* close button on the right. The right-side `action` slot carries
|
||||
* the state badge, total billed amount, and the "Download 837"
|
||||
* button, all of which used to live in a custom <header> block.
|
||||
*
|
||||
* Top-left: instrument-style "Claim" eyebrow + the claim ID.
|
||||
* Top-right: state badge + total billed amount + download button.
|
||||
* The badge color encodes state so the user can read the drawer's
|
||||
* status at a glance without scrolling.
|
||||
*/
|
||||
export function ClaimDrawerHeader({
|
||||
claim,
|
||||
@@ -80,66 +87,48 @@ export function ClaimDrawerHeader({
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<header
|
||||
className={cn(
|
||||
"flex items-start justify-between gap-4 px-6 py-5",
|
||||
"border-b border-[color:var(--m-border-heavy)]/40",
|
||||
"bg-[color:var(--m-surface)]"
|
||||
)}
|
||||
data-testid="claim-drawer-header"
|
||||
>
|
||||
{/* Left: eyebrow + mono claim ID */}
|
||||
<div className="flex flex-col gap-1 min-w-0">
|
||||
<span className="eyebrow text-[color:var(--m-ink-tertiary)]">
|
||||
Claim
|
||||
</span>
|
||||
// The action slot is rendered by DrillDrawerHeader to the left of
|
||||
// the close button. Group the three action pieces (badge, amount,
|
||||
// download) in a single flex row so they read as a unit.
|
||||
const action = (
|
||||
<div className="flex items-center gap-2" data-testid="claim-header-actions">
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge
|
||||
variant={badgeVariantFor(claim.state)}
|
||||
data-testid="header-state"
|
||||
className="uppercase tracking-[0.14em]"
|
||||
>
|
||||
{claim.stateLabel}
|
||||
</Badge>
|
||||
<span
|
||||
data-testid="header-id"
|
||||
className="mono text-2xl font-semibold tracking-tight text-[color:var(--m-ink-primary)]"
|
||||
data-testid="header-amount"
|
||||
className="mono text-sm tabular-nums text-muted-foreground"
|
||||
>
|
||||
{claim.id}
|
||||
{fmt.usdPrecise(claim.billedAmount)}
|
||||
</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleDownload}
|
||||
disabled={downloading}
|
||||
aria-label={downloading ? "Downloading 837 file" : "Download 837 file"}
|
||||
title="Download 837 file"
|
||||
data-testid="header-download-837"
|
||||
>
|
||||
<Download className="h-4 w-4" strokeWidth={1.75} />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
{/* Right: state badge + total amount + download + close */}
|
||||
<div className="flex items-start gap-2">
|
||||
<div className="flex flex-col items-end gap-1">
|
||||
<Badge
|
||||
variant={badgeVariantFor(claim.state)}
|
||||
data-testid="header-state"
|
||||
className="uppercase tracking-[0.14em]"
|
||||
>
|
||||
{claim.stateLabel}
|
||||
</Badge>
|
||||
<span
|
||||
data-testid="header-amount"
|
||||
className="mono text-lg tabular-nums text-[color:var(--m-ink-primary)]"
|
||||
>
|
||||
{fmt.usdPrecise(claim.billedAmount)}
|
||||
</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={handleDownload}
|
||||
disabled={downloading}
|
||||
aria-label={downloading ? "Downloading 837 file" : "Download 837 file"}
|
||||
title="Download 837 file"
|
||||
data-testid="header-download-837"
|
||||
>
|
||||
<Download className="h-4 w-4" strokeWidth={1.75} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={onClose}
|
||||
aria-label="Close drawer"
|
||||
data-testid="header-close"
|
||||
>
|
||||
<X className="h-4 w-4" strokeWidth={1.75} />
|
||||
</Button>
|
||||
</div>
|
||||
return (
|
||||
<header data-testid="claim-drawer-header">
|
||||
<DrillDrawerHeader
|
||||
eyebrow="Claim"
|
||||
title={claim.id}
|
||||
onClose={onClose}
|
||||
action={action}
|
||||
/>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user