import { useEffect, useState } from "react"; import { DownloadSimple, SealCheck, ListChecks, ClockCounterClockwise } from "@phosphor-icons/react"; import { api, ApiError, type Run } from "../lib/api"; import { ErrorNote, Note, TableSkeleton } from "./common"; export function Handoff({ runId }: { runId: string }) { const [run, setRun] = useState(null); const [error, setError] = useState(null); const [showAll, setShowAll] = useState(false); const load = () => { setError(null); setRun(null); api.getRun(runId) .then(setRun) .catch((e) => setError(e instanceof ApiError ? e.message : String(e))); }; useEffect(load, [runId]); if (error) return ; if (!run) { return
; } const covered = run.coverage.filter((c) => c.covered); const uncovered = run.coverage.filter((c) => !c.covered); const pct = run.coverage_pct; const blockers = run.severity.blocker ?? 0; return ( <>

Handoff to the merchant banker

The draft, the clause coverage and the complete decision log. PrimaryDraft does not certify and does not file. The merchant banker reviews this, exercises independent judgement, and gives the due diligence certificate required under Regulation 23.

ICDR Schedule VI coverage

{covered.length} of {run.coverage.length} clauses
{(showAll ? run.coverage : uncovered).map((c) => (
{c.clause} {c.title} {!c.covered && ( {c.reason} )} {c.covered ? "drafted" : "gap"}
))}

Decision log

{run.decisions.length} entries
{run.decisions.map((d, i) => (
{d.at.replace("T", " ").replace("+00:00", "")} {d.actor} · {d.action} {d.rule_id && · {d.rule_id}}
{d.detail}
))}
); } function Stat({ k, v }: { k: string; v: string }) { return (
{k} {v}
); } function Ring({ pct }: { pct: number }) { const r = 52; const c = 2 * Math.PI * r; return ( {pct}% ); }