Files
bakery-ia/frontend/src/pages/app/analytics/ProductionAnalyticsPage.tsx
2025-09-23 19:24:22 +02:00

252 lines
9.6 KiB
TypeScript

import React, { useState } from 'react';
import { TrendingUp, DollarSign, Activity, AlertTriangle, Settings } from 'lucide-react';
import { Card, StatsGrid, Button } from '../../../components/ui';
import { PageHeader } from '../../../components/layout';
import { QualityDashboard, EquipmentManager } from '../../../components/domain/production';
// Production Cost Monitor Component (placeholder)
const ProductionCostMonitor: React.FC = () => {
return (
<Card className="p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Monitor de Costos de Producción</h3>
<DollarSign className="w-5 h-5 text-[var(--color-primary)]" />
</div>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div className="p-4 bg-[var(--surface-secondary)] rounded-lg">
<p className="text-sm text-[var(--text-secondary)]">Costo por unidad</p>
<p className="text-2xl font-bold text-[var(--text-primary)]">2.45</p>
<p className="text-xs text-green-600">-8% vs mes anterior</p>
</div>
<div className="p-4 bg-[var(--surface-secondary)] rounded-lg">
<p className="text-sm text-[var(--text-secondary)]">Eficiencia de costos</p>
<p className="text-2xl font-bold text-[var(--text-primary)]">92%</p>
<p className="text-xs text-green-600">+3% vs objetivo</p>
</div>
</div>
<div className="h-64 bg-[var(--surface-secondary)] rounded-lg flex items-center justify-center">
<p className="text-[var(--text-secondary)]">Gráfico de tendencias de costos</p>
</div>
</div>
</Card>
);
};
// AI Insights Component (placeholder)
const AIInsights: React.FC = () => {
return (
<Card className="p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Insights de IA</h3>
<Activity className="w-5 h-5 text-[var(--color-primary)]" />
</div>
<div className="space-y-4">
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
<div className="flex items-start gap-3">
<TrendingUp className="w-5 h-5 text-blue-600 mt-0.5" />
<div>
<h4 className="font-medium text-blue-900">Optimización de Producción</h4>
<p className="text-sm text-blue-700">Se detectó que producir croissants los martes reduce costos en 15%</p>
</div>
</div>
</div>
<div className="p-4 bg-amber-50 border border-amber-200 rounded-lg">
<div className="flex items-start gap-3">
<AlertTriangle className="w-5 h-5 text-amber-600 mt-0.5" />
<div>
<h4 className="font-medium text-amber-900">Predicción de Demanda</h4>
<p className="text-sm text-amber-700">Aumento del 25% en demanda de pan integral previsto para el fin de semana</p>
</div>
</div>
</div>
</div>
</Card>
);
};
// Equipment Status Component (placeholder)
const EquipmentStatus: React.FC = () => {
return (
<Card className="p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Estado de Equipos</h3>
<Settings className="w-5 h-5 text-[var(--color-primary)]" />
</div>
<div className="space-y-3">
<div className="flex items-center justify-between p-3 bg-green-50 border border-green-200 rounded-lg">
<div>
<p className="font-medium text-green-900">Horno Principal</p>
<p className="text-sm text-green-700">Funcionando óptimamente</p>
</div>
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div className="flex items-center justify-between p-3 bg-yellow-50 border border-yellow-200 rounded-lg">
<div>
<p className="font-medium text-yellow-900">Mezcladora #2</p>
<p className="text-sm text-yellow-700">Mantenimiento requerido en 3 días</p>
</div>
<div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
</div>
<div className="flex items-center justify-between p-3 bg-green-50 border border-green-200 rounded-lg">
<div>
<p className="font-medium text-green-900">Refrigerador</p>
<p className="text-sm text-green-700">Temperatura estable</p>
</div>
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
</div>
</Card>
);
};
const ProductionAnalyticsPage: React.FC = () => {
const [activeTab, setActiveTab] = useState('overview');
return (
<div className="space-y-6">
<PageHeader
title="Análisis de Producción"
description="Análisis avanzado y insights para profesionales y empresas"
/>
{/* Key Metrics */}
<StatsGrid
stats={[
{
title: 'Eficiencia General',
value: '94%',
variant: 'success' as const,
icon: TrendingUp,
},
{
title: 'Costo Promedio',
value: '€2.45',
variant: 'info' as const,
icon: DollarSign,
},
{
title: 'Equipos Activos',
value: '8/9',
variant: 'warning' as const,
icon: Settings,
},
{
title: 'Calidad Promedio',
value: '9.2/10',
variant: 'success' as const,
icon: Activity,
}
]}
columns={4}
/>
{/* Tabs Navigation */}
<div className="border-b border-[var(--border-primary)]">
<nav className="-mb-px flex space-x-8">
<button
onClick={() => setActiveTab('overview')}
className={`py-2 px-1 border-b-2 font-medium text-sm ${
activeTab === 'overview'
? 'border-orange-500 text-[var(--color-primary)]'
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
}`}
>
Resumen
</button>
<button
onClick={() => setActiveTab('costs')}
className={`py-2 px-1 border-b-2 font-medium text-sm ${
activeTab === 'costs'
? 'border-orange-500 text-[var(--color-primary)]'
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
}`}
>
Costos
</button>
<button
onClick={() => setActiveTab('ai-insights')}
className={`py-2 px-1 border-b-2 font-medium text-sm ${
activeTab === 'ai-insights'
? 'border-orange-500 text-[var(--color-primary)]'
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
}`}
>
IA Insights
</button>
<button
onClick={() => setActiveTab('equipment')}
className={`py-2 px-1 border-b-2 font-medium text-sm ${
activeTab === 'equipment'
? 'border-orange-500 text-[var(--color-primary)]'
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
}`}
>
Equipos
</button>
<button
onClick={() => setActiveTab('quality')}
className={`py-2 px-1 border-b-2 font-medium text-sm ${
activeTab === 'quality'
? 'border-orange-500 text-[var(--color-primary)]'
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
}`}
>
Calidad
</button>
</nav>
</div>
{/* Tab Content */}
{activeTab === 'overview' && (
<div className="grid gap-6 lg:grid-cols-2">
<ProductionCostMonitor />
<AIInsights />
<EquipmentStatus />
<Card className="p-6">
<h3 className="text-lg font-semibold text-[var(--text-primary)] mb-4">Resumen de Calidad</h3>
<div className="space-y-3">
<div className="flex justify-between">
<span className="text-[var(--text-secondary)]">Productos aprobados</span>
<span className="font-medium">96%</span>
</div>
<div className="flex justify-between">
<span className="text-[var(--text-secondary)]">Rechazos por calidad</span>
<span className="font-medium">2%</span>
</div>
<div className="flex justify-between">
<span className="text-[var(--text-secondary)]">Reprocesos</span>
<span className="font-medium">2%</span>
</div>
</div>
</Card>
</div>
)}
{activeTab === 'costs' && (
<div className="grid gap-6">
<ProductionCostMonitor />
</div>
)}
{activeTab === 'ai-insights' && (
<div className="grid gap-6">
<AIInsights />
</div>
)}
{activeTab === 'equipment' && (
<div className="grid gap-6">
<EquipmentStatus />
<EquipmentManager />
</div>
)}
{activeTab === 'quality' && (
<QualityDashboard />
)}
</div>
);
};
export default ProductionAnalyticsPage;