From 078208c0fc5694a5e348c3c8e485580ee5eb5957 Mon Sep 17 00:00:00 2001 From: isra el Date: Sat, 15 Feb 2025 15:48:05 +0300 Subject: [PATCH] feat: show current plan in dashboard --- api/src/billing/billing.controller.ts | 7 ++ api/src/billing/billing.service.ts | 21 +++- .../(components)/account-settings.tsx | 102 ++++++++++++++++++ web/config/api.ts | 5 + 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/api/src/billing/billing.controller.ts b/api/src/billing/billing.controller.ts index 289c918..cb5a0a8 100644 --- a/api/src/billing/billing.controller.ts +++ b/api/src/billing/billing.controller.ts @@ -19,6 +19,13 @@ export class BillingController { return this.billingService.getPlans() } + + @Get('current-plan') + @UseGuards(AuthGuard) + async getCurrentPlan(@Request() req: any) { + return this.billingService.getCurrentPlan(req.user) + } + @Post('checkout') @UseGuards(AuthGuard) async getCheckoutUrl( diff --git a/api/src/billing/billing.service.ts b/api/src/billing/billing.service.ts index 19807e3..e81836b 100644 --- a/api/src/billing/billing.service.ts +++ b/api/src/billing/billing.service.ts @@ -70,6 +70,25 @@ export class BillingService { }) } + async getCurrentPlan(user: any) { + const subscription = await this.subscriptionModel.findOne({ + user: user._id, + isActive: true, + }) + + + + let plan = null + + if (!subscription) { + plan = await this.planModel.findOne({ name: 'free' }) + } else { + plan = await this.planModel.findById(subscription.plan) + } + + return plan + } + async getCheckoutUrl({ user, payload, @@ -105,10 +124,8 @@ export class BillingService { customerEmail: user.email, customerName: user.name, customerIpAddress: req.ip, - customerId: user._id?.toString(), metadata: { userId: user._id?.toString(), - customerId: user._id?.toString(), }, } const discount = await this.polarApi.discounts.get({ diff --git a/web/app/(app)/dashboard/(components)/account-settings.tsx b/web/app/(app)/dashboard/(components)/account-settings.tsx index 4c832bb..686717d 100644 --- a/web/app/(app)/dashboard/(components)/account-settings.tsx +++ b/web/app/(app)/dashboard/(components)/account-settings.tsx @@ -27,6 +27,7 @@ import { UserCircle, Loader2, Check, + Calendar, } from 'lucide-react' import { useForm } from 'react-hook-form' import { z } from 'zod' @@ -195,6 +196,106 @@ export default function AccountSettings() { }, }) + const CurrentPlan = () => { + + const { + data: currentPlan, + isLoading: isLoadingPlan, + error: planError, + } = useQuery({ + queryKey: ['currentPlan'], + queryFn: () => + httpBrowserClient + .get(ApiEndpoints.billing.currentPlan()) + .then((res) => res.data), + }) + + + if (isLoadingPlan) return
+ if (planError) + return ( +

+ Failed to load plan information +

+ ) + + return ( +
+
+
+

+ {currentPlan?.name} +

+

+ Current subscription +

+
+
+ + Active +
+
+ +
+
+ +
+

Next Payment

+

+ {currentPlan?.nextPaymentDate ?? '-:-'} +

+
+
+ +
+ +
+

Quota

+

+ {currentPlan?.quota} +

+
+
+ +
+
+
+

Daily

+

{currentPlan?.dailyLimit}

+
+
+

Monthly

+

{currentPlan?.monthlyLimit}

+
+
+

Bulk

+

{currentPlan?.bulkSendLimit}

+
+
+
+
+ +
+ {currentPlan?.name?.toLowerCase() === 'free' ? ( + + Upgrade to Pro → + + ) : ( + + Manage Subscription → + + )} +
+
+ ) + } + if (isLoadingUser) return (
@@ -204,6 +305,7 @@ export default function AccountSettings() { return (
+
diff --git a/web/config/api.ts b/web/config/api.ts index 4a5c9ba..6952c80 100644 --- a/web/config/api.ts +++ b/web/config/api.ts @@ -31,4 +31,9 @@ export const ApiEndpoints = { updateWebhook: (id: string) => `/webhooks/${id}`, getStats: () => '/gateway/stats', }, + billing: { + currentPlan: () => '/billing/current-plan', + checkout: () => '/billing/checkout', + plans: () => '/billing/plans', + }, }