diff --git a/apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts b/apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts index ea8f2722b..77fb20ae7 100644 --- a/apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts +++ b/apps/web/app/home/(user)/billing/_lib/server/personal-account-billing-page.loader.ts @@ -2,26 +2,9 @@ import 'server-only'; import { cache } from 'react'; -import { z } from 'zod'; - import { createAccountsApi } from '@kit/accounts/api'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; -/** - * The variable BILLING_MODE represents the billing mode for a service. It can - * have either the value 'subscription' or 'one-time'. If not provided, the default - * value is 'subscription'. The value can be overridden by the environment variable - * BILLING_MODE. - * - * If the value is 'subscription', we fetch the subscription data for the user. - * If the value is 'one-time', we fetch the orders data for the user. - * if none of these suits your needs, please override the below function. - */ -const BILLING_MODE = z - .enum(['subscription', 'one-time']) - .default('subscription') - .parse(process.env.BILLING_MODE); - /** * Load the personal account billing page data for the given user. * @param userId @@ -36,12 +19,9 @@ function personalAccountBillingPageDataLoader(userId: string) { const client = getSupabaseServerClient(); const api = createAccountsApi(client); - const data = - BILLING_MODE === 'subscription' - ? api.getSubscription(userId) - : api.getOrder(userId); - + const subscription = api.getSubscription(userId); + const order = api.getOrder(userId); const customerId = api.getCustomerId(userId); - return Promise.all([data, customerId]); + return Promise.all([subscription, order, customerId]); } diff --git a/apps/web/app/home/(user)/billing/page.tsx b/apps/web/app/home/(user)/billing/page.tsx index b2b3e5246..3d218338e 100644 --- a/apps/web/app/home/(user)/billing/page.tsx +++ b/apps/web/app/home/(user)/billing/page.tsx @@ -35,24 +35,21 @@ export const generateMetadata = async () => { async function PersonalAccountBillingPage() { const user = await requireUserInServerComponent(); - const [data, customerId] = await loadPersonalAccountBillingPageData(user.id); + const [subscription, order, customerId] = + await loadPersonalAccountBillingPageData(user.id); - let productPlan: { - product: ProductSchema; - plan: z.infer; - } | null = null; + const subscriptionProductPlan = subscription + ? await getProductPlan( + subscription.items[0]?.variant_id, + subscription.currency, + ) + : undefined; - if (data) { - const firstLineItem = data.items[0]; + const orderProductPlan = order + ? await getProductPlan(order.items[0]?.variant_id, order.currency) + : undefined; - if (firstLineItem) { - productPlan = await resolveProductPlan( - billingConfig, - firstLineItem.variant_id, - data.currency, - ); - } - } + const hasBillingData = subscription || order; return ( <> @@ -63,7 +60,7 @@ async function PersonalAccountBillingPage() {
- + @@ -71,32 +68,36 @@ async function PersonalAccountBillingPage() { - - {(data) => ( -
- {'active' in data ? ( - - ) : ( - - )} + +
+ + {(subscription) => { + return ( + + ); + }} + - - - + + {(order) => { + return ( + + ); + }} + +
+
- - - -
- )} + +
@@ -113,3 +114,20 @@ function CustomerBillingPortalForm() { ); } + +async function getProductPlan( + variantId: string | undefined, + currency: string, +): Promise< + | { + product: ProductSchema; + plan: z.infer; + } + | undefined +> { + if (!variantId) { + return undefined; + } + + return resolveProductPlan(billingConfig, variantId, currency); +} diff --git a/apps/web/app/home/[account]/_components/dashboard-demo-charts.tsx b/apps/web/app/home/[account]/_components/dashboard-demo-charts.tsx index 436853b8e..55301ce98 100644 --- a/apps/web/app/home/[account]/_components/dashboard-demo-charts.tsx +++ b/apps/web/app/home/[account]/_components/dashboard-demo-charts.tsx @@ -815,7 +815,7 @@ export function PageViewsChart() { desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0), mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0), }), - [], + [chartData], ); return ( diff --git a/apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts b/apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts index 73f400b75..890b1b643 100644 --- a/apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts +++ b/apps/web/app/home/[account]/_lib/server/team-account-billing-page.loader.ts @@ -2,26 +2,9 @@ import 'server-only'; import { cache } from 'react'; -import { z } from 'zod'; - import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { createTeamAccountsApi } from '@kit/team-accounts/api'; -/** - * The variable BILLING_MODE represents the billing mode for a service. It can - * have either the value 'subscription' or 'one-time'. If not provided, the default - * value is 'subscription'. The value can be overridden by the environment variable - * BILLING_MODE. - * - * If the value is 'subscription', we fetch the subscription data for the user. - * If the value is 'one-time', we fetch the orders data for the user. - * if none of these suits your needs, please override the below function. - */ -const BILLING_MODE = z - .enum(['subscription', 'one-time']) - .default('subscription') - .parse(process.env.BILLING_MODE); - /** * @name loadTeamAccountBillingPage * @description Load the team account billing page data for the given account. @@ -32,12 +15,9 @@ function teamAccountBillingPageLoader(accountId: string) { const client = getSupabaseServerClient(); const api = createTeamAccountsApi(client); - const data = - BILLING_MODE === 'subscription' - ? api.getSubscription(accountId) - : api.getOrder(accountId); - + const subscription = api.getSubscription(accountId); + const order = api.getOrder(accountId); const customerId = api.getCustomerId(accountId); - return Promise.all([data, customerId]); + return Promise.all([subscription, order, customerId]); } diff --git a/apps/web/app/home/[account]/billing/page.tsx b/apps/web/app/home/[account]/billing/page.tsx index d18a5e5ef..bf949b3c1 100644 --- a/apps/web/app/home/[account]/billing/page.tsx +++ b/apps/web/app/home/[account]/billing/page.tsx @@ -44,24 +44,21 @@ async function TeamAccountBillingPage({ params }: TeamAccountBillingPageProps) { const workspace = await loadTeamWorkspace(account); const accountId = workspace.account.id; - const [data, customerId] = await loadTeamAccountBillingPage(accountId); + const [subscription, order, customerId] = + await loadTeamAccountBillingPage(accountId); - let productPlan: { - product: ProductSchema; - plan: z.infer; - } | null = null; + const subscriptionProductPlan = subscription + ? await getProductPlan( + subscription.items[0]?.variant_id, + subscription.currency, + ) + : undefined; - if (data) { - const firstLineItem = data.items[0]; + const orderProductPlan = order + ? await getProductPlan(order.items[0]?.variant_id, order.currency) + : undefined; - if (firstLineItem) { - productPlan = await resolveProductPlan( - billingConfig, - firstLineItem.variant_id, - data.currency, - ); - } - } + const hasBillingData = subscription || order; const canManageBilling = workspace.account.permissions.includes('billing.manage'); @@ -102,33 +99,32 @@ async function TeamAccountBillingPage({ params }: TeamAccountBillingPageProps) {
- - -
- } - > - {(data) => { - if ('active' in data) { - return ( - - ); - } + + + + + {(subscription) => { + return ( + + ); + }} + + + + {(order) => { return ( ); }} @@ -158,3 +154,20 @@ function CannotManageBillingAlert() { ); } + +async function getProductPlan( + variantId: string | undefined, + currency: string, +): Promise< + | { + product: ProductSchema; + plan: z.infer; + } + | undefined +> { + if (!variantId) { + return undefined; + } + + return resolveProductPlan(billingConfig, variantId, currency); +} diff --git a/package.json b/package.json index 58d75197a..e267dd59d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next-supabase-saas-kit-turbo", - "version": "2.11.0", + "version": "2.12.0", "private": true, "sideEffects": false, "engines": {