252 lines
9.6 KiB
TypeScript
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; |