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:
parent
13bee49f90
commit
e933844479
4
.gitignore
vendored
4
.gitignore
vendored
@ -30,6 +30,8 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
certificates
|
||||||
|
|
||||||
# env files (can opt-in for committing if needed)
|
# env files (can opt-in for committing if needed)
|
||||||
.env*
|
.env*
|
||||||
|
|
||||||
@ -53,4 +55,4 @@ next-env.d.ts
|
|||||||
.wrangler
|
.wrangler
|
||||||
.dev.vars
|
.dev.vars
|
||||||
.dev.vars*
|
.dev.vars*
|
||||||
!.dev.vars.example
|
!.dev.vars.example
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
"dev-https": "next dev --experimental-https",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"postinstall": "fumadocs-mdx",
|
"postinstall": "fumadocs-mdx",
|
||||||
|
@ -8,6 +8,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/u
|
|||||||
import { CREDIT_PACKAGES } from '@/lib/constants';
|
import { CREDIT_PACKAGES } from '@/lib/constants';
|
||||||
import { formatPrice } from '@/lib/formatter';
|
import { formatPrice } from '@/lib/formatter';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { useTransactionStore } from '@/stores/transaction-store';
|
||||||
import { CircleCheckBigIcon, CoinsIcon, Loader2Icon } from 'lucide-react';
|
import { CircleCheckBigIcon, CoinsIcon, Loader2Icon } from 'lucide-react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
@ -28,6 +29,8 @@ export function CreditPackages() {
|
|||||||
clientSecret: null,
|
clientSecret: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { refreshTrigger } = useTransactionStore();
|
||||||
|
|
||||||
const fetchCredits = async () => {
|
const fetchCredits = async () => {
|
||||||
try {
|
try {
|
||||||
setLoadingCredits(true);
|
setLoadingCredits(true);
|
||||||
@ -48,9 +51,10 @@ export function CreditPackages() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initial fetch and listen for transaction updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchCredits();
|
fetchCredits();
|
||||||
}, []);
|
}, [refreshTrigger]);
|
||||||
|
|
||||||
const handlePurchase = async (packageId: string) => {
|
const handlePurchase = async (packageId: string) => {
|
||||||
try {
|
try {
|
||||||
@ -82,11 +86,6 @@ export function CreditPackages() {
|
|||||||
packageId: null,
|
packageId: null,
|
||||||
clientSecret: null,
|
clientSecret: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Refresh credit balance without page reload
|
|
||||||
fetchCredits();
|
|
||||||
|
|
||||||
// Show success toast
|
|
||||||
toast.success('Your credits have been added to your account');
|
toast.success('Your credits have been added to your account');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import { confirmCreditPayment } from '@/actions/credits.action';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { formatPrice } from '@/lib/formatter';
|
import { formatPrice } from '@/lib/formatter';
|
||||||
|
import { useTransactionStore } from '@/stores/transaction-store';
|
||||||
import {
|
import {
|
||||||
Elements,
|
Elements,
|
||||||
PaymentElement,
|
PaymentElement,
|
||||||
@ -82,6 +83,7 @@ function PaymentForm({
|
|||||||
const stripe = useStripe();
|
const stripe = useStripe();
|
||||||
const elements = useElements();
|
const elements = useElements();
|
||||||
const [processing, setProcessing] = useState(false);
|
const [processing, setProcessing] = useState(false);
|
||||||
|
const { triggerRefresh } = useTransactionStore();
|
||||||
|
|
||||||
const handleSubmit = async (event: React.FormEvent) => {
|
const handleSubmit = async (event: React.FormEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -115,6 +117,10 @@ function PaymentForm({
|
|||||||
if (result?.data?.success) {
|
if (result?.data?.success) {
|
||||||
console.log('PaymentForm, payment success');
|
console.log('PaymentForm, payment success');
|
||||||
toast.success(`${packageInfo.credits} credits have been added to your account.`);
|
toast.success(`${packageInfo.credits} credits have been added to your account.`);
|
||||||
|
|
||||||
|
// Trigger refresh for transaction-dependent UI components
|
||||||
|
triggerRefresh();
|
||||||
|
|
||||||
onPaymentSuccess();
|
onPaymentSuccess();
|
||||||
} else {
|
} else {
|
||||||
console.error('PaymentForm, payment error:', result?.data?.error);
|
console.error('PaymentForm, payment error:', result?.data?.error);
|
||||||
|
11
src/stores/transaction-store.ts
Normal file
11
src/stores/transaction-store.ts
Normal 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 })),
|
||||||
|
}));
|
Loading…
Reference in New Issue
Block a user