Add improved production UI
This commit is contained in:
@@ -8,6 +8,9 @@ import StatsGrid from '../../components/ui/Stats/StatsGrid';
|
||||
import RealTimeAlerts from '../../components/domain/dashboard/RealTimeAlerts';
|
||||
import ProcurementPlansToday from '../../components/domain/dashboard/ProcurementPlansToday';
|
||||
import ProductionPlansToday from '../../components/domain/dashboard/ProductionPlansToday';
|
||||
import ProductionCostMonitor from '../../components/domain/dashboard/ProductionCostMonitor';
|
||||
import EquipmentStatusWidget from '../../components/domain/dashboard/EquipmentStatusWidget';
|
||||
import AIInsightsWidget from '../../components/domain/dashboard/AIInsightsWidget';
|
||||
import { useTenant } from '../../stores/tenant.store';
|
||||
import {
|
||||
AlertTriangle,
|
||||
@@ -170,6 +173,15 @@ const DashboardPage: React.FC = () => {
|
||||
onViewDetails={handleViewDetails}
|
||||
onViewAllPlans={handleViewAllPlans}
|
||||
/>
|
||||
|
||||
{/* 4. Production Cost Monitor */}
|
||||
<ProductionCostMonitor />
|
||||
|
||||
{/* 5. Equipment Status Widget */}
|
||||
<EquipmentStatusWidget />
|
||||
|
||||
{/* 6. AI Insights Widget */}
|
||||
<AIInsightsWidget />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Plus, ShoppingCart, Truck, Euro, Calendar, Clock, CheckCircle, AlertCir
|
||||
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
|
||||
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
|
||||
import { PageHeader } from '../../../../components/layout';
|
||||
import { CreatePurchaseOrderModal } from '../../../../components/domain/procurement/CreatePurchaseOrderModal';
|
||||
import {
|
||||
useProcurementDashboard,
|
||||
useProcurementPlans,
|
||||
@@ -25,6 +26,8 @@ const ProcurementPage: React.FC = () => {
|
||||
const [showGeneratePlanModal, setShowGeneratePlanModal] = useState(false);
|
||||
const [showRequirementDetailsModal, setShowRequirementDetailsModal] = useState(false);
|
||||
const [selectedRequirement, setSelectedRequirement] = useState<any>(null);
|
||||
const [showCreatePurchaseOrderModal, setShowCreatePurchaseOrderModal] = useState(false);
|
||||
const [selectedRequirementsForPO, setSelectedRequirementsForPO] = useState<any[]>([]);
|
||||
const [generatePlanForm, setGeneratePlanForm] = useState({
|
||||
plan_date: new Date().toISOString().split('T')[0],
|
||||
planning_horizon_days: 14,
|
||||
@@ -255,11 +258,16 @@ const ProcurementPage: React.FC = () => {
|
||||
description="Administra planes de compras, requerimientos y análisis de procurement"
|
||||
actions={[
|
||||
{
|
||||
id: "generate",
|
||||
label: "Generar Plan",
|
||||
id: "create-po",
|
||||
label: "Crear Orden de Compra",
|
||||
variant: "primary" as const,
|
||||
icon: Plus,
|
||||
onClick: () => setShowGeneratePlanModal(true)
|
||||
onClick: () => {
|
||||
// Open the purchase order modal with empty requirements
|
||||
// This allows manual creation of purchase orders without procurement plans
|
||||
setSelectedRequirementsForPO([]);
|
||||
setShowCreatePurchaseOrderModal(true);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "trigger",
|
||||
@@ -561,7 +569,21 @@ const ProcurementPage: React.FC = () => {
|
||||
<Loader className="w-8 h-8 animate-spin text-[var(--color-primary)]" />
|
||||
</div>
|
||||
) : planRequirements && planRequirements.length > 0 ? (
|
||||
<div className="grid gap-4">
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-end mb-4">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
// Set all requirements for PO creation
|
||||
setSelectedRequirementsForPO(planRequirements);
|
||||
setShowCreatePurchaseOrderModal(true);
|
||||
}}
|
||||
>
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Crear Orden de Compra para Todos
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{planRequirements.map((requirement) => (
|
||||
<StatusCard
|
||||
key={requirement.id}
|
||||
@@ -619,7 +641,9 @@ const ProcurementPage: React.FC = () => {
|
||||
variant: 'outline' as const,
|
||||
priority: 'secondary' as const,
|
||||
onClick: () => {
|
||||
// TODO: Create purchase order for requirement
|
||||
// Set the single requirement for PO creation
|
||||
setSelectedRequirementsForPO([requirement]);
|
||||
setShowCreatePurchaseOrderModal(true);
|
||||
}
|
||||
}
|
||||
]),
|
||||
@@ -954,6 +978,23 @@ const ProcurementPage: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Create Purchase Order Modal */}
|
||||
{showCreatePurchaseOrderModal && (
|
||||
<CreatePurchaseOrderModal
|
||||
isOpen={showCreatePurchaseOrderModal}
|
||||
onClose={() => {
|
||||
setShowCreatePurchaseOrderModal(false);
|
||||
setSelectedRequirementsForPO([]);
|
||||
}}
|
||||
requirements={selectedRequirementsForPO}
|
||||
onSuccess={() => {
|
||||
// Refresh the plan requirements data
|
||||
setSelectedRequirementsForPO([]);
|
||||
// You might want to invalidate queries here to refresh data
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Requirement Details Modal */}
|
||||
{showRequirementDetailsModal && selectedRequirement && (
|
||||
<div className="fixed top-[var(--header-height)] left-0 right-0 bottom-0 bg-black bg-opacity-50 flex items-center justify-center z-40">
|
||||
|
||||
@@ -5,7 +5,7 @@ import { statusColors } from '../../../../styles/colors';
|
||||
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
|
||||
import { LoadingSpinner } from '../../../../components/shared';
|
||||
import { PageHeader } from '../../../../components/layout';
|
||||
import { ProductionSchedule, BatchTracker, QualityControl, CreateProductionBatchModal } from '../../../../components/domain/production';
|
||||
import { ProductionSchedule, BatchTracker, QualityControl, QualityDashboard, QualityInspection, EquipmentManager, CreateProductionBatchModal } from '../../../../components/domain/production';
|
||||
import { useCurrentTenant } from '../../../../stores/tenant.store';
|
||||
import {
|
||||
useProductionDashboard,
|
||||
@@ -298,6 +298,36 @@ const ProductionPage: React.FC = () => {
|
||||
>
|
||||
Control de Calidad
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('quality-dashboard')}
|
||||
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
||||
activeTab === 'quality-dashboard'
|
||||
? 'border-orange-500 text-[var(--color-primary)]'
|
||||
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
|
||||
}`}
|
||||
>
|
||||
Dashboard Calidad
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('quality-inspection')}
|
||||
className={`py-2 px-1 border-b-2 font-medium text-sm ${
|
||||
activeTab === 'quality-inspection'
|
||||
? 'border-orange-500 text-[var(--color-primary)]'
|
||||
: 'border-transparent text-[var(--text-tertiary)] hover:text-[var(--text-secondary)] hover:border-[var(--border-secondary)]'
|
||||
}`}
|
||||
>
|
||||
Inspección
|
||||
</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>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -400,6 +430,18 @@ const ProductionPage: React.FC = () => {
|
||||
<QualityControl />
|
||||
)}
|
||||
|
||||
{activeTab === 'quality-dashboard' && (
|
||||
<QualityDashboard />
|
||||
)}
|
||||
|
||||
{activeTab === 'quality-inspection' && (
|
||||
<QualityInspection />
|
||||
)}
|
||||
|
||||
{activeTab === 'equipment' && (
|
||||
<EquipmentManager />
|
||||
)}
|
||||
|
||||
{/* Production Batch Modal */}
|
||||
{showBatchModal && selectedBatch && (
|
||||
<StatusModal
|
||||
|
||||
Reference in New Issue
Block a user