refactor: optimize credits balance card logic after successful payment
This commit is contained in:
parent
1fb89a2a05
commit
cf8a7f1242
@ -11,11 +11,7 @@ import {
|
|||||||
} from '@/components/ui/card';
|
} from '@/components/ui/card';
|
||||||
import { Skeleton } from '@/components/ui/skeleton';
|
import { Skeleton } from '@/components/ui/skeleton';
|
||||||
import { websiteConfig } from '@/config/website';
|
import { websiteConfig } from '@/config/website';
|
||||||
import {
|
import { useCreditBalance, useCreditStats } from '@/hooks/use-credits';
|
||||||
creditsKeys,
|
|
||||||
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 { useCurrentPlan } from '@/hooks/use-payment';
|
||||||
import { useLocaleRouter } from '@/i18n/navigation';
|
import { useLocaleRouter } from '@/i18n/navigation';
|
||||||
@ -23,7 +19,6 @@ 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';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
|
||||||
import { RefreshCwIcon } from 'lucide-react';
|
import { RefreshCwIcon } from 'lucide-react';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
@ -42,7 +37,6 @@ export default function CreditsBalanceCard() {
|
|||||||
const t = useTranslations('Dashboard.settings.credits.balance');
|
const t = useTranslations('Dashboard.settings.credits.balance');
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const localeRouter = useLocaleRouter();
|
const localeRouter = useLocaleRouter();
|
||||||
const queryClient = useQueryClient();
|
|
||||||
const hasHandledSession = useRef(false);
|
const hasHandledSession = useRef(false);
|
||||||
const mounted = useMounted();
|
const mounted = useMounted();
|
||||||
|
|
||||||
@ -67,6 +61,21 @@ export default function CreditsBalanceCard() {
|
|||||||
refetch: refetchStats,
|
refetch: refetchStats,
|
||||||
} = useCreditStats();
|
} = useCreditStats();
|
||||||
|
|
||||||
|
// Handle payment success after credits purchase
|
||||||
|
const handlePaymentSuccess = useCallback(async () => {
|
||||||
|
// Use queueMicrotask to avoid React rendering conflicts
|
||||||
|
queueMicrotask(() => {
|
||||||
|
toast.success(t('creditsAdded'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait for webhook to process (simplified approach)
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
// Force refresh data
|
||||||
|
refetchBalance();
|
||||||
|
refetchStats();
|
||||||
|
}, [t, refetchBalance, refetchStats]);
|
||||||
|
|
||||||
// Check for payment success and show success message
|
// Check for payment success and show success message
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sessionId = searchParams.get('credits_session_id');
|
const sessionId = searchParams.get('credits_session_id');
|
||||||
@ -78,40 +87,17 @@ export default function CreditsBalanceCard() {
|
|||||||
url.searchParams.delete('credits_session_id');
|
url.searchParams.delete('credits_session_id');
|
||||||
localeRouter.replace(Routes.SettingsCredits + url.search);
|
localeRouter.replace(Routes.SettingsCredits + url.search);
|
||||||
|
|
||||||
// Handle payment success with proper timing
|
// Handle payment success
|
||||||
const handlePaymentSuccess = async () => {
|
|
||||||
// Show success toast (must be in setTimeout to avoid errors)
|
|
||||||
setTimeout(() => {
|
|
||||||
toast.success(t('creditsAdded'));
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
// Wait for webhook to process
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
||||||
|
|
||||||
// Force refresh data
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: creditsKeys.balance(),
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: creditsKeys.stats(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
handlePaymentSuccess();
|
handlePaymentSuccess();
|
||||||
}
|
}
|
||||||
}, [searchParams, localeRouter, queryClient, t]);
|
}, [searchParams, localeRouter, handlePaymentSuccess]);
|
||||||
|
|
||||||
// Retry all data fetching
|
// Retry all data fetching using refetch methods
|
||||||
const handleRetry = useCallback(() => {
|
const handleRetry = useCallback(() => {
|
||||||
// console.log('handleRetry, refetch credits data');
|
// Use refetch methods for immediate data refresh
|
||||||
// Force invalidate cache to ensure fresh data
|
refetchBalance();
|
||||||
queryClient.invalidateQueries({
|
refetchStats();
|
||||||
queryKey: creditsKeys.balance(),
|
}, [refetchBalance, refetchStats]);
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: creditsKeys.stats(),
|
|
||||||
});
|
|
||||||
}, [queryClient]);
|
|
||||||
|
|
||||||
// Render loading skeleton
|
// Render loading skeleton
|
||||||
if (!mounted || isLoadingBalance || isLoadingStats) {
|
if (!mounted || isLoadingBalance || isLoadingStats) {
|
||||||
|
@ -32,8 +32,6 @@ export function useCreditBalance() {
|
|||||||
console.log('Credit balance fetched:', result.data.credits);
|
console.log('Credit balance fetched:', result.data.credits);
|
||||||
return result.data.credits || 0;
|
return result.data.credits || 0;
|
||||||
},
|
},
|
||||||
staleTime: 30 * 1000, // 30 seconds - reasonable stale time
|
|
||||||
retry: 2, // Retry up to 2 times on failure
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +48,6 @@ export function useCreditStats() {
|
|||||||
console.log('Credit stats fetched:', result.data.data);
|
console.log('Credit stats fetched:', result.data.data);
|
||||||
return result.data.data;
|
return result.data.data;
|
||||||
},
|
},
|
||||||
staleTime: 30 * 1000, // 30 seconds - reasonable stale time
|
|
||||||
retry: 2, // Retry up to 2 times on failure
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user