/** * Predictions Hooks */ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from 'react-hot-toast'; import { predictionsApi } from '../services/predictions.api'; import { usePredictionsStore } from '../stores/predictions.store'; import type { RequestPredictionInput, PurchasePackageInput, PredictionFilters, PredictionWithOutcome } from '../types'; // Query keys export const predictionKeys = { all: ['predictions'] as const, packages: (filters?: object) => [...predictionKeys.all, 'packages', filters] as const, package: (id: string) => [...predictionKeys.all, 'package', id] as const, purchases: (activeOnly?: boolean) => [...predictionKeys.all, 'purchases', activeOnly] as const, purchase: (id: string) => [...predictionKeys.all, 'purchase', id] as const, predictions: (filters?: PredictionFilters) => [...predictionKeys.all, 'list', filters] as const, prediction: (id: string) => [...predictionKeys.all, 'detail', id] as const, stats: () => [...predictionKeys.all, 'stats'] as const, }; // Packages export function usePackages(filters?: { predictionType?: string; assetClass?: string }) { const { setPackages } = usePredictionsStore(); return useQuery({ queryKey: predictionKeys.packages(filters), queryFn: async () => { const packages = await predictionsApi.getPackages(filters); setPackages(packages); return packages; }, staleTime: 5 * 60 * 1000, }); } // User purchases export function usePurchases(activeOnly = true) { const { setPurchases } = usePredictionsStore(); return useQuery({ queryKey: predictionKeys.purchases(activeOnly), queryFn: async () => { const purchases = await predictionsApi.getUserPurchases(activeOnly); setPurchases(purchases); return purchases; }, staleTime: 30 * 1000, }); } // Predictions list export function usePredictions(filters?: PredictionFilters) { const { setPredictions } = usePredictionsStore(); return useQuery({ queryKey: predictionKeys.predictions(filters), queryFn: async () => { const predictions = await predictionsApi.getPredictions(filters); setPredictions(predictions); return predictions; }, placeholderData: (previousData) => previousData, staleTime: 30 * 1000, }); } // Single prediction export function usePrediction(predictionId: string) { return useQuery({ queryKey: predictionKeys.prediction(predictionId), queryFn: () => predictionsApi.getPrediction(predictionId), enabled: !!predictionId, }); } // User stats export function usePredictionStats() { const { setStats } = usePredictionsStore(); return useQuery({ queryKey: predictionKeys.stats(), queryFn: async () => { const stats = await predictionsApi.getUserStats(); setStats(stats); return stats; }, staleTime: 60 * 1000, }); } // Purchase package export function usePurchasePackage() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (input: PurchasePackageInput) => predictionsApi.purchasePackage(input), onSuccess: () => { queryClient.invalidateQueries({ queryKey: predictionKeys.purchases() }); queryClient.invalidateQueries({ queryKey: ['wallet'] }); toast.success('Package purchased successfully!'); }, onError: (error: Error) => { toast.error(error.message || 'Failed to purchase package'); }, }); } // Request prediction export function useRequestPrediction() { const queryClient = useQueryClient(); const { appendPrediction } = usePredictionsStore(); return useMutation({ mutationFn: (input: RequestPredictionInput) => predictionsApi.requestPrediction(input), onSuccess: (prediction) => { appendPrediction(prediction); queryClient.invalidateQueries({ queryKey: predictionKeys.purchases() }); queryClient.invalidateQueries({ queryKey: predictionKeys.predictions() }); queryClient.invalidateQueries({ queryKey: predictionKeys.stats() }); toast.success(`Prediction delivered for ${prediction.asset}`); }, onError: (error: Error) => { toast.error(error.message || 'Failed to get prediction'); }, }); }