refactor: remove subscription and lifetime credits logic from credit stats and balance card
This commit is contained in:
parent
19120ee7f1
commit
63a5e4f328
@ -601,8 +601,7 @@
|
|||||||
"creditsAdded": "Credits have been added to your account",
|
"creditsAdded": "Credits have been added to your account",
|
||||||
"viewTransactions": "View Credit Transactions",
|
"viewTransactions": "View Credit Transactions",
|
||||||
"retry": "Retry",
|
"retry": "Retry",
|
||||||
"subscriptionCredits": "{credits} credits from subscription this month",
|
|
||||||
"lifetimeCredits": "{credits} credits from lifetime plan this month",
|
|
||||||
"expiringCredits": "{credits} credits expiring on {date}"
|
"expiringCredits": "{credits} credits expiring on {date}"
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
|
@ -601,8 +601,7 @@
|
|||||||
"creditsAdded": "积分已添加到您的账户",
|
"creditsAdded": "积分已添加到您的账户",
|
||||||
"viewTransactions": "查看积分记录",
|
"viewTransactions": "查看积分记录",
|
||||||
"retry": "重试",
|
"retry": "重试",
|
||||||
"subscriptionCredits": "本月订阅获得 {credits} 积分",
|
|
||||||
"lifetimeCredits": "本月终身会员获得 {credits} 积分",
|
|
||||||
"expiringCredits": "{credits} 积分将在 {date} 过期"
|
"expiringCredits": "{credits} 积分将在 {date} 过期"
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import { CREDIT_TRANSACTION_TYPE } from '@/credits/types';
|
|
||||||
import { getDb } from '@/db';
|
import { getDb } from '@/db';
|
||||||
import { creditTransaction } from '@/db/schema';
|
import { creditTransaction } from '@/db/schema';
|
||||||
import type { User } from '@/lib/auth-types';
|
import type { User } from '@/lib/auth-types';
|
||||||
@ -9,7 +8,6 @@ import { addDays } from 'date-fns';
|
|||||||
import { and, eq, gte, isNotNull, lte, sql, sum } from 'drizzle-orm';
|
import { and, eq, gte, isNotNull, lte, sql, sum } from 'drizzle-orm';
|
||||||
|
|
||||||
const CREDITS_EXPIRATION_DAYS = 31;
|
const CREDITS_EXPIRATION_DAYS = 31;
|
||||||
const CREDITS_MONTHLY_DAYS = 31;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get credit statistics for a user
|
* Get credit statistics for a user
|
||||||
@ -39,38 +37,6 @@ export const getCreditStatsAction = userActionClient.action(async ({ ctx }) => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get credits from subscription renewals (recent CREDITS_MONTHLY_DAYS days)
|
|
||||||
const monthlyRefreshDaysAgo = addDays(new Date(), -CREDITS_MONTHLY_DAYS);
|
|
||||||
const subscriptionCredits = await db
|
|
||||||
.select({
|
|
||||||
amount: sum(creditTransaction.amount),
|
|
||||||
})
|
|
||||||
.from(creditTransaction)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(creditTransaction.userId, userId),
|
|
||||||
eq(
|
|
||||||
creditTransaction.type,
|
|
||||||
CREDIT_TRANSACTION_TYPE.SUBSCRIPTION_RENEWAL
|
|
||||||
),
|
|
||||||
gte(creditTransaction.createdAt, monthlyRefreshDaysAgo)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get credits from monthly lifetime distribution (recent CREDITS_MONTHLY_DAYS days)
|
|
||||||
const lifetimeCredits = await db
|
|
||||||
.select({
|
|
||||||
amount: sum(creditTransaction.amount),
|
|
||||||
})
|
|
||||||
.from(creditTransaction)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(creditTransaction.userId, userId),
|
|
||||||
eq(creditTransaction.type, CREDIT_TRANSACTION_TYPE.LIFETIME_MONTHLY),
|
|
||||||
gte(creditTransaction.createdAt, monthlyRefreshDaysAgo)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
@ -78,12 +44,6 @@ export const getCreditStatsAction = userActionClient.action(async ({ ctx }) => {
|
|||||||
amount: Number(expiringCredits[0]?.amount) || 0,
|
amount: Number(expiringCredits[0]?.amount) || 0,
|
||||||
earliestExpiration: expiringCredits[0]?.earliestExpiration || null,
|
earliestExpiration: expiringCredits[0]?.earliestExpiration || null,
|
||||||
},
|
},
|
||||||
subscriptionCredits: {
|
|
||||||
amount: Number(subscriptionCredits[0]?.amount) || 0,
|
|
||||||
},
|
|
||||||
lifetimeCredits: {
|
|
||||||
amount: Number(lifetimeCredits[0]?.amount) || 0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -13,9 +13,7 @@ import { Skeleton } from '@/components/ui/skeleton';
|
|||||||
import { websiteConfig } from '@/config/website';
|
import { websiteConfig } from '@/config/website';
|
||||||
import { useCreditBalance, useCreditStats } from '@/hooks/use-credits';
|
import { useCreditBalance, useCreditStats } from '@/hooks/use-credits';
|
||||||
import { useMounted } from '@/hooks/use-mounted';
|
import { useMounted } from '@/hooks/use-mounted';
|
||||||
import { useCurrentPlan } from '@/hooks/use-payment';
|
|
||||||
import { useLocaleRouter } from '@/i18n/navigation';
|
import { useLocaleRouter } from '@/i18n/navigation';
|
||||||
import { authClient } from '@/lib/auth-client';
|
|
||||||
import { formatDate } from '@/lib/formatter';
|
import { formatDate } from '@/lib/formatter';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { Routes } from '@/routes';
|
import { Routes } from '@/routes';
|
||||||
@ -48,11 +46,6 @@ export default function CreditsBalanceCard() {
|
|||||||
refetch: refetchBalance,
|
refetch: refetchBalance,
|
||||||
} = useCreditBalance();
|
} = useCreditBalance();
|
||||||
|
|
||||||
// Get payment info to check plan type
|
|
||||||
const { data: session } = authClient.useSession();
|
|
||||||
const { data: paymentData } = useCurrentPlan(session?.user?.id);
|
|
||||||
const currentPlan = paymentData?.currentPlan;
|
|
||||||
|
|
||||||
// TanStack Query hook for credit statistics
|
// TanStack Query hook for credit statistics
|
||||||
const {
|
const {
|
||||||
data: creditStats,
|
data: creditStats,
|
||||||
@ -167,44 +160,22 @@ export default function CreditsBalanceCard() {
|
|||||||
|
|
||||||
{/* Balance information */}
|
{/* Balance information */}
|
||||||
<div className="text-sm text-muted-foreground space-y-2">
|
<div className="text-sm text-muted-foreground space-y-2">
|
||||||
{/* Plan-based credits info */}
|
|
||||||
{!isLoadingStats && creditStats && (
|
|
||||||
<>
|
|
||||||
{/* Subscription credits (for paid plans) */}
|
|
||||||
{!currentPlan?.isFree &&
|
|
||||||
(creditStats.subscriptionCredits.amount > 0 ||
|
|
||||||
creditStats.lifetimeCredits.amount > 0) && (
|
|
||||||
<div className="flex items-center gap-2 text-muted-foreground">
|
|
||||||
<span>
|
|
||||||
{currentPlan?.isLifetime
|
|
||||||
? t('lifetimeCredits', {
|
|
||||||
credits: creditStats.lifetimeCredits.amount,
|
|
||||||
})
|
|
||||||
: t('subscriptionCredits', {
|
|
||||||
credits: creditStats.subscriptionCredits.amount,
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Expiring credits warning */}
|
{/* Expiring credits warning */}
|
||||||
{creditStats.expiringCredits.amount > 0 &&
|
{!isLoadingStats &&
|
||||||
|
creditStats &&
|
||||||
|
creditStats.expiringCredits.amount > 0 &&
|
||||||
creditStats.expiringCredits.earliestExpiration && (
|
creditStats.expiringCredits.earliestExpiration && (
|
||||||
<div className="flex items-center gap-2 text-amber-600">
|
<div className="flex items-center gap-2 text-amber-600">
|
||||||
<span>
|
<span>
|
||||||
{t('expiringCredits', {
|
{t('expiringCredits', {
|
||||||
credits: creditStats.expiringCredits.amount,
|
credits: creditStats.expiringCredits.amount,
|
||||||
date: formatDate(
|
date: formatDate(
|
||||||
new Date(
|
new Date(creditStats.expiringCredits.earliestExpiration)
|
||||||
creditStats.expiringCredits.earliestExpiration
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter className="">
|
<CardFooter className="">
|
||||||
|
Loading…
Reference in New Issue
Block a user