Refactor billing components to improve price display and modularity (#132)

* Refactor billing components to improve price display and modularity
- Created new `PlanCostDisplay` component to centralize price formatting logic
- Simplified price rendering in plan picker and pricing table
- Removed redundant price calculation code
- Improved handling of metered and tiered pricing display
This commit is contained in:
Giancarlo Buomprisco
2025-02-03 12:06:40 +07:00
committed by GitHub
parent 001903ddac
commit f46286b503
4 changed files with 117 additions and 119 deletions

View File

@@ -15,7 +15,6 @@ import {
getPrimaryLineItem,
getProductPlanPair,
} from '@kit/billing';
import { formatCurrency } from '@kit/shared/utils';
import { Badge } from '@kit/ui/badge';
import { Button } from '@kit/ui/button';
import {
@@ -38,6 +37,7 @@ import { Trans } from '@kit/ui/trans';
import { cn } from '@kit/ui/utils';
import { LineItemDetails } from './line-item-details';
import { PlanCostDisplay } from './plan-cost-display';
export function PlanPicker(
props: React.PropsWithChildren<{
@@ -108,8 +108,6 @@ export function PlanPicker(
const isRecurringPlan =
selectedPlan?.paymentType === 'recurring' || !selectedPlan;
const locale = useTranslation().i18n.language;
return (
<Form {...form}>
<div
@@ -238,30 +236,6 @@ export function PlanPicker(
throw new Error(`Base line item was not found`);
}
const shouldDisplayTier =
primaryLineItem.type === 'metered' &&
Array.isArray(primaryLineItem.tiers) &&
primaryLineItem.tiers.length > 0;
const isMultiTier =
Array.isArray(primaryLineItem.tiers) &&
primaryLineItem.tiers.length > 1;
const lowestTier = primaryLineItem.tiers?.reduce(
(acc, curr) => {
if (acc && acc.cost < curr.cost) {
return acc;
}
return curr;
},
primaryLineItem.tiers[0],
);
const tierTranslationKey = isMultiTier
? 'billing:startingAtPriceUnit'
: 'billing:priceUnit';
return (
<RadioGroupItemLabel
selected={selected}
@@ -341,34 +315,14 @@ export function PlanPicker(
}
>
<div>
<If
condition={shouldDisplayTier}
fallback={
<Price key={plan.id}>
<span>
{formatCurrency({
currencyCode:
product.currency.toLowerCase(),
value: primaryLineItem.cost,
locale,
})}
</span>
</Price>
}
>
<Trans
i18nKey={tierTranslationKey}
values={{
price: formatCurrency({
currencyCode:
product.currency.toLowerCase(),
value: lowestTier?.cost ?? 0,
locale,
}),
unit: primaryLineItem.unit,
}}
<Price key={plan.id}>
<PlanCostDisplay
primaryLineItem={primaryLineItem}
currencyCode={product.currency}
interval={selectedInterval}
alwaysDisplayMonthlyPrice={true}
/>
</If>
</Price>
<div>
<span className={'text-muted-foreground'}>