diff --git a/src/client/routes/settings/usage.tsx b/src/client/routes/settings/usage.tsx index 6ef790d..0c91a95 100644 --- a/src/client/routes/settings/usage.tsx +++ b/src/client/routes/settings/usage.tsx @@ -10,6 +10,7 @@ import { CommonHeader } from '@/components/CommonHeader'; import { Card, CardContent, CardHeader } from '@/components/ui/card'; import dayjs from 'dayjs'; import { formatNumber } from '@/utils/common'; +import { UsageCard } from '@/components/UsageCard'; export const Route = createFileRoute('/settings/usage')({ beforeLoad: routeAuthBeforeLoad, @@ -34,6 +35,10 @@ function PageComponent() { endAt: endDate.valueOf(), }); + const { data: limit } = trpc.billing.limit.useQuery({ + workspaceId, + }); + return ( }> @@ -49,85 +54,61 @@ function PageComponent() {
- - - {t('Website Count')} - - {serviceCountData?.website ?? 0} - + - - - {t('Monitor Count')} - - {serviceCountData?.monitor ?? 0} - + - - - {t('Survey Count')} - - {serviceCountData?.survey ?? 0} - + - - - {t('Page Count')} - - {serviceCountData?.page ?? 0} - + - - - {t('Feed Channel Count')} - - {serviceCountData?.feed ?? 0} - + - - - {t('Website Accepted Count')} - - - {formatNumber(billingUsageData?.websiteAcceptedCount ?? 0)} - - + - - - {t('Website Event Count')} - - - {formatNumber(billingUsageData?.websiteEventCount ?? 0)} - - + - - - {t('Monitor Execution Count')} - - - {formatNumber(billingUsageData?.monitorExecutionCount ?? 0)} - - + - - - {t('Survey Count')} - - - {formatNumber(billingUsageData?.surveyCount ?? 0)} - - + - - - {t('Feed Event Count')} - - - {formatNumber(billingUsageData?.feedEventCount ?? 0)} - - +
diff --git a/src/server/model/billing/limit.ts b/src/server/model/billing/limit.ts index eccc348..0136a5f 100644 --- a/src/server/model/billing/limit.ts +++ b/src/server/model/billing/limit.ts @@ -1,13 +1,16 @@ import { WorkspaceSubscriptionTier } from '@prisma/client'; +import { z } from 'zod'; -interface TierLimit { - maxWebsiteCount: number; - maxWebsiteEventCount: number; - maxMonitorExecutionCount: number; - maxSurveyCount: number; - maxFeedChannelCount: number; - maxFeedEventCount: number; -} +export const TierLimitSchema = z.object({ + maxWebsiteCount: z.number(), + maxWebsiteEventCount: z.number(), + maxMonitorExecutionCount: z.number(), + maxSurveyCount: z.number(), + maxFeedChannelCount: z.number(), + maxFeedEventCount: z.number(), +}); + +type TierLimit = z.infer; /** * Limit, Every month diff --git a/src/server/trpc/routers/billing.ts b/src/server/trpc/routers/billing.ts index 2e55da2..ee4609d 100644 --- a/src/server/trpc/routers/billing.ts +++ b/src/server/trpc/routers/billing.ts @@ -16,7 +16,11 @@ import { SubscriptionTierType, } from '../../model/billing/index.js'; import { LemonSqueezySubscriptionModelSchema } from '../../prisma/zod/lemonsqueezysubscription.js'; -import { getWorkspaceUsage } from '../../model/billing/workspace.js'; +import { + getWorkspaceSubscription, + getWorkspaceUsage, +} from '../../model/billing/workspace.js'; +import { getTierLimit, TierLimitSchema } from '../../model/billing/limit.js'; export const billingRouter = router({ usage: workspaceProcedure @@ -47,6 +51,21 @@ export const billingRouter = router({ return getWorkspaceUsage(workspaceId, startAt, endAt); }), + limit: workspaceProcedure + .meta( + buildBillingOpenapi({ + method: 'GET', + path: '/limit', + description: 'get workspace subscription limit', + }) + ) + .output(TierLimitSchema) + .query(async ({ input }) => { + const { workspaceId } = input; + const tier = await getWorkspaceSubscription(workspaceId); + + return getTierLimit(tier); + }), currentSubscription: workspaceProcedure .meta( buildBillingOpenapi({