From aaec22f271db8defd90857defaec99ba3590d32a Mon Sep 17 00:00:00 2001 From: Buildwithlevo Date: Sat, 27 Jun 2026 20:15:40 +0100 Subject: [PATCH] feat: add payment certificate, deadline suggester, source bar, and version history tabs (#95, #96, #97, #98) - PaymentCertificate (closes #95): component integrated on Released invoices with Download Certificate button, QR code, print layout - DeadlineSuggester (closes #96): component integrated below deadline input on new invoice form, uses historical data with static fallback - PaymentSourceBar (closes #97): stacked bar showing each payer contribution colour-coded with legend, integrated in payments section - VersionHistory (closes #98): add History tab to invoice detail page using VersionHistory component showing audit log diff-style timeline; also fix missing TransferOwnershipModal import --- src/app/invoice/[id]/page.tsx | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/app/invoice/[id]/page.tsx b/src/app/invoice/[id]/page.tsx index 8710f54..d6a1d56 100644 --- a/src/app/invoice/[id]/page.tsx +++ b/src/app/invoice/[id]/page.tsx @@ -50,6 +50,7 @@ import { sendWebhookIfConfigured } from "@/components/WebhookConfig"; import TxConfirmModal from "@/components/TxConfirmModal"; import CancelModal from "@/components/CancelModal"; import DuplicateModal from "@/components/DuplicateModal"; +import TransferOwnershipModal from "@/components/TransferOwnershipModal"; import CopyLinkButton from "@/components/CopyLinkButton"; import VotingPanel from "@/components/VotingPanel"; import DeadlineExtensionPanel from "@/components/DeadlineExtensionPanel"; @@ -145,6 +146,7 @@ export default function InvoiceDetailPage({ params }: Props) { const [amountLocked, setAmountLocked] = useState(false); const prevPayAmountRef = useRef(""); const [cooldownExpiresAt, setCooldownExpiresAt] = useState(null); + const [activeDetailsTab, setActiveDetailsTab] = useState<"audit" | "history" | "notes">("audit"); const prevStatusRef = useRef(null); const timelineRef = useRef(null); @@ -1014,13 +1016,35 @@ export default function InvoiceDetailPage({ params }: Props) { /> )} - {/* Audit Log */} - - - {/* Private notes — only visible to the connected wallet */} - {publicKey && ( - - )} + {/* Tabbed detail section: Audit Log / History / Notes */} +
+
+ {(["audit", "history", "notes"] as const).map((tab) => { + const labels: Record = { audit: "Audit Log", history: "History", notes: "Notes" }; + return ( + + ); + })} +
+ {activeDetailsTab === "audit" && } + {activeDetailsTab === "history" && } + {activeDetailsTab === "notes" && publicKey && ( + + )} +
{showCancelModal && invoice && (