ADD new frontend
This commit is contained in:
568
frontend/src/hooks/api/useForecasting.ts
Normal file
568
frontend/src/hooks/api/useForecasting.ts
Normal file
@@ -0,0 +1,568 @@
|
||||
/**
|
||||
* Forecasting hook for managing demand forecasting and ML models
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { ForecastingService } from '../../services/api/forecasting.service';
|
||||
import {
|
||||
ForecastModel,
|
||||
ForecastModelCreate,
|
||||
ForecastModelUpdate,
|
||||
ForecastPrediction,
|
||||
ForecastPredictionCreate,
|
||||
ForecastBatch,
|
||||
ModelTraining,
|
||||
ModelEvaluation
|
||||
} from '../../types/forecasting.types';
|
||||
import { ApiResponse, PaginatedResponse, QueryParams } from '../../types/api.types';
|
||||
|
||||
interface ForecastingState {
|
||||
models: ForecastModel[];
|
||||
predictions: ForecastPrediction[];
|
||||
batches: ForecastBatch[];
|
||||
trainings: ModelTraining[];
|
||||
evaluations: ModelEvaluation[];
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
pagination: {
|
||||
total: number;
|
||||
page: number;
|
||||
pages: number;
|
||||
limit: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface ForecastingActions {
|
||||
// Models
|
||||
fetchModels: (params?: QueryParams) => Promise<void>;
|
||||
createModel: (data: ForecastModelCreate) => Promise<boolean>;
|
||||
updateModel: (id: string, data: ForecastModelUpdate) => Promise<boolean>;
|
||||
deleteModel: (id: string) => Promise<boolean>;
|
||||
getModel: (id: string) => Promise<ForecastModel | null>;
|
||||
trainModel: (id: string, parameters?: any) => Promise<boolean>;
|
||||
deployModel: (id: string) => Promise<boolean>;
|
||||
|
||||
// Predictions
|
||||
fetchPredictions: (params?: QueryParams) => Promise<void>;
|
||||
createPrediction: (data: ForecastPredictionCreate) => Promise<boolean>;
|
||||
getPrediction: (id: string) => Promise<ForecastPrediction | null>;
|
||||
generateDemandForecast: (modelId: string, horizon: number, parameters?: any) => Promise<any>;
|
||||
|
||||
// Batch Predictions
|
||||
fetchBatches: (params?: QueryParams) => Promise<void>;
|
||||
createBatch: (modelId: string, data: any) => Promise<boolean>;
|
||||
getBatch: (id: string) => Promise<ForecastBatch | null>;
|
||||
downloadBatchResults: (id: string) => Promise<boolean>;
|
||||
|
||||
// Model Training
|
||||
fetchTrainings: (modelId?: string) => Promise<void>;
|
||||
getTraining: (id: string) => Promise<ModelTraining | null>;
|
||||
cancelTraining: (id: string) => Promise<boolean>;
|
||||
|
||||
// Model Evaluation
|
||||
fetchEvaluations: (modelId?: string) => Promise<void>;
|
||||
createEvaluation: (modelId: string, testData: any) => Promise<boolean>;
|
||||
getEvaluation: (id: string) => Promise<ModelEvaluation | null>;
|
||||
|
||||
// Analytics
|
||||
getModelPerformance: (modelId: string, period?: string) => Promise<any>;
|
||||
getAccuracyReport: (modelId: string, startDate?: string, endDate?: string) => Promise<any>;
|
||||
getFeatureImportance: (modelId: string) => Promise<any>;
|
||||
|
||||
// Utilities
|
||||
clearError: () => void;
|
||||
refresh: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const useForecasting = (): ForecastingState & ForecastingActions => {
|
||||
const [state, setState] = useState<ForecastingState>({
|
||||
models: [],
|
||||
predictions: [],
|
||||
batches: [],
|
||||
trainings: [],
|
||||
evaluations: [],
|
||||
isLoading: false,
|
||||
error: null,
|
||||
pagination: {
|
||||
total: 0,
|
||||
page: 1,
|
||||
pages: 1,
|
||||
limit: 20,
|
||||
},
|
||||
});
|
||||
|
||||
const forecastingService = new ForecastingService();
|
||||
|
||||
// Fetch forecast models
|
||||
const fetchModels = useCallback(async (params?: QueryParams) => {
|
||||
setState(prev => ({ ...prev, isLoading: true, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.getModels(params);
|
||||
|
||||
if (response.success && response.data) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
models: Array.isArray(response.data) ? response.data : response.data.items || [],
|
||||
pagination: response.data.pagination || prev.pagination,
|
||||
isLoading: false,
|
||||
}));
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
isLoading: false,
|
||||
error: response.error || 'Error al cargar modelos de predicción',
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
isLoading: false,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Create forecast model
|
||||
const createModel = useCallback(async (data: ForecastModelCreate): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.createModel(data);
|
||||
|
||||
if (response.success) {
|
||||
await fetchModels();
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al crear modelo de predicción',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchModels]);
|
||||
|
||||
// Update forecast model
|
||||
const updateModel = useCallback(async (id: string, data: ForecastModelUpdate): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.updateModel(id, data);
|
||||
|
||||
if (response.success) {
|
||||
await fetchModels();
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al actualizar modelo de predicción',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchModels]);
|
||||
|
||||
// Delete forecast model
|
||||
const deleteModel = useCallback(async (id: string): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.deleteModel(id);
|
||||
|
||||
if (response.success) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
models: prev.models.filter(model => model.id !== id),
|
||||
}));
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al eliminar modelo de predicción',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Get single forecast model
|
||||
const getModel = useCallback(async (id: string): Promise<ForecastModel | null> => {
|
||||
try {
|
||||
const response = await forecastingService.getModel(id);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching model:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Train forecast model
|
||||
const trainModel = useCallback(async (id: string, parameters?: any): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.trainModel(id, parameters);
|
||||
|
||||
if (response.success) {
|
||||
await fetchModels();
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al entrenar modelo',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchModels]);
|
||||
|
||||
// Deploy forecast model
|
||||
const deployModel = useCallback(async (id: string): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.deployModel(id);
|
||||
|
||||
if (response.success) {
|
||||
await fetchModels();
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al desplegar modelo',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchModels]);
|
||||
|
||||
// Fetch predictions
|
||||
const fetchPredictions = useCallback(async (params?: QueryParams) => {
|
||||
setState(prev => ({ ...prev, isLoading: true, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.getPredictions(params);
|
||||
|
||||
if (response.success && response.data) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
predictions: Array.isArray(response.data) ? response.data : response.data.items || [],
|
||||
isLoading: false,
|
||||
}));
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
isLoading: false,
|
||||
error: response.error || 'Error al cargar predicciones',
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
isLoading: false,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Create prediction
|
||||
const createPrediction = useCallback(async (data: ForecastPredictionCreate): Promise<boolean> => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
|
||||
try {
|
||||
const response = await forecastingService.createPrediction(data);
|
||||
|
||||
if (response.success) {
|
||||
await fetchPredictions();
|
||||
return true;
|
||||
} else {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: response.error || 'Error al crear predicción',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
error: 'Error de conexión al servidor',
|
||||
}));
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchPredictions]);
|
||||
|
||||
// Get single prediction
|
||||
const getPrediction = useCallback(async (id: string): Promise<ForecastPrediction | null> => {
|
||||
try {
|
||||
const response = await forecastingService.getPrediction(id);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching prediction:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Generate demand forecast
|
||||
const generateDemandForecast = useCallback(async (modelId: string, horizon: number, parameters?: any) => {
|
||||
try {
|
||||
const response = await forecastingService.generateDemandForecast(modelId, horizon, parameters);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error generating demand forecast:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Fetch batch predictions
|
||||
const fetchBatches = useCallback(async (params?: QueryParams) => {
|
||||
try {
|
||||
const response = await forecastingService.getBatches(params);
|
||||
|
||||
if (response.success && response.data) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
batches: Array.isArray(response.data) ? response.data : response.data.items || [],
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching batches:', error);
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Create batch prediction
|
||||
const createBatch = useCallback(async (modelId: string, data: any): Promise<boolean> => {
|
||||
try {
|
||||
const response = await forecastingService.createBatch(modelId, data);
|
||||
|
||||
if (response.success) {
|
||||
await fetchBatches();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Error creating batch:', error);
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchBatches]);
|
||||
|
||||
// Get single batch
|
||||
const getBatch = useCallback(async (id: string): Promise<ForecastBatch | null> => {
|
||||
try {
|
||||
const response = await forecastingService.getBatch(id);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching batch:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Download batch results
|
||||
const downloadBatchResults = useCallback(async (id: string): Promise<boolean> => {
|
||||
try {
|
||||
const response = await forecastingService.downloadBatchResults(id);
|
||||
return response.success;
|
||||
} catch (error) {
|
||||
console.error('Error downloading batch results:', error);
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Fetch model trainings
|
||||
const fetchTrainings = useCallback(async (modelId?: string) => {
|
||||
try {
|
||||
const response = await forecastingService.getTrainings(modelId);
|
||||
|
||||
if (response.success && response.data) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
trainings: Array.isArray(response.data) ? response.data : response.data.items || [],
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching trainings:', error);
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Get single training
|
||||
const getTraining = useCallback(async (id: string): Promise<ModelTraining | null> => {
|
||||
try {
|
||||
const response = await forecastingService.getTraining(id);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching training:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Cancel model training
|
||||
const cancelTraining = useCallback(async (id: string): Promise<boolean> => {
|
||||
try {
|
||||
const response = await forecastingService.cancelTraining(id);
|
||||
|
||||
if (response.success) {
|
||||
await fetchTrainings();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Error canceling training:', error);
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchTrainings]);
|
||||
|
||||
// Fetch model evaluations
|
||||
const fetchEvaluations = useCallback(async (modelId?: string) => {
|
||||
try {
|
||||
const response = await forecastingService.getEvaluations(modelId);
|
||||
|
||||
if (response.success && response.data) {
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
evaluations: Array.isArray(response.data) ? response.data : response.data.items || [],
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching evaluations:', error);
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Create model evaluation
|
||||
const createEvaluation = useCallback(async (modelId: string, testData: any): Promise<boolean> => {
|
||||
try {
|
||||
const response = await forecastingService.createEvaluation(modelId, testData);
|
||||
|
||||
if (response.success) {
|
||||
await fetchEvaluations(modelId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error('Error creating evaluation:', error);
|
||||
return false;
|
||||
}
|
||||
}, [forecastingService, fetchEvaluations]);
|
||||
|
||||
// Get single evaluation
|
||||
const getEvaluation = useCallback(async (id: string): Promise<ModelEvaluation | null> => {
|
||||
try {
|
||||
const response = await forecastingService.getEvaluation(id);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching evaluation:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Get model performance
|
||||
const getModelPerformance = useCallback(async (modelId: string, period?: string) => {
|
||||
try {
|
||||
const response = await forecastingService.getModelPerformance(modelId, period);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching model performance:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Get accuracy report
|
||||
const getAccuracyReport = useCallback(async (modelId: string, startDate?: string, endDate?: string) => {
|
||||
try {
|
||||
const response = await forecastingService.getAccuracyReport(modelId, startDate, endDate);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching accuracy report:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Get feature importance
|
||||
const getFeatureImportance = useCallback(async (modelId: string) => {
|
||||
try {
|
||||
const response = await forecastingService.getFeatureImportance(modelId);
|
||||
return response.success ? response.data : null;
|
||||
} catch (error) {
|
||||
console.error('Error fetching feature importance:', error);
|
||||
return null;
|
||||
}
|
||||
}, [forecastingService]);
|
||||
|
||||
// Clear error
|
||||
const clearError = useCallback(() => {
|
||||
setState(prev => ({ ...prev, error: null }));
|
||||
}, []);
|
||||
|
||||
// Refresh all data
|
||||
const refresh = useCallback(async () => {
|
||||
await Promise.all([
|
||||
fetchModels(),
|
||||
fetchPredictions(),
|
||||
fetchBatches(),
|
||||
]);
|
||||
}, [fetchModels, fetchPredictions, fetchBatches]);
|
||||
|
||||
// Initialize data on mount
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
}, []);
|
||||
|
||||
return {
|
||||
...state,
|
||||
fetchModels,
|
||||
createModel,
|
||||
updateModel,
|
||||
deleteModel,
|
||||
getModel,
|
||||
trainModel,
|
||||
deployModel,
|
||||
fetchPredictions,
|
||||
createPrediction,
|
||||
getPrediction,
|
||||
generateDemandForecast,
|
||||
fetchBatches,
|
||||
createBatch,
|
||||
getBatch,
|
||||
downloadBatchResults,
|
||||
fetchTrainings,
|
||||
getTraining,
|
||||
cancelTraining,
|
||||
fetchEvaluations,
|
||||
createEvaluation,
|
||||
getEvaluation,
|
||||
getModelPerformance,
|
||||
getAccuracyReport,
|
||||
getFeatureImportance,
|
||||
clearError,
|
||||
refresh,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user