diff --git a/docs/release-control/v6/internal/subsystems/cloud-paid.md b/docs/release-control/v6/internal/subsystems/cloud-paid.md index 807b1c0324..1f8d96a541 100644 --- a/docs/release-control/v6/internal/subsystems/cloud-paid.md +++ b/docs/release-control/v6/internal/subsystems/cloud-paid.md @@ -504,10 +504,10 @@ while `frontend-modern/src/pages/CloudPricing.tsx`, and the self-hosted billing settings surfaces must consume those shared owners instead of redefining retail plan facts or counted-unit policy locally. That shared ownership also includes display-ready price semantics. Monthly -headline price, founding-rate override, compare-at strike-through copy, and -annual summary text must come from the shared plan-definition owners rather -than page-local string parsing or hardcoded retail amounts inside hosted -pricing/signup screens. +headline price, founding-rate override, compare-at strike-through copy, +campaign badge copy, and annual summary text must come from the shared +plan-definition owners rather than page-local string parsing or hardcoded +retail amounts inside hosted pricing/signup screens. That same counted-unit boundary also owns the disclosure rule for retail copy: default billing and pricing surfaces should use concise monitored-system copy, while the full counted-unit definition appears only behind explicit disclosure diff --git a/frontend-modern/src/pages/CloudPricing.tsx b/frontend-modern/src/pages/CloudPricing.tsx index 1e18cc879a..d6b8cee665 100644 --- a/frontend-modern/src/pages/CloudPricing.tsx +++ b/frontend-modern/src/pages/CloudPricing.tsx @@ -32,10 +32,10 @@ function CloudTierCard(props: { tier: CloudPlanDefinition }) { : 'relative' } > - +
- Founding rate + {price.campaignBadge}
diff --git a/frontend-modern/src/pages/__tests__/CloudPricing.test.tsx b/frontend-modern/src/pages/__tests__/CloudPricing.test.tsx index 9e9493ccc7..6213bd30e2 100644 --- a/frontend-modern/src/pages/__tests__/CloudPricing.test.tsx +++ b/frontend-modern/src/pages/__tests__/CloudPricing.test.tsx @@ -24,6 +24,7 @@ describe('CloudPricing', () => { 'href', '/cloud/signup?tier=starter', ); + expect(screen.getByText('Founding rate')).toBeInTheDocument(); expect(screen.getByText('$19')).toBeInTheDocument(); expect(screen.getByText('$29/month')).toBeInTheDocument(); expect(screen.getByRole('link', { name: 'Choose Power' })).toHaveAttribute( diff --git a/frontend-modern/src/utils/__tests__/cloudPlans.test.ts b/frontend-modern/src/utils/__tests__/cloudPlans.test.ts index d9f0256f43..840ba08343 100644 --- a/frontend-modern/src/utils/__tests__/cloudPlans.test.ts +++ b/frontend-modern/src/utils/__tests__/cloudPlans.test.ts @@ -12,6 +12,7 @@ describe('cloudPlans', () => { cadence: '/month', annualSummary: 'or $249/year (save 29%)', compareAtMonthlyPrice: '$29', + campaignBadge: 'Founding rate', }); }); @@ -21,6 +22,7 @@ describe('cloudPlans', () => { cadence: '/month', annualSummary: 'or $449/year (save 24%)', compareAtMonthlyPrice: undefined, + campaignBadge: undefined, }); }); }); diff --git a/frontend-modern/src/utils/cloudPlans.ts b/frontend-modern/src/utils/cloudPlans.ts index c2bf34dafd..e9a8dd22a1 100644 --- a/frontend-modern/src/utils/cloudPlans.ts +++ b/frontend-modern/src/utils/cloudPlans.ts @@ -9,6 +9,7 @@ export interface CloudPlanDefinition { monitoredSystems: number; support: 'Community' | 'Priority'; foundingMonthlyPrice?: string; + campaignBadge?: string; highlighted?: boolean; } @@ -17,6 +18,7 @@ export interface CloudPlanPricePresentation { cadence: '/month'; annualSummary: string; compareAtMonthlyPrice?: string; + campaignBadge?: string; } export const DEFAULT_CLOUD_TIER: CloudTierKey = 'starter'; @@ -31,6 +33,7 @@ export const CLOUD_PLAN_DEFINITIONS: readonly CloudPlanDefinition[] = [ monitoredSystems: 10, support: 'Community', foundingMonthlyPrice: '$19', + campaignBadge: 'Founding rate', highlighted: true, }, { @@ -93,5 +96,6 @@ export function getCloudPlanPricePresentation( cadence: '/month', annualSummary: plan.annualSummary, compareAtMonthlyPrice: plan.foundingMonthlyPrice ? plan.monthlyPrice : undefined, + campaignBadge: plan.campaignBadge, }; }