129 lines
4.2 KiB
TypeScript
129 lines
4.2 KiB
TypeScript
/**
|
|
* 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<PredictionWithOutcome[], Error>({
|
|
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');
|
|
},
|
|
});
|
|
}
|