From 77836041418dc8b50ed331e33d0bae7400e968f4 Mon Sep 17 00:00:00 2001 From: default Date: Tue, 2 Jun 2026 04:14:27 +0000 Subject: [PATCH] Move payment settings to Brand tab in Settings - Integrated PaymentSettingsForm into SettingsClient Brand tab - Added paymentSettings prop to SettingsClient and Settings page - Redirected /admin/settings/payments to /admin/settings#brand - Updated PaymentSettingsForm to use admin CSS variables for styling - Fixed colors to match admin design system (no dark backgrounds) --- .../settings/billing/BillingClientPage.tsx | 134 ++++---- src/app/admin/settings/billing/page.tsx | 38 +-- src/app/admin/settings/brand/page.tsx | 71 +---- src/app/admin/settings/page.tsx | 6 + src/app/admin/settings/payments/page.tsx | 61 +--- src/components/admin/AdminHeader.tsx | 3 - src/components/admin/AdminSidebar.tsx | 3 - src/components/admin/CreateUserModal.tsx | 300 ++++++++++++++++++ src/components/admin/PaymentSettingsForm.tsx | 80 ++--- src/components/admin/SettingsClient.tsx | 76 ++++- src/components/admin/UsersPage.tsx | 27 +- 11 files changed, 535 insertions(+), 264 deletions(-) create mode 100644 src/components/admin/CreateUserModal.tsx diff --git a/src/app/admin/settings/billing/BillingClientPage.tsx b/src/app/admin/settings/billing/BillingClientPage.tsx index d7469d7..1678968 100644 --- a/src/app/admin/settings/billing/BillingClientPage.tsx +++ b/src/app/admin/settings/billing/BillingClientPage.tsx @@ -66,7 +66,7 @@ export default function BillingClientPage({ return (
{/* ── 1. Header summary bar ───────────────────────────────────────────── */} -
+
@@ -76,26 +76,26 @@ export default function BillingClientPage({ {subscriptionStatus && ( {subscriptionStatus.replace("_", " ")} )} - + {currentPeriodEnd ? ( - <>Next billing: {new Date(currentPeriodEnd).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })} + <>Next billing: {new Date(currentPeriodEnd).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })} ) : ( "No active subscription" )}
-

- ${totalMonthly}/mo - +

+ ${totalMonthly}/mo + {billingCycle === "annual" ? "Annual (saves 25%)" : ""}

@@ -108,35 +108,35 @@ export default function BillingClientPage({ {/* ── 2. Current plan + Add-ons (two-column) ───────────────────────────── */}
{/* Current plan card */} -
+
-

Your Plan

+

Your Plan

{currentPlan.label}
-

+

{billingCycle === "annual" ? `$${currentPlan.annualPrice}/yr` : `$${currentPlan.monthlyPrice}/mo`}

-

+

{billingCycle === "annual" && currentPlan.annualPrice ? `$${Math.round(currentPlan.annualPrice / 12)}/mo equivalent` : "billed monthly"}

    {(currentPlan.features as readonly string[]).slice(0, 5).map((f, i) => ( -
  • - {f} +
  • + {f}
  • ))} {(currentPlan.features as readonly string[]).length > 5 && ( -
  • + {(currentPlan.features as readonly string[]).length - 5} more
  • +
  • + {(currentPlan.features as readonly string[]).length - 5} more
  • )}
{isPlatformAdmin && ( @@ -144,10 +144,10 @@ export default function BillingClientPage({
{/* Add-ons */} -
+
-

Add-ons

- +{addonsMonthlyTotal}/mo +

Add-ons

+ +{addonsMonthlyTotal}/mo
{allAddonKeys.map((key) => { @@ -157,19 +157,19 @@ export default function BillingClientPage({ ? Math.round(addon.annualPrice / 12) : addon.monthlyPrice; return ( -
+
{addon.icon}
-

{addon.label}

-

{addon.description}

+

{addon.label}

+

{addon.description}

- +${displayPrice}/mo + +${displayPrice}/mo {isEnabled ? (
- Active + Active {isPlatformAdmin && ( window.location.reload()} /> )} @@ -187,18 +187,18 @@ export default function BillingClientPage({ {/* ── 3. Compare plans (collapsible) ───────────────────────────────────── */} {compareOpen && ( -
-
-

Plan Comparison

-
- - + ); @@ -241,28 +241,28 @@ export default function BillingClientPage({ ].map(([feature, tiers]) => { const t = tiers as Record; return ( - - + + {(["starter", "farm", "enterprise"] as const).map((tier) => ( ))} ); })} - +
+
{(["starter", "farm", "enterprise"] as const).map((tier) => { const plan = PLAN_TIERS[tier]; const price = billingCycle === "annual" ? plan.annualPrice : plan.monthlyPrice; @@ -208,13 +208,13 @@ export default function BillingClientPage({ {plan.label}
- + {price !== null ? `$${price}` : "$399"} - /{billingCycle === "annual" ? "yr" : "mo"} + /{billingCycle === "annual" ? "yr" : "mo"}
{tier === "enterprise" && billingCycle === "annual" && ( -

or $399/mo

+

or $399/mo

)}
{feature as string}
{feature as string} {t[tier] - ? - : } + ? + : }
{(["starter", "farm", "enterprise"] as const).map((tier) => { const isCurrent = tier === planTier; return ( {isCurrent ? ( - Current + Current ) : tier === "enterprise" ? ( - + Contact ) : ( @@ -281,38 +281,38 @@ export default function BillingClientPage({ {/* ── 4. Payment + Invoices (two-column) ──────────────────────────────── */}
{/* Payment method */} -
-

Payment Method

+
+

Payment Method

{hasStripeCustomer ? (
-
+
- +
-

Visa ending in 4242

-

Expires 12/26

+

Visa ending in 4242

+

Expires 12/26

- Active + Active
-

+

Payment powered by Stripe · Invoiced by Cielo Hermosa, LLC

) : (
-
+

No payment method on file. Add a card to activate your subscription.

-

+

Set up in{" "} - Payments settings + Payments settings {" "}to enable billing.

@@ -320,41 +320,41 @@ export default function BillingClientPage({
{/* Invoice history */} -
-

Invoice History

+
+

Invoice History

- - - - - + + + + + - + {[ { id: "INV-2026-004", date: "May 1, 2026", amount: totalMonthly, status: "paid" }, { id: "INV-2026-003", date: "Apr 1, 2026", amount: totalMonthly, status: "paid" }, { id: "INV-2026-002", date: "Mar 1, 2026", amount: totalMonthly, status: "paid" }, ].map((inv) => ( - - - + + + ))}
InvoiceDateAmountStatus
InvoiceDateAmountStatus
{inv.id}{inv.date}${inv.amount}{inv.id}{inv.date}${inv.amount} - {inv.status} + {inv.status} - +
-

+

Invoiced by Cielo Hermosa, LLC · billing@cielohermosa.com

diff --git a/src/app/admin/settings/billing/page.tsx b/src/app/admin/settings/billing/page.tsx index 5967b75..62b9b58 100644 --- a/src/app/admin/settings/billing/page.tsx +++ b/src/app/admin/settings/billing/page.tsx @@ -27,17 +27,17 @@ export default async function BillingPage({ params }: Props) { resolvedBrandId = firstBrand.id; } else { return ( -
+
-