trading-platform-frontend-v2/src/modules/predictions/hooks/usePredictions.ts
rckrdmrd 737303d177 Migración desde trading-platform/apps/frontend - Estándar multi-repo v2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:32:49 -06:00

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');
},
});
}