154 lines
4.2 KiB
TypeScript
154 lines
4.2 KiB
TypeScript
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 = {
|
|
all: ['credits'] as const,
|
|
balance: () => [...creditsKeys.all, 'balance'] as const,
|
|
stats: () => [...creditsKeys.all, 'stats'] as const,
|
|
transactions: () => [...creditsKeys.all, 'transactions'] as const,
|
|
transactionsList: (filters: {
|
|
pageIndex: number;
|
|
pageSize: number;
|
|
search: string;
|
|
sorting: SortingState;
|
|
}) => [...creditsKeys.transactions(), filters] as const,
|
|
};
|
|
|
|
// Hook to fetch credit balance
|
|
export function useCreditBalance() {
|
|
const updateTrigger = useCreditsStore((state) => state.updateTrigger);
|
|
|
|
const query = useQuery({
|
|
queryKey: creditsKeys.balance(),
|
|
queryFn: async () => {
|
|
console.log('Fetching credit balance...');
|
|
const result = await getCreditBalanceAction();
|
|
if (!result?.data?.success) {
|
|
throw new Error(
|
|
result?.data?.error || 'Failed to fetch credit balance'
|
|
);
|
|
}
|
|
console.log('Credit balance fetched:', result.data.credits);
|
|
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() {
|
|
const updateTrigger = useCreditsStore((state) => state.updateTrigger);
|
|
|
|
const query = useQuery({
|
|
queryKey: creditsKeys.stats(),
|
|
queryFn: async () => {
|
|
console.log('Fetching credit stats...');
|
|
const result = await getCreditStatsAction();
|
|
if (!result?.data?.success) {
|
|
throw new Error(result?.data?.error || 'Failed to fetch credit stats');
|
|
}
|
|
console.log('Credit stats fetched:', result.data.data);
|
|
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 ({
|
|
amount,
|
|
description,
|
|
}: {
|
|
amount: number;
|
|
description: string;
|
|
}) => {
|
|
const result = await consumeCreditsAction({
|
|
amount,
|
|
description,
|
|
});
|
|
if (!result?.data?.success) {
|
|
throw new Error(result?.data?.error || 'Failed to consume credits');
|
|
}
|
|
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(),
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: creditsKeys.stats(),
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
// Hook to fetch credit transactions with pagination, search, and sorting
|
|
export function useCreditTransactions(
|
|
pageIndex: number,
|
|
pageSize: number,
|
|
search: string,
|
|
sorting: SortingState
|
|
) {
|
|
return useQuery({
|
|
queryKey: creditsKeys.transactionsList({
|
|
pageIndex,
|
|
pageSize,
|
|
search,
|
|
sorting,
|
|
}),
|
|
queryFn: async () => {
|
|
const result = await getCreditTransactionsAction({
|
|
pageIndex,
|
|
pageSize,
|
|
search,
|
|
sorting,
|
|
});
|
|
|
|
if (!result?.data?.success) {
|
|
throw new Error(
|
|
result?.data?.error || 'Failed to fetch credit transactions'
|
|
);
|
|
}
|
|
|
|
return {
|
|
items: result.data.data?.items || [],
|
|
total: result.data.data?.total || 0,
|
|
};
|
|
},
|
|
});
|
|
}
|