= ({
isOpen,
onClose,
model
}) => {
// Early return if model is not provided
if (!model) {
return (
);
}
// Calculate business metrics from technical metrics
// The API response has metrics directly on the model object, not nested in training_metrics
const accuracy = calculateAccuracy((model as any).mape || model.training_metrics?.mape);
const performanceColor = getPerformanceColor(accuracy);
const performanceMessage = getPerformanceMessage(accuracy);
// Prepare sections for StatusModal
const sections: StatusModalSection[] = [
{
title: "Resumen",
icon: Activity,
fields: [
{
label: "Rendimiento del Modelo",
value: (
Precisión
{accuracy.toFixed(0)}%
{performanceMessage}
),
span: 2
},
{
label: "Estado",
value: (
{(model as any).is_active ? 'Activo' : 'Inactivo'}
)
},
{
label: "Última Actualización",
value: formatDate(model.created_at || new Date().toISOString())
},
{
label: "Período de Entrenamiento",
value: `${formatDate((model as any).training_start_date || model.training_period?.start_date || new Date().toISOString())} - ${formatDate((model as any).training_end_date || model.training_period?.end_date || new Date().toISOString())}`
}
]
},
{
title: "Métricas de Rendimiento",
icon: TrendingUp,
fields: [
{
label: "Tasa de Precisión",
value: `${accuracy.toFixed(0)}%`,
highlight: true
},
{
label: "Diferencia Típica",
value: (() => {
const maeValue = ((model as any).mae || model.training_metrics?.mae || 0).toFixed(0);
return (
±{maeValue} productos
En promedio, las predicciones se desvían por {maeValue} productos
);
})()
},
{
label: "Confiabilidad General",
value: `${(((model as any).r2_score || model.training_metrics?.r2_score || 0) * 100).toFixed(0)}% confiable`
}
]
},
{
title: "Qué Significa Esto para Tu Panadería",
icon: Target,
fields: [
{
label: "Precisión de las Predicciones",
value: (() => {
const mapeValue = Math.round((model as any).mape || model.training_metrics?.mape || 0);
return (
Error promedio: {mapeValue}%
Ejemplo práctico: Si el modelo predice que venderás 100 panes,
es muy probable que vendas entre {100 - mapeValue} y {100 + mapeValue} panes.
Mientras menor sea este porcentaje, más precisas son las predicciones.
);
})(),
span: 2
},
{
label: "Potencial de Reducción de Desperdicio",
value: accuracy >= 80
? `Podría ayudar a reducir el desperdicio diario en ~${Math.round(accuracy / 8)}% mediante mejor planificación`
: accuracy >= 60
? 'Alguna reducción de desperdicio posible con monitoreo cuidadoso'
: 'Precisión del modelo demasiado baja para reducción confiable de desperdicio',
highlight: true
}
]
},
{
title: "Factores que Considera el Modelo",
icon: Settings,
fields: [
{
label: "Información que Analiza",
value: (() => {
const features = ((model as any).features_used || model.features_used || []);
const featureCount = features.length;
if (featureCount === 0) {
return (
Usando datos básicos de ventas e historial
);
}
return (
El modelo analiza {featureCount} factores diferentes para hacer predicciones más precisas.
📅 Temporales:
Días de semana, festivos, estaciones
🌤️ Clima:
Temperatura, lluvia, humedad
🚶 Tráfico:
Peatones, congestión, velocidad
📊 Ventas:
Historial, patrones, tendencias
💡 En resumen: Cuantos más factores analiza el modelo, más precisas son las predicciones para tu panadería.
);
})(),
span: 2
}
]
},
{
title: "Detalles Técnicos",
icon: Calendar,
fields: [
{
label: "Método de Predicción",
value: model.model_type || 'Pronóstico con IA'
},
{
label: "Última Actualización",
value: formatDate(model.created_at || new Date().toISOString())
},
{
label: "Período de Entrenamiento",
value: `${formatDate((model as any).training_start_date || model.training_period?.start_date || new Date().toISOString())} a ${formatDate((model as any).training_end_date || model.training_period?.end_date || new Date().toISOString())}`,
span: 2
}
]
},
{
title: "Perspectivas de Negocio",
icon: Lightbulb,
fields: [
{
label: "Qué funciona mejor",
value: (
Este modelo te da las predicciones más precisas para días de semana regulares
),
span: 2
},
{
label: "Ten cuidado con",
value: (
Las predicciones pueden ser menos confiables durante festivos y eventos especiales
),
span: 2
},
{
label: "Patrones descubiertos",
value: ((model as any).features_used || model.features_used || []).some((f: string) => f.toLowerCase().includes('weekend'))
? "Tu negocio muestra patrones diferentes entre días de semana y fines de semana"
: "Este modelo ha aprendido tus patrones regulares de ventas",
span: 2
},
{
label: "Próximos pasos",
value: accuracy < 80
? "Considera reentrenar con datos más recientes para mejorar la precisión"
: "Tu modelo está funcionando bien. Continúa monitoreando las predicciones",
span: 2
}
]
}
];
// Actions for the modal - removed console.log placeholders for production readiness
const actions = [
{
label: 'Actualizar Modelo',
variant: 'primary' as const,
onClick: () => {
// TODO: Implement model retraining functionality
// This should trigger a new training job for the product
}
},
{
label: 'Ver Predicciones',
variant: 'secondary' as const,
onClick: () => {
// TODO: Navigate to forecast history or predictions view
// This should show historical predictions vs actual sales
}
}
];
// Only show deactivate if model is active
if ((model as any).is_active) {
actions.push({
label: 'Desactivar',
variant: 'secondary' as const,
onClick: () => {
// TODO: Implement model deactivation
// This should set model status to inactive
}
});
}
return (
);
};
export default ModelDetailsModal;