diff --git a/packages/web/app/src/components/organization/billing/PlanSummary.tsx b/packages/web/app/src/components/organization/billing/PlanSummary.tsx index 68d11dd2adb..839520db9c2 100644 --- a/packages/web/app/src/components/organization/billing/PlanSummary.tsx +++ b/packages/web/app/src/components/organization/billing/PlanSummary.tsx @@ -2,7 +2,7 @@ import { ReactElement, ReactNode } from 'react'; import { Stat, Table, TBody, Td, TFoot, Th, THead, Tr } from '@/components/v2'; import { FragmentType, graphql, useFragment } from '@/gql'; import { BillingPlanType } from '@/gql/graphql'; -import { CurrencyFormatter } from './helpers'; +import { CurrencyFormatter, formatOperations } from './helpers'; const PriceEstimationTable_PlanFragment = graphql(` fragment PriceEstimationTable_PlanFragment on BillingPlan { @@ -48,7 +48,7 @@ function PriceEstimationTable(props: { Included Operations (free) - {includedOperationsInMillions}M + {formatOperations(includedOperationsInMillions)} {CurrencyFormatter.format(0)} {CurrencyFormatter.format(0)} @@ -56,7 +56,7 @@ function PriceEstimationTable(props: { {plan.planType === BillingPlanType.Pro && ( Operations - {additionalOperations}M + {formatOperations(additionalOperations)} {CurrencyFormatter.format(plan.pricePerOperationsUnit ?? 0)} {CurrencyFormatter.format(operationsTotal)} @@ -114,7 +114,7 @@ export function PlanSummary({ Operations Limit up to - {operationsRateLimit}M + {formatOperations(operationsRateLimit)} per month diff --git a/packages/web/app/src/components/organization/billing/helpers.ts b/packages/web/app/src/components/organization/billing/helpers.ts index ac2981a70f2..ec83a205a15 100644 --- a/packages/web/app/src/components/organization/billing/helpers.ts +++ b/packages/web/app/src/components/organization/billing/helpers.ts @@ -9,3 +9,12 @@ export const DateFormatter = Intl.DateTimeFormat('en', { month: 'short', day: 'numeric', }); + +/** Format millions of operations as "500M" or "2.5B" */ +export function formatOperations(millions: number): string { + if (millions >= 1000) { + const b = parseFloat((millions / 1000).toFixed(3)); + return `${b}B`; + } + return `${millions}M`; +} diff --git a/packages/web/app/src/pages/organization-subscription-manage.tsx b/packages/web/app/src/pages/organization-subscription-manage.tsx index d3f595c5d67..e7342a195d5 100644 --- a/packages/web/app/src/pages/organization-subscription-manage.tsx +++ b/packages/web/app/src/pages/organization-subscription-manage.tsx @@ -379,16 +379,18 @@ function Inner(props: {
1M - 100M - 200M - 300M + 1B + 2B + 3B + 4B + 5B
diff --git a/packages/web/docs/src/components/pricing/index.tsx b/packages/web/docs/src/components/pricing/index.tsx index a189aae220f..1ac25c2c9f1 100644 --- a/packages/web/docs/src/components/pricing/index.tsx +++ b/packages/web/docs/src/components/pricing/index.tsx @@ -86,7 +86,7 @@ export function Pricing({ className }: { className?: string }): ReactElement { { - const newPlan = value === 1 ? 'Hobby' : value < 280 ? 'Pro' : 'Enterprise'; + const newPlan = value === 1 ? 'Hobby' : value < 4800 ? 'Pro' : 'Enterprise'; if (newPlan !== highlightedPlan) { setHighlightedPlan(newPlan); if (!scrollviewRef.current) return; diff --git a/packages/web/docs/src/components/pricing/pricing-slider.tsx b/packages/web/docs/src/components/pricing/pricing-slider.tsx index b0df47aafab..93792deee2b 100644 --- a/packages/web/docs/src/components/pricing/pricing-slider.tsx +++ b/packages/web/docs/src/components/pricing/pricing-slider.tsx @@ -4,6 +4,16 @@ import { CallToAction, cn } from '@theguild/components'; import { BookIcon } from '../book-icon'; import { Slider } from '../slider'; +function formatOps(millions: number): { label: string; chars: number } { + if (millions >= 1000) { + const b = parseFloat((millions / 1000).toFixed(3)); + const label = `${b} B`; + return { label, chars: label.length - 1 }; + } + const label = `${millions} M`; + return { label, chars: label.length - 1 }; +} + export function PricingSlider({ className, onChange, @@ -13,29 +23,30 @@ export function PricingSlider({ onChange: (value: number) => void; }) { const min = 1; - const max = 300; + const max = 5000; const [popoverOpen, setPopoverOpen] = useState(false); + const [opsLabel, setOpsLabel] = useState(() => formatOps(min).label); const rootRef = useRef(null); return (
-
-
- M +
+
+ {opsLabel}
How many @@ -60,11 +71,14 @@ export function PricingSlider({ counter="after:content-['$'_counter(price)_'_/_month'] after:[counter-set:price_calc(var(--price))]" onChange={event => { const value = event.currentTarget.valueAsNumber; + const display = formatOps(value); rootRef.current!.style.setProperty('--ops', `${value}`); + rootRef.current!.style.setProperty('--ops-chars', `${display.chars}`); + setOpsLabel(display.label); onChange(value); }} /> - {max}M + 5B