diff --git a/.gitignore b/.gitignore index 32c5e88..98722b3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,8 @@ yarn-debug.log* yarn-error.log* .pnpm-debug.log* +certificates + # env files (can opt-in for committing if needed) .env* @@ -53,4 +55,4 @@ next-env.d.ts .wrangler .dev.vars .dev.vars* -!.dev.vars.example \ No newline at end of file +!.dev.vars.example diff --git a/package.json b/package.json index 0f79bd4..d0fe6b3 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "next dev", + "dev-https": "next dev --experimental-https", "build": "next build", "start": "next start", "postinstall": "fumadocs-mdx", diff --git a/src/components/settings/credits/credit-packages.tsx b/src/components/settings/credits/credit-packages.tsx index 2bbeb3b..a71fdfc 100644 --- a/src/components/settings/credits/credit-packages.tsx +++ b/src/components/settings/credits/credit-packages.tsx @@ -8,6 +8,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/u import { CREDIT_PACKAGES } from '@/lib/constants'; import { formatPrice } from '@/lib/formatter'; import { cn } from '@/lib/utils'; +import { useTransactionStore } from '@/stores/transaction-store'; import { CircleCheckBigIcon, CoinsIcon, Loader2Icon } from 'lucide-react'; import { useEffect, useState } from 'react'; import { toast } from 'sonner'; @@ -28,6 +29,8 @@ export function CreditPackages() { clientSecret: null, }); + const { refreshTrigger } = useTransactionStore(); + const fetchCredits = async () => { try { setLoadingCredits(true); @@ -48,9 +51,10 @@ export function CreditPackages() { } }; + // Initial fetch and listen for transaction updates useEffect(() => { fetchCredits(); - }, []); + }, [refreshTrigger]); const handlePurchase = async (packageId: string) => { try { @@ -82,11 +86,6 @@ export function CreditPackages() { packageId: null, clientSecret: null, }); - - // Refresh credit balance without page reload - fetchCredits(); - - // Show success toast toast.success('Your credits have been added to your account'); }; diff --git a/src/components/settings/credits/stripe-payment-form.tsx b/src/components/settings/credits/stripe-payment-form.tsx index ff7d6c3..f7bb42c 100644 --- a/src/components/settings/credits/stripe-payment-form.tsx +++ b/src/components/settings/credits/stripe-payment-form.tsx @@ -4,6 +4,7 @@ import { confirmCreditPayment } from '@/actions/credits.action'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { formatPrice } from '@/lib/formatter'; +import { useTransactionStore } from '@/stores/transaction-store'; import { Elements, PaymentElement, @@ -82,6 +83,7 @@ function PaymentForm({ const stripe = useStripe(); const elements = useElements(); const [processing, setProcessing] = useState(false); + const { triggerRefresh } = useTransactionStore(); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); @@ -115,6 +117,10 @@ function PaymentForm({ if (result?.data?.success) { console.log('PaymentForm, payment success'); toast.success(`${packageInfo.credits} credits have been added to your account.`); + + // Trigger refresh for transaction-dependent UI components + triggerRefresh(); + onPaymentSuccess(); } else { console.error('PaymentForm, payment error:', result?.data?.error); diff --git a/src/stores/transaction-store.ts b/src/stores/transaction-store.ts new file mode 100644 index 0000000..47107da --- /dev/null +++ b/src/stores/transaction-store.ts @@ -0,0 +1,11 @@ +import { create } from "zustand"; + +interface TransactionStore { + refreshTrigger: number; + triggerRefresh: () => void; +} + +export const useTransactionStore = create((set) => ({ + refreshTrigger: 0, + triggerRefresh: () => set((state) => ({ refreshTrigger: state.refreshTrigger + 1 })), +}));