From 7851a715a3d56843d603698e4dcf00bf5360ecbb Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 24 Aug 2025 19:26:54 +0800 Subject: [PATCH] feat: enhance credit hooks to trigger updates on store changes --- src/hooks/use-credits.ts | 34 ++++++++++++++++++++++++++++++++-- src/stores/credits-store.ts | 23 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/stores/credits-store.ts diff --git a/src/hooks/use-credits.ts b/src/hooks/use-credits.ts index 7c4ed8c..136972f 100644 --- a/src/hooks/use-credits.ts +++ b/src/hooks/use-credits.ts @@ -2,8 +2,10 @@ import { consumeCreditsAction } from '@/actions/consume-credits'; import { getCreditBalanceAction } from '@/actions/get-credit-balance'; import { getCreditStatsAction } from '@/actions/get-credit-stats'; import { getCreditTransactionsAction } from '@/actions/get-credit-transactions'; +import { useCreditsStore } from '@/stores/credits-store'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import type { SortingState } from '@tanstack/react-table'; +import { useEffect } from 'react'; // Query keys export const creditsKeys = { @@ -21,7 +23,9 @@ export const creditsKeys = { // Hook to fetch credit balance export function useCreditBalance() { - return useQuery({ + const updateTrigger = useCreditsStore((state) => state.updateTrigger); + + const query = useQuery({ queryKey: creditsKeys.balance(), queryFn: async () => { console.log('Fetching credit balance...'); @@ -33,11 +37,23 @@ export function useCreditBalance() { return result.data.credits || 0; }, }); + + // Refetch when updateTrigger changes + useEffect(() => { + if (updateTrigger > 0) { + console.log('Credits update triggered, refetching balance...'); + query.refetch(); + } + }, [updateTrigger, query]); + + return query; } // Hook to fetch credit statistics export function useCreditStats() { - return useQuery({ + const updateTrigger = useCreditsStore((state) => state.updateTrigger); + + const query = useQuery({ queryKey: creditsKeys.stats(), queryFn: async () => { console.log('Fetching credit stats...'); @@ -49,11 +65,22 @@ export function useCreditStats() { return result.data.data; }, }); + + // Refetch when updateTrigger changes + useEffect(() => { + if (updateTrigger > 0) { + console.log('Credits update triggered, refetching stats...'); + query.refetch(); + } + }, [updateTrigger, query]); + + return query; } // Hook to consume credits export function useConsumeCredits() { const queryClient = useQueryClient(); + const triggerUpdate = useCreditsStore((state) => state.triggerUpdate); return useMutation({ mutationFn: async ({ @@ -73,6 +100,9 @@ export function useConsumeCredits() { return result.data; }, onSuccess: () => { + // Trigger credits update in store to notify all components + triggerUpdate(); + // Invalidate credit balance and stats after consuming credits queryClient.invalidateQueries({ queryKey: creditsKeys.balance(), diff --git a/src/stores/credits-store.ts b/src/stores/credits-store.ts new file mode 100644 index 0000000..3c2f909 --- /dev/null +++ b/src/stores/credits-store.ts @@ -0,0 +1,23 @@ +import { create } from 'zustand'; + +interface CreditsState { + // trigger for credit updates, incremented each time credits change + updateTrigger: number; + // method to trigger credit updates + triggerUpdate: () => void; +} + +/** + * Credits store for managing credit balance updates. + * + * This store provides a simple trigger mechanism to notify components + * when credits have been consumed or updated, ensuring UI components can + * refetch the latest credit balance. + */ +export const useCreditsStore = create((set) => ({ + updateTrigger: 0, + triggerUpdate: () => + set((state) => ({ + updateTrigger: state.updateTrigger + 1, + })), +}));