refactor: add usage limit and update card style
This commit is contained in:
parent
71f75c27dd
commit
34f9fe6957
@ -10,6 +10,7 @@ import { CommonHeader } from '@/components/CommonHeader';
|
|||||||
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { formatNumber } from '@/utils/common';
|
import { formatNumber } from '@/utils/common';
|
||||||
|
import { UsageCard } from '@/components/UsageCard';
|
||||||
|
|
||||||
export const Route = createFileRoute('/settings/usage')({
|
export const Route = createFileRoute('/settings/usage')({
|
||||||
beforeLoad: routeAuthBeforeLoad,
|
beforeLoad: routeAuthBeforeLoad,
|
||||||
@ -34,6 +35,10 @@ function PageComponent() {
|
|||||||
endAt: endDate.valueOf(),
|
endAt: endDate.valueOf(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { data: limit } = trpc.billing.limit.useQuery({
|
||||||
|
workspaceId,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CommonWrapper header={<CommonHeader title={t('Usage')} />}>
|
<CommonWrapper header={<CommonHeader title={t('Usage')} />}>
|
||||||
<ScrollArea className="h-full overflow-hidden p-4">
|
<ScrollArea className="h-full overflow-hidden p-4">
|
||||||
@ -49,85 +54,61 @@ function PageComponent() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
|
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Website Count')}
|
||||||
{t('Website Count')}
|
current={serviceCountData?.website ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxWebsiteCount}
|
||||||
<CardContent>{serviceCountData?.website ?? 0}</CardContent>
|
/>
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Monitor Count')}
|
||||||
{t('Monitor Count')}
|
current={serviceCountData?.monitor ?? 0}
|
||||||
</CardHeader>
|
/>
|
||||||
<CardContent>{serviceCountData?.monitor ?? 0}</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Survey Count')}
|
||||||
{t('Survey Count')}
|
current={serviceCountData?.survey ?? 0}
|
||||||
</CardHeader>
|
/>
|
||||||
<CardContent>{serviceCountData?.survey ?? 0}</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Page Count')}
|
||||||
{t('Page Count')}
|
current={serviceCountData?.page ?? 0}
|
||||||
</CardHeader>
|
/>
|
||||||
<CardContent>{serviceCountData?.page ?? 0}</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Feed Channel Count')}
|
||||||
{t('Feed Channel Count')}
|
current={serviceCountData?.feed ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxFeedChannelCount}
|
||||||
<CardContent>{serviceCountData?.feed ?? 0}</CardContent>
|
/>
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Website Accepted Count')}
|
||||||
{t('Website Accepted Count')}
|
current={billingUsageData?.websiteAcceptedCount ?? 0}
|
||||||
</CardHeader>
|
/>
|
||||||
<CardContent>
|
|
||||||
{formatNumber(billingUsageData?.websiteAcceptedCount ?? 0)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Website Event Count')}
|
||||||
{t('Website Event Count')}
|
current={billingUsageData?.websiteEventCount ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxWebsiteEventCount}
|
||||||
<CardContent>
|
/>
|
||||||
{formatNumber(billingUsageData?.websiteEventCount ?? 0)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Monitor Execution Count')}
|
||||||
{t('Monitor Execution Count')}
|
current={billingUsageData?.monitorExecutionCount ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxMonitorExecutionCount}
|
||||||
<CardContent>
|
/>
|
||||||
{formatNumber(billingUsageData?.monitorExecutionCount ?? 0)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Survey Count')}
|
||||||
{t('Survey Count')}
|
current={billingUsageData?.surveyCount ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxSurveyCount}
|
||||||
<CardContent>
|
/>
|
||||||
{formatNumber(billingUsageData?.surveyCount ?? 0)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="flex-1">
|
<UsageCard
|
||||||
<CardHeader className="text-muted-foreground">
|
title={t('Feed Event Count')}
|
||||||
{t('Feed Event Count')}
|
current={billingUsageData?.feedEventCount ?? 0}
|
||||||
</CardHeader>
|
limit={limit?.maxFeedEventCount}
|
||||||
<CardContent>
|
/>
|
||||||
{formatNumber(billingUsageData?.feedEventCount ?? 0)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { WorkspaceSubscriptionTier } from '@prisma/client';
|
import { WorkspaceSubscriptionTier } from '@prisma/client';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
interface TierLimit {
|
export const TierLimitSchema = z.object({
|
||||||
maxWebsiteCount: number;
|
maxWebsiteCount: z.number(),
|
||||||
maxWebsiteEventCount: number;
|
maxWebsiteEventCount: z.number(),
|
||||||
maxMonitorExecutionCount: number;
|
maxMonitorExecutionCount: z.number(),
|
||||||
maxSurveyCount: number;
|
maxSurveyCount: z.number(),
|
||||||
maxFeedChannelCount: number;
|
maxFeedChannelCount: z.number(),
|
||||||
maxFeedEventCount: number;
|
maxFeedEventCount: z.number(),
|
||||||
}
|
});
|
||||||
|
|
||||||
|
type TierLimit = z.infer<typeof TierLimitSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit, Every month
|
* Limit, Every month
|
||||||
|
@ -16,7 +16,11 @@ import {
|
|||||||
SubscriptionTierType,
|
SubscriptionTierType,
|
||||||
} from '../../model/billing/index.js';
|
} from '../../model/billing/index.js';
|
||||||
import { LemonSqueezySubscriptionModelSchema } from '../../prisma/zod/lemonsqueezysubscription.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({
|
export const billingRouter = router({
|
||||||
usage: workspaceProcedure
|
usage: workspaceProcedure
|
||||||
@ -47,6 +51,21 @@ export const billingRouter = router({
|
|||||||
|
|
||||||
return getWorkspaceUsage(workspaceId, startAt, endAt);
|
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
|
currentSubscription: workspaceProcedure
|
||||||
.meta(
|
.meta(
|
||||||
buildBillingOpenapi({
|
buildBillingOpenapi({
|
||||||
|
Loading…
Reference in New Issue
Block a user