From e8fab2a444206e56e5499b76db5b8566a68f93d0 Mon Sep 17 00:00:00 2001 From: rrader26 Date: Wed, 1 Jul 2026 14:24:51 -0400 Subject: [PATCH] feat(plans): "Show in customer portal" toggle (self_serve) in the plan form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator-facing checkbox for the `self_serve` plan flag (ThinkfleetAI/lago-api #15). When off, the plan is hidden from the customer-portal self-serve list but stays assignable by operators — enterprise / white-label tiers. - PlanSettingsSection: SwitchField bound to `selfServe` + `selfServe` on the PlanForSettingsSection fragment - CreatePlan EditPlan fragment: fetch `selfServe` - usePlanForm: initial value `selfServe ?? true` (new plans default visible) - serialize: already forwarded via the `...otherValues` spread Requires (env-dependent, not done here): lago-api #15 merged (schema exposes selfServe) + `graphql:codegen` to regenerate src/generated/graphql.tsx — the form won't type-check until then. Labels are literal strings (add i18n keys if lint requires). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/components/plans/PlanSettingsSection.tsx | 10 ++++++++++ src/hooks/plans/usePlanForm.tsx | 3 +++ src/pages/CreatePlan.tsx | 1 + 3 files changed, 14 insertions(+) diff --git a/src/components/plans/PlanSettingsSection.tsx b/src/components/plans/PlanSettingsSection.tsx index ff698cd824..b77237808d 100644 --- a/src/components/plans/PlanSettingsSection.tsx +++ b/src/components/plans/PlanSettingsSection.tsx @@ -33,6 +33,7 @@ gql` description interval name + selfServe taxes { ...TaxForPlanSettingsSection } @@ -175,6 +176,15 @@ export const PlanSettingsSection = ({ )} + + {(field) => ( + + )} + + {canApplyChargesMonthly && ( <> {hasAnyFixedCharge && ( diff --git a/src/hooks/plans/usePlanForm.tsx b/src/hooks/plans/usePlanForm.tsx index 42cf6b604f..e6070a14ea 100644 --- a/src/hooks/plans/usePlanForm.tsx +++ b/src/hooks/plans/usePlanForm.tsx @@ -104,6 +104,9 @@ const buildDefaultValues = ( taxes: plan?.taxes || [], invoiceDisplayName: plan?.invoiceDisplayName || undefined, payInAdvance: plan?.payInAdvance || false, + // Default new plans to visible in the customer portal; false hides them + // from self-serve while keeping them operator-assignable. + selfServe: plan?.selfServe ?? true, amountCents: isNaN(plan?.amountCents) ? '0' : String(deserializeAmount(plan?.amountCents || 0, initialCurrency)), diff --git a/src/pages/CreatePlan.tsx b/src/pages/CreatePlan.tsx index 2ea9e60409..2a6aaf1f5d 100644 --- a/src/pages/CreatePlan.tsx +++ b/src/pages/CreatePlan.tsx @@ -81,6 +81,7 @@ gql` description interval payInAdvance + selfServe invoiceDisplayName amountCents amountCurrency