From 0d04f6914ec109bacf404e97c6c8c883da27c4ab Mon Sep 17 00:00:00 2001 From: javayhu Date: Thu, 24 Jul 2025 00:50:23 +0800 Subject: [PATCH] refactor: optimize credits rendering by memoizing and moving checks before hooks --- .../(protected)/settings/billing/page.tsx | 8 ++++++-- .../settings/billing/credits-balance-card.tsx | 10 +++++----- .../settings/credits/credit-packages.tsx | 15 ++++++++++----- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/app/[locale]/(protected)/settings/billing/page.tsx b/src/app/[locale]/(protected)/settings/billing/page.tsx index dddba6b..1246b71 100644 --- a/src/app/[locale]/(protected)/settings/billing/page.tsx +++ b/src/app/[locale]/(protected)/settings/billing/page.tsx @@ -2,18 +2,22 @@ import BillingCard from '@/components/settings/billing/billing-card'; import CreditsBalanceCard from '@/components/settings/billing/credits-balance-card'; import { CreditPackages } from '@/components/settings/credits/credit-packages'; import { websiteConfig } from '@/config/website'; +import { useMemo } from 'react'; export default function BillingPage() { + // Memoize the credits enabled state to ensure consistency across renders + const creditsEnabled = useMemo(() => websiteConfig.credits.enableCredits, []); + return (
{/* Billing and Credits Balance Cards */}
- {websiteConfig.credits.enableCredits && } + {creditsEnabled && }
{/* Credit Packages */} - {websiteConfig.credits.enableCredits && ( + {creditsEnabled && (
diff --git a/src/components/settings/billing/credits-balance-card.tsx b/src/components/settings/billing/credits-balance-card.tsx index bddc3ee..7db64f8 100644 --- a/src/components/settings/billing/credits-balance-card.tsx +++ b/src/components/settings/billing/credits-balance-card.tsx @@ -26,6 +26,11 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { toast } from 'sonner'; export default function CreditsBalanceCard() { + // Don't render if credits are disabled - move this check before any hooks + if (!websiteConfig.credits.enableCredits) { + return null; + } + const t = useTranslations('Dashboard.settings.credits.balance'); const searchParams = useSearchParams(); const localeRouter = useLocaleRouter(); @@ -109,11 +114,6 @@ export default function CreditsBalanceCard() { fetchCreditStats(); }, [fetchCredits, fetchCreditStats]); - // Don't render if credits are disabled - if (!websiteConfig.credits.enableCredits) { - return null; - } - // Render loading skeleton const isPageLoading = isLoadingBalance || isLoadingStats; if (!mounted || isPageLoading) { diff --git a/src/components/settings/credits/credit-packages.tsx b/src/components/settings/credits/credit-packages.tsx index 9a2945a..2e93b54 100644 --- a/src/components/settings/credits/credit-packages.tsx +++ b/src/components/settings/credits/credit-packages.tsx @@ -23,12 +23,22 @@ import { CreditCheckoutButton } from './credit-checkout-button'; * @returns Credit packages component */ export function CreditPackages() { + // Check if credits are enabled - move this check before any hooks + if (!websiteConfig.credits.enableCredits) { + return null; + } + const t = useTranslations('Dashboard.settings.credits.packages'); // Get current user and payment info const currentUser = useCurrentUser(); const { currentPlan } = usePayment(); + // Get credit packages with translations - must be called here to maintain hook order + const creditPackages = Object.values(getCreditPackages()).filter( + (pkg) => !pkg.disabled && pkg.price.priceId + ); + // Check if user is on free plan and enableForFreePlan is false const isFreePlan = currentPlan?.isFree === true; @@ -37,11 +47,6 @@ export function CreditPackages() { return null; } - // show only enabled packages - const creditPackages = Object.values(getCreditPackages()).filter( - (pkg) => !pkg.disabled && pkg.price.priceId - ); - return (