/** * Transaction Analytics Hooks * * React Query hooks for fetching and managing transaction analytics data. */ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { getTransactions, getTransaction, getTransactionSummary, getStripeCharges, getStripePayouts, getStripeBalance, exportTransactions, getTransactionDetail, refundTransaction, TransactionFilters, ExportRequest, RefundRequest, } from '../api/payments'; /** * Hook to fetch paginated transaction list with optional filters. */ export const useTransactions = (filters?: TransactionFilters) => { return useQuery({ queryKey: ['transactions', filters], queryFn: async () => { const { data } = await getTransactions(filters); return data; }, staleTime: 30 * 1000, // 30 seconds }); }; /** * Hook to fetch a single transaction by ID. */ export const useTransaction = (id: number) => { return useQuery({ queryKey: ['transaction', id], queryFn: async () => { const { data } = await getTransaction(id); return data; }, enabled: !!id, }); }; /** * Hook to fetch transaction summary/analytics. */ export const useTransactionSummary = (filters?: Pick) => { return useQuery({ queryKey: ['transactionSummary', filters], queryFn: async () => { const { data } = await getTransactionSummary(filters); return data; }, staleTime: 60 * 1000, // 1 minute }); }; /** * Hook to fetch Stripe charges directly from Stripe API. */ export const useStripeCharges = (limit: number = 20) => { return useQuery({ queryKey: ['stripeCharges', limit], queryFn: async () => { const { data } = await getStripeCharges(limit); return data; }, staleTime: 30 * 1000, }); }; /** * Hook to fetch Stripe payouts. */ export const useStripePayouts = (limit: number = 20) => { return useQuery({ queryKey: ['stripePayouts', limit], queryFn: async () => { const { data } = await getStripePayouts(limit); return data; }, staleTime: 30 * 1000, }); }; /** * Hook to fetch current Stripe balance. */ export const useStripeBalance = () => { return useQuery({ queryKey: ['stripeBalance'], queryFn: async () => { const { data } = await getStripeBalance(); return data; }, staleTime: 60 * 1000, // 1 minute refetchInterval: 5 * 60 * 1000, // Refresh every 5 minutes }); }; /** * Hook to export transaction data. * Returns a mutation that triggers file download. */ export const useExportTransactions = () => { return useMutation({ mutationFn: async (request: ExportRequest) => { const response = await exportTransactions(request); return response; }, onSuccess: (response, request) => { // Create blob URL and trigger download const blob = new Blob([response.data], { type: response.headers['content-type'] }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; // Determine file extension based on format const extensions: Record = { csv: 'csv', xlsx: 'xlsx', pdf: 'pdf', quickbooks: 'iif', }; const ext = extensions[request.format] || 'txt'; link.download = `transactions.${ext}`; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); }, }); }; /** * Hook to invalidate all transaction-related queries. * Useful after actions that modify transaction data. */ export const useInvalidateTransactions = () => { const queryClient = useQueryClient(); return () => { queryClient.invalidateQueries({ queryKey: ['transactions'] }); queryClient.invalidateQueries({ queryKey: ['transactionSummary'] }); queryClient.invalidateQueries({ queryKey: ['stripeCharges'] }); queryClient.invalidateQueries({ queryKey: ['stripePayouts'] }); queryClient.invalidateQueries({ queryKey: ['stripeBalance'] }); queryClient.invalidateQueries({ queryKey: ['transactionDetail'] }); }; }; /** * Hook to fetch detailed transaction information including refund data. */ export const useTransactionDetail = (id: number | null) => { return useQuery({ queryKey: ['transactionDetail', id], queryFn: async () => { if (!id) return null; const { data } = await getTransactionDetail(id); return data; }, enabled: !!id, staleTime: 10 * 1000, // 10 seconds (refresh often for live data) }); }; /** * Hook to issue a refund for a transaction. * Automatically invalidates transaction queries on success. */ export const useRefundTransaction = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ transactionId, request }: { transactionId: number; request?: RefundRequest }) => { const { data } = await refundTransaction(transactionId, request); return data; }, onSuccess: (data, variables) => { // Invalidate all relevant queries queryClient.invalidateQueries({ queryKey: ['transactions'] }); queryClient.invalidateQueries({ queryKey: ['transactionSummary'] }); queryClient.invalidateQueries({ queryKey: ['transactionDetail', variables.transactionId] }); queryClient.invalidateQueries({ queryKey: ['stripeCharges'] }); queryClient.invalidateQueries({ queryKey: ['stripeBalance'] }); }, }); };