refactor: conditionally render credits-related components based on configuration
This commit is contained in:
parent
31116cbf8b
commit
4313e32471
@ -571,6 +571,7 @@
|
|||||||
"createCustomerPortalFailed": "Failed to open Stripe customer portal"
|
"createCustomerPortalFailed": "Failed to open Stripe customer portal"
|
||||||
},
|
},
|
||||||
"price": "Price:",
|
"price": "Price:",
|
||||||
|
"periodStartDate": "Period start date:",
|
||||||
"nextBillingDate": "Next billing date:",
|
"nextBillingDate": "Next billing date:",
|
||||||
"trialEnds": "Trial ends:",
|
"trialEnds": "Trial ends:",
|
||||||
"freePlanMessage": "You are currently on the free plan with limited features",
|
"freePlanMessage": "You are currently on the free plan with limited features",
|
||||||
|
@ -571,6 +571,7 @@
|
|||||||
"createCustomerPortalFailed": "打开Stripe客户界面失败"
|
"createCustomerPortalFailed": "打开Stripe客户界面失败"
|
||||||
},
|
},
|
||||||
"price": "价格:",
|
"price": "价格:",
|
||||||
|
"periodStartDate": "周期开始日期:",
|
||||||
"nextBillingDate": "下次账单日期:",
|
"nextBillingDate": "下次账单日期:",
|
||||||
"trialEnds": "试用结束日期:",
|
"trialEnds": "试用结束日期:",
|
||||||
"freePlanMessage": "您当前使用的是功能有限的免费方案",
|
"freePlanMessage": "您当前使用的是功能有限的免费方案",
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { websiteConfig } from '@/config/website';
|
||||||
import { useCredits } from '@/hooks/use-credits';
|
import { useCredits } from '@/hooks/use-credits';
|
||||||
import { useLocaleRouter } from '@/i18n/navigation';
|
import { useLocaleRouter } from '@/i18n/navigation';
|
||||||
import { Routes } from '@/routes';
|
import { Routes } from '@/routes';
|
||||||
import { CoinsIcon, Loader2Icon } from 'lucide-react';
|
import { CoinsIcon, Loader2Icon } from 'lucide-react';
|
||||||
|
|
||||||
export function CreditsBalanceButton() {
|
export function CreditsBalanceButton() {
|
||||||
|
// If credits are not enabled, return null
|
||||||
|
if (!websiteConfig.credits.enableCredits) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const router = useLocaleRouter();
|
const router = useLocaleRouter();
|
||||||
|
|
||||||
// Use the new useCredits hook
|
// Use the new useCredits hook
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { websiteConfig } from '@/config/website';
|
||||||
import { useCredits } from '@/hooks/use-credits';
|
import { useCredits } from '@/hooks/use-credits';
|
||||||
import { useLocaleRouter } from '@/i18n/navigation';
|
import { useLocaleRouter } from '@/i18n/navigation';
|
||||||
import { Routes } from '@/routes';
|
import { Routes } from '@/routes';
|
||||||
@ -7,6 +8,11 @@ import { CoinsIcon, Loader2Icon } from 'lucide-react';
|
|||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
export function CreditsBalanceMenu() {
|
export function CreditsBalanceMenu() {
|
||||||
|
// If credits are not enabled, return null
|
||||||
|
if (!websiteConfig.credits.enableCredits) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const t = useTranslations('Marketing.avatar');
|
const t = useTranslations('Marketing.avatar');
|
||||||
const router = useLocaleRouter();
|
const router = useLocaleRouter();
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import { formatDate, formatPrice } from '@/lib/formatter';
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { PlanIntervals } from '@/payment/types';
|
import { PlanIntervals } from '@/payment/types';
|
||||||
import { Routes } from '@/routes';
|
import { Routes } from '@/routes';
|
||||||
import { RefreshCwIcon } from 'lucide-react';
|
import { CheckCircleIcon, ClockIcon, RefreshCwIcon } from 'lucide-react';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
@ -63,6 +63,11 @@ export default function BillingCard() {
|
|||||||
(price) => price.priceId === subscription?.priceId
|
(price) => price.priceId === subscription?.priceId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Get current period start date
|
||||||
|
const currentPeriodStart = subscription?.currentPeriodStart
|
||||||
|
? formatDate(subscription.currentPeriodStart)
|
||||||
|
: null;
|
||||||
|
|
||||||
// Format next billing date if subscription is active
|
// Format next billing date if subscription is active
|
||||||
const nextBillingDate = subscription?.currentPeriodEnd
|
const nextBillingDate = subscription?.currentPeriodEnd
|
||||||
? formatDate(subscription.currentPeriodEnd)
|
? formatDate(subscription.currentPeriodEnd)
|
||||||
@ -178,15 +183,23 @@ export default function BillingCard() {
|
|||||||
{/* Plan name and status */}
|
{/* Plan name and status */}
|
||||||
<div className="flex items-center justify-start space-x-4">
|
<div className="flex items-center justify-start space-x-4">
|
||||||
<div className="text-3xl font-medium">{currentPlan?.name}</div>
|
<div className="text-3xl font-medium">{currentPlan?.name}</div>
|
||||||
{subscription && (
|
{subscription &&
|
||||||
<Badge variant="outline">
|
(subscription.status === 'trialing' ||
|
||||||
{subscription?.status === 'trialing'
|
subscription.status === 'active') && (
|
||||||
? t('status.trial')
|
<Badge variant="outline" className="text-xs">
|
||||||
: subscription?.status === 'active'
|
{subscription.status === 'trialing' ? (
|
||||||
? t('status.active')
|
<div className="flex items-center space-x-2">
|
||||||
: ''}
|
<ClockIcon className="size-3 mr-1 text-amber-600" />
|
||||||
</Badge>
|
{t('status.trial')}
|
||||||
)}
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<CheckCircleIcon className="size-3 mr-1 text-green-600" />
|
||||||
|
{t('status.active')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Free plan message */}
|
{/* Free plan message */}
|
||||||
@ -206,7 +219,7 @@ export default function BillingCard() {
|
|||||||
{/* Subscription plan message */}
|
{/* Subscription plan message */}
|
||||||
{subscription && currentPrice && (
|
{subscription && currentPrice && (
|
||||||
<div className="text-sm text-muted-foreground space-y-2">
|
<div className="text-sm text-muted-foreground space-y-2">
|
||||||
<div>
|
{/* <div>
|
||||||
{t('price')}{' '}
|
{t('price')}{' '}
|
||||||
{formatPrice(currentPrice.amount, currentPrice.currency)} /{' '}
|
{formatPrice(currentPrice.amount, currentPrice.currency)} /{' '}
|
||||||
{currentPrice.interval === PlanIntervals.MONTH
|
{currentPrice.interval === PlanIntervals.MONTH
|
||||||
@ -214,10 +227,16 @@ export default function BillingCard() {
|
|||||||
: currentPrice.interval === PlanIntervals.YEAR
|
: currentPrice.interval === PlanIntervals.YEAR
|
||||||
? t('interval.year')
|
? t('interval.year')
|
||||||
: t('interval.oneTime')}
|
: t('interval.oneTime')}
|
||||||
</div>
|
</div> */}
|
||||||
|
|
||||||
|
{currentPeriodStart && (
|
||||||
|
<div className="text-muted-foreground">
|
||||||
|
{t('periodStartDate')} {currentPeriodStart}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{nextBillingDate && (
|
{nextBillingDate && (
|
||||||
<div className="text-green-600">
|
<div className="text-muted-foreground">
|
||||||
{t('nextBillingDate')} {nextBillingDate}
|
{t('nextBillingDate')} {nextBillingDate}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
UsersRoundIcon,
|
UsersRoundIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
|
import { websiteConfig } from './website';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get sidebar config with translations
|
* Get sidebar config with translations
|
||||||
@ -67,12 +68,16 @@ export function getSidebarLinks(): NestedMenuItem[] {
|
|||||||
href: Routes.SettingsBilling,
|
href: Routes.SettingsBilling,
|
||||||
external: false,
|
external: false,
|
||||||
},
|
},
|
||||||
{
|
...(websiteConfig.credits.enableCredits
|
||||||
title: t('settings.credits.title'),
|
? [
|
||||||
icon: <CoinsIcon className="size-4 shrink-0" />,
|
{
|
||||||
href: Routes.SettingsCredits,
|
title: t('settings.credits.title'),
|
||||||
external: false,
|
icon: <CoinsIcon className="size-4 shrink-0" />,
|
||||||
},
|
href: Routes.SettingsCredits,
|
||||||
|
external: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
{
|
{
|
||||||
title: t('settings.security.title'),
|
title: t('settings.security.title'),
|
||||||
icon: <LockKeyholeIcon className="size-4 shrink-0" />,
|
icon: <LockKeyholeIcon className="size-4 shrink-0" />,
|
||||||
|
Loading…
Reference in New Issue
Block a user