feat: enhance credit management with transaction store and UI updates

- Added a new transaction store to manage refresh triggers for credit-related components.
- Updated CreditPackages and StripePaymentForm components to utilize the transaction store for refreshing UI after credit purchases.
- Modified .gitignore to include certificates.
- Introduced a new script in package.json for running the development server with HTTPS support.
This commit is contained in:
javayhu 2025-07-05 23:59:30 +08:00
parent 13bee49f90
commit e933844479
5 changed files with 26 additions and 7 deletions

4
.gitignore vendored
View File

@ -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
!.dev.vars.example

View File

@ -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",

View File

@ -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');
};

View File

@ -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);

View File

@ -0,0 +1,11 @@
import { create } from "zustand";
interface TransactionStore {
refreshTrigger: number;
triggerRefresh: () => void;
}
export const useTransactionStore = create<TransactionStore>((set) => ({
refreshTrigger: 0,
triggerRefresh: () => set((state) => ({ refreshTrigger: state.refreshTrigger + 1 })),
}));