feat(eoi): signed-EOI hero + send-signed-copy; fix search dropdown z-order

- EOI tab: when an EOI is already signed and none is in flight, lead with a
  SignedEoiCard (preview + download + send-to-client) instead of the big
  "Generate EOI" empty state; quiet "Generate new EOI" remains for re-issue
- history rows + hero gain a "Send to client" action — POST
  /api/v1/documents/[id]/send-signed-copy emails the deal's client the
  finalized signed PDF (sendSignedCopyToClient reuses sendSigningCompleted),
  guarded by a confirm
- topbar: header gets z-30 so the global search dropdown paints above page
  content (charts/tables were bleeding through — header + main are sibling
  normal-flow boxes, so the dropdown's own z-50 couldn't win cross-context).
  Stays below the z-50 modal tier.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 15:55:28 +02:00
parent 3b227fe9b2
commit d1f6d6a427
4 changed files with 251 additions and 7 deletions

View File

@@ -51,7 +51,13 @@ export function Topbar({ ports, user, leadingSlot }: TopbarProps) {
// Sarah Doe"). Detail pages register their parent via
// `useBreadcrumbHint` so the label is entity-aware; everything else
// is URL-derived. See src/hooks/use-smart-back.ts.
<header className="relative grid h-14 grid-cols-[auto_1fr_auto] items-center border-b border-border bg-background gap-3 px-4 shrink-0">
// `z-30` makes the header a stacking context that sits ABOVE the page
// content in <main>. Without it the search dropdown (absolute, z-50 within
// the header) still paints under main's charts/tables: header + main are
// sibling normal-flow boxes, so main paints later and wins regardless of
// the dropdown's own z. Kept below the modal/overlay tier (z-50) so
// dialogs still cover the bar.
<header className="relative z-30 grid h-14 grid-cols-[auto_1fr_auto] items-center border-b border-border bg-background gap-3 px-4 shrink-0">
{/* LEFT: optional sidebar trigger (tablet) + smart back button.
Hard-capped width so the column never extends into the
absolutely-positioned search bar's footprint. The cap is