{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "author": "Lopifi (https://lopifi.com)",
  "categories": [
    "ledger-tables",
    "finance",
    "accounting"
  ],
  "dependencies": [],
  "description": "Full detail sheet with attachments and audit trail.",
  "files": [
    {
      "content": "\"use client\";\n\nimport type * as React from \"react\";\nimport { formatDate, formatTimestamp } from \"@/lib/ledger/fiscal-period\";\nimport { Figure } from \"@/components/ledger/figure\";\nimport { Reference } from \"@/components/ledger/reference\";\nimport { Sheet } from \"@/components/ledger/sheet\";\nimport { StatusPill } from \"@/components/ledger/status-pill\";\nimport type { Transaction } from \"@/components/ledger/transaction-table\";\n\nexport type AuditEvent = {\n  at: Date;\n  actor: string;\n  role: string;\n  action: string;\n  onBehalfOf?: string;\n};\n\nexport interface TransactionDetailProps {\n  attachments?: { name: string; size: string }[];\n  auditTrail?: AuditEvent[];\n  /** The rule that fired, if any — shown, because it is editable context. */\n  categorizationRule?: string;\n  onOpenChange: (open: boolean) => void;\n  open: boolean;\n  transaction: Transaction | null;\n}\n\n/**\n * A sheet on phone, a side panel on desktop. Everything: full amounts, the\n * rule that fired, the attachments, and the full audit trail with actor,\n * role and timestamp.\n */\nexport function TransactionDetail({\n  transaction: t,\n  open,\n  onOpenChange,\n  auditTrail = [],\n  categorizationRule,\n  attachments = [],\n}: TransactionDetailProps) {\n  if (!t) return null;\n  return (\n    <Sheet\n      description={formatDate(t.date)}\n      onOpenChange={onOpenChange}\n      open={open}\n      side=\"right\"\n      title={t.description}\n    >\n      <div className=\"space-y-6\">\n        <div>\n          <Figure colorBySign size=\"lg\" value={t.amount} />\n          <div className=\"mt-2\">\n            <StatusPill entity=\"Transaction\" status={t.status} />\n          </div>\n        </div>\n\n        <dl className=\"space-y-2\">\n          <Row label=\"Account\">\n            {t.account} <span className=\"reference-numeric\">•••• {t.accountLast4}</span>\n          </Row>\n          <Row label=\"Category\">{t.category}</Row>\n          <Row label=\"Reference\">\n            <Reference truncate={false} value={t.reference} />\n          </Row>\n          {t.memo ? <Row label=\"Memo\">{t.memo}</Row> : null}\n          {t.createdBy ? <Row label=\"Created by\">{t.createdBy}</Row> : null}\n        </dl>\n\n        {categorizationRule ? (\n          <section>\n            <h3 className=\"text-label font-medium text-text-secondary\">Categorization rule</h3>\n            <p className=\"mt-1 rounded-sm bg-surface-sunken p-3 text-body\">{categorizationRule}</p>\n          </section>\n        ) : null}\n\n        {attachments.length > 0 ? (\n          <section>\n            <h3 className=\"text-label font-medium text-text-secondary\">Attachments</h3>\n            <ul className=\"mt-2 space-y-1\">\n              {attachments.map((a) => (\n                <li\n                  className=\"flex items-center justify-between rounded-sm border border-border px-3 py-2 text-body\"\n                  key={a.name}\n                >\n                  <span className=\"truncate\">{a.name}</span>\n                  <span className=\"numeric text-caption text-text-tertiary\">{a.size}</span>\n                </li>\n              ))}\n            </ul>\n          </section>\n        ) : null}\n\n        {auditTrail.length > 0 ? (\n          <section>\n            <h3 className=\"text-label font-medium text-text-secondary\">Audit trail</h3>\n            <ol className=\"mt-2 space-y-3\">\n              {auditTrail.map((e, i) => (\n                <li className=\"border-l-2 border-border pl-3\" key={i}>\n                  <p className=\"text-body\">{e.action}</p>\n                  <p className=\"text-caption text-text-secondary\">\n                    {e.actor} ({e.role}){e.onBehalfOf ? ` on behalf of ${e.onBehalfOf}` : \"\"}\n                  </p>\n                  <p className=\"numeric text-caption text-text-tertiary\">{formatTimestamp(e.at)}</p>\n                </li>\n              ))}\n            </ol>\n          </section>\n        ) : null}\n      </div>\n    </Sheet>\n  );\n}\n\nfunction Row({ label, children }: { label: string; children: React.ReactNode }) {\n  return (\n    <div className=\"flex items-baseline justify-between gap-6 border-b border-border-subtle pb-2\">\n      <dt className=\"text-body text-text-secondary\">{label}</dt>\n      <dd className=\"text-right text-body\">{children}</dd>\n    </div>\n  );\n}\n\nexport { Money } from \"@/components/ledger/money\";\n",
      "path": "components/ledger/transaction-detail.tsx",
      "target": "components/ledger/transaction-detail.tsx",
      "type": "registry:block"
    }
  ],
  "name": "transaction-detail",
  "registryDependencies": [
    "@lopifi/theme",
    "@lopifi/figure",
    "@lopifi/fiscal-period",
    "@lopifi/money",
    "@lopifi/reference",
    "@lopifi/sheet",
    "@lopifi/status-pill",
    "@lopifi/transaction-table"
  ],
  "title": "TransactionDetail",
  "type": "registry:block"
}
