Add detailed plan info and additional subscription types

Implemented detailed pricing information for various subscription types in the plan-picker component. Two additional subscription types, 'per-seat' and 'metered', have been added to the billing configuration, providing more flexibility for customers to choose different billing methods that suit their needs. The billing schema has also been refined to allow plans without a 'base' line item.
This commit is contained in:
giancarlo
2024-03-31 15:47:20 +08:00
parent 57c8f89804
commit ba92e14363
3 changed files with 88 additions and 7 deletions

View File

@@ -302,7 +302,78 @@ export function PlanPicker(
</p>
</div>
<div className={'flex flex-col'}>
<div className={'flex flex-col space-y-1'}>
<span className={'font-semibold'}>Details</span>
<div className={'flex flex-col divide-y'}>
{selectedPlan?.lineItems.map((item) => {
switch (item.type) {
case 'base':
return (
<div
key={item.id}
className={
'flex items-center justify-between py-1.5 text-sm'
}
>
<span>{item.name}</span>
<span className={'font-semibold'}>
{formatCurrency(
selectedProduct?.currency.toLowerCase(),
item.cost,
)}
</span>
</div>
);
case 'per-seat':
return (
<div
key={item.id}
className={
'flex items-center justify-between py-1.5 text-sm'
}
>
<span>Per team member</span>
<span className={'font-semibold'}>
{formatCurrency(
selectedProduct?.currency.toLowerCase(),
item.cost,
)}
</span>
</div>
);
case 'metered':
return (
<div
key={item.id}
className={
'flex items-center justify-between py-1.5 text-sm'
}
>
<span>
Per {item.unit}
{item.included
? ` (${item.included} included)`
: ''}
</span>
<span className={'font-semibold'}>
{formatCurrency(
selectedProduct?.currency.toLowerCase(),
item.cost,
)}
</span>
</div>
);
}
})}
</div>
</div>
<div className={'flex flex-col space-y-2'}>
<span className={'font-semibold'}>Features</span>
{selectedProduct?.features.map((item) => {
return (
<div
@@ -316,8 +387,6 @@ export function PlanPicker(
);
})}
</div>
<Separator />
</div>
</If>
</div>

View File

@@ -40,10 +40,6 @@ export const PlanSchema = z
message: 'Plans must have at least one line item',
path: ['lineItems'],
})
.refine((data) => data.lineItems.some((item) => item.type === 'base'), {
message: 'Plans must include a base line item',
path: ['lineItems'],
})
.refine(
(data) => data.paymentType !== 'one-time' || data.interval === undefined,
{