From fa359443f8fe747efa270334acbf306aa873965b Mon Sep 17 00:00:00 2001
From: xmrcheckout
Date: Fri, 30 Jan 2026 16:13:56 +0000
Subject: [PATCH] ui: add public tour with simulated data
---
ui/app/(app)/dashboard/actions.ts | 51 +++
ui/app/(marketing)/layout.tsx | 1 +
ui/app/(marketing)/page.tsx | 14 +
ui/app/(marketing)/tour/page.tsx | 418 ++++++++++++++++++++++++
ui/components/invoice-panel.tsx | 183 +++++++++--
ui/components/webhook-history-panel.tsx | 13 +-
ui/components/webhook-section.tsx | 20 +-
7 files changed, 661 insertions(+), 39 deletions(-)
create mode 100644 ui/app/(marketing)/tour/page.tsx
diff --git a/ui/app/(app)/dashboard/actions.ts b/ui/app/(app)/dashboard/actions.ts
index d7d65b8..c5462ef 100644
--- a/ui/app/(app)/dashboard/actions.ts
+++ b/ui/app/(app)/dashboard/actions.ts
@@ -62,6 +62,57 @@ export type WebhookRedeliverState = {
success: string | null;
};
+const tourNoopMessage = "Tour mode only: no changes are saved.";
+
+export async function createInvoiceTourAction(
+ _prevState: InvoiceState,
+ _formData: FormData
+): Promise {
+ return {
+ error: tourNoopMessage,
+ invoiceId: null,
+ address: null,
+ amount: null,
+ recipientName: null,
+ description: null,
+ subaddressIndex: null,
+ warnings: null,
+ };
+}
+
+export async function archiveInvoiceTourAction(
+ _prevState: ArchiveInvoiceState,
+ formData: FormData
+): Promise {
+ const archivedId = String(formData.get("invoice_id") ?? "").trim() || null;
+ return {
+ error: null,
+ success: tourNoopMessage,
+ archivedId,
+ };
+}
+
+export async function createWebhookTourAction(
+ _prevState: WebhookFormState,
+ _formData: FormData
+): Promise {
+ return { error: null, success: tourNoopMessage };
+}
+
+export async function deleteWebhookTourAction(
+ _prevState: WebhookFormState,
+ _formData: FormData
+): Promise {
+ return { error: null, success: tourNoopMessage };
+}
+
+export async function redeliverWebhookDeliveryTourAction(
+ _prevState: WebhookRedeliverState,
+ _formData: FormData
+): Promise {
+ return { error: null, success: tourNoopMessage };
+}
+
const webhookEventKeys = [
{ event: "invoice.created", key: "invoice_created" },
{ event: "invoice.payment_detected", key: "invoice_payment_detected" },
diff --git a/ui/app/(marketing)/layout.tsx b/ui/app/(marketing)/layout.tsx
index 2f7ab4b..dbf2a84 100644
--- a/ui/app/(marketing)/layout.tsx
+++ b/ui/app/(marketing)/layout.tsx
@@ -43,6 +43,7 @@ export default async function MarketingLayout({
Create a new invoice
+ {mode === "tour" ? (
+
+ Tour mode: submissions are simulated. No invoice is created.
+
+ ) : null}