From ba92e14363928e4e8c91b857778e20b32269db32 Mon Sep 17 00:00:00 2001 From: giancarlo Date: Sun, 31 Mar 2024 15:47:20 +0800 Subject: [PATCH] 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. --- apps/web/config/billing.config.ts | 16 ++++ .../src/components/plan-picker.tsx | 75 ++++++++++++++++++- packages/billing/src/create-billing-schema.ts | 4 - 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/apps/web/config/billing.config.ts b/apps/web/config/billing.config.ts index a43e45f91..e3954ccce 100644 --- a/apps/web/config/billing.config.ts +++ b/apps/web/config/billing.config.ts @@ -28,6 +28,22 @@ export default createBillingSchema({ cost: 9.99, type: 'base', }, + { + id: 'price_1NNwYHI1i3VnbZTqI2UzaHIe6', + name: 'Per Seat', + description: 'Add-on plan', + cost: 1.99, + type: 'per-seat', + }, + { + id: 'price_1NNwYHI1i3VnbZTqI2UzaHIe7', + name: 'Metered', + description: 'Metered plan', + cost: 0.99, + type: 'metered', + unit: 'GB', + included: 10, + }, ], }, { diff --git a/packages/billing-gateway/src/components/plan-picker.tsx b/packages/billing-gateway/src/components/plan-picker.tsx index 8d1b4a250..29a57d298 100644 --- a/packages/billing-gateway/src/components/plan-picker.tsx +++ b/packages/billing-gateway/src/components/plan-picker.tsx @@ -302,7 +302,78 @@ export function PlanPicker(

-
+
+ Details + +
+ {selectedPlan?.lineItems.map((item) => { + switch (item.type) { + case 'base': + return ( +
+ {item.name} + + {formatCurrency( + selectedProduct?.currency.toLowerCase(), + item.cost, + )} + +
+ ); + + case 'per-seat': + return ( +
+ Per team member + + {formatCurrency( + selectedProduct?.currency.toLowerCase(), + item.cost, + )} + +
+ ); + + case 'metered': + return ( +
+ + Per {item.unit} + {item.included + ? ` (${item.included} included)` + : ''} + + + {formatCurrency( + selectedProduct?.currency.toLowerCase(), + item.cost, + )} + +
+ ); + } + })} +
+
+ +
+ Features + {selectedProduct?.features.map((item) => { return (
- -
diff --git a/packages/billing/src/create-billing-schema.ts b/packages/billing/src/create-billing-schema.ts index 1ac902466..748f0facf 100644 --- a/packages/billing/src/create-billing-schema.ts +++ b/packages/billing/src/create-billing-schema.ts @@ -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, {