Delete legacy alerts
This commit is contained in:
@@ -1,165 +0,0 @@
|
||||
// Real API hook for Critical Alerts using backend forecast alerts
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useForecast } from '../api';
|
||||
import { useTenantId } from './useTenantId';
|
||||
|
||||
export interface RealAlert {
|
||||
id: string;
|
||||
type: 'stock' | 'weather' | 'order' | 'production' | 'system';
|
||||
severity: 'high' | 'medium' | 'low';
|
||||
title: string;
|
||||
description: string;
|
||||
action?: string;
|
||||
time: string;
|
||||
}
|
||||
|
||||
export const useRealAlerts = () => {
|
||||
const [alerts, setAlerts] = useState<RealAlert[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const { tenantId } = useTenantId();
|
||||
const { getForecastAlerts, acknowledgeForecastAlert } = useForecast();
|
||||
|
||||
// Transform backend forecast alerts to frontend alert format
|
||||
const transformForecastAlert = (alert: any): RealAlert => {
|
||||
// Map alert types
|
||||
let type: RealAlert['type'] = 'system';
|
||||
if (alert.alert_type?.includes('stock') || alert.alert_type?.includes('demand')) {
|
||||
type = 'stock';
|
||||
} else if (alert.alert_type?.includes('weather')) {
|
||||
type = 'weather';
|
||||
} else if (alert.alert_type?.includes('production')) {
|
||||
type = 'production';
|
||||
}
|
||||
|
||||
// Map severity
|
||||
let severity: RealAlert['severity'] = 'medium';
|
||||
if (alert.severity === 'critical' || alert.severity === 'high') {
|
||||
severity = 'high';
|
||||
} else if (alert.severity === 'low') {
|
||||
severity = 'low';
|
||||
}
|
||||
|
||||
// Generate user-friendly title and description
|
||||
let title = alert.message;
|
||||
let description = alert.message;
|
||||
|
||||
if (alert.alert_type?.includes('high_demand')) {
|
||||
title = 'Alta Demanda Prevista';
|
||||
description = `Se prevé alta demanda. ${alert.message}`;
|
||||
} else if (alert.alert_type?.includes('low_confidence')) {
|
||||
title = 'Predicción Incierta';
|
||||
description = `Baja confianza en predicción. ${alert.message}`;
|
||||
} else if (alert.alert_type?.includes('stock_risk')) {
|
||||
title = 'Riesgo de Desabastecimiento';
|
||||
description = `Posible falta de stock. ${alert.message}`;
|
||||
}
|
||||
|
||||
return {
|
||||
id: alert.id,
|
||||
type,
|
||||
severity,
|
||||
title,
|
||||
description,
|
||||
action: 'Ver detalles',
|
||||
time: new Date(alert.created_at).toLocaleTimeString('es-ES', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
// Load real alerts from backend
|
||||
const loadAlerts = useCallback(async () => {
|
||||
if (!tenantId) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
// Get forecast alerts from backend
|
||||
const response = await getForecastAlerts(tenantId);
|
||||
|
||||
// Extract alerts array from paginated response
|
||||
const forecastAlerts = response.alerts || [];
|
||||
|
||||
// Filter only active alerts
|
||||
const activeAlerts = forecastAlerts.filter(alert => alert.is_active);
|
||||
|
||||
// Transform to frontend format
|
||||
const transformedAlerts = activeAlerts.map(transformForecastAlert);
|
||||
|
||||
// Sort by severity and time (most recent first)
|
||||
transformedAlerts.sort((a, b) => {
|
||||
// First by severity (high > medium > low)
|
||||
const severityOrder = { high: 3, medium: 2, low: 1 };
|
||||
const severityDiff = severityOrder[b.severity] - severityOrder[a.severity];
|
||||
if (severityDiff !== 0) return severityDiff;
|
||||
|
||||
// Then by time (most recent first)
|
||||
return b.time.localeCompare(a.time);
|
||||
});
|
||||
|
||||
setAlerts(transformedAlerts.slice(0, 3)); // Show max 3 alerts in dashboard
|
||||
} catch (error) {
|
||||
console.error('Error loading alerts:', error);
|
||||
setError(error instanceof Error ? error.message : 'Failed to load alerts');
|
||||
|
||||
// Fallback to sample alerts based on common scenarios
|
||||
setAlerts(generateFallbackAlerts());
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [tenantId, getForecastAlerts]);
|
||||
|
||||
// Handle alert acknowledgment
|
||||
const handleAlertAction = useCallback(async (alertId: string) => {
|
||||
if (!tenantId) return;
|
||||
|
||||
try {
|
||||
await acknowledgeForecastAlert(tenantId, alertId);
|
||||
// Remove acknowledged alert from local state
|
||||
setAlerts(prev => prev.filter(alert => alert.id !== alertId));
|
||||
} catch (error) {
|
||||
console.error('Error acknowledging alert:', error);
|
||||
}
|
||||
}, [tenantId, acknowledgeForecastAlert]);
|
||||
|
||||
// Generate fallback alerts when API fails
|
||||
const generateFallbackAlerts = (): RealAlert[] => {
|
||||
const now = new Date();
|
||||
const timeString = now.toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit' });
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'fallback-1',
|
||||
type: 'stock',
|
||||
severity: 'high',
|
||||
title: 'Stock Bajo de Croissants',
|
||||
description: 'Se prevé alta demanda este fin de semana',
|
||||
action: 'Aumentar producción',
|
||||
time: timeString
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
// Load alerts on mount and when tenant changes
|
||||
useEffect(() => {
|
||||
loadAlerts();
|
||||
|
||||
// Refresh alerts every 5 minutes
|
||||
const interval = setInterval(loadAlerts, 5 * 60 * 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [loadAlerts]);
|
||||
|
||||
return {
|
||||
alerts,
|
||||
isLoading,
|
||||
error,
|
||||
onAlertAction: handleAlertAction,
|
||||
reload: loadAlerts,
|
||||
clearError: () => setError(null),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user