Add order page with real API calls

This commit is contained in:
Urtzi Alfaro
2025-09-19 11:44:38 +02:00
parent 447e2a5012
commit 105410c9d3
22 changed files with 2556 additions and 463 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Plus, Search, Download, ShoppingCart, Truck, DollarSign, Calendar, Clock, CheckCircle, AlertCircle, Package, Eye, Loader, Edit, ArrowRight, Play, Pause, X, Save } from 'lucide-react';
import { Plus, Search, Download, ShoppingCart, Truck, DollarSign, Calendar, Clock, CheckCircle, AlertCircle, Package, Eye, Loader, Edit, ArrowRight, Play, Pause, X, Save, Building2 } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { PageHeader } from '../../../../components/layout';
@@ -410,17 +410,22 @@ const ProcurementPage: React.FC = () => {
id={plan.plan_number}
statusIndicator={statusConfig}
title={`Plan ${plan.plan_number}`}
subtitle={new Date(plan.plan_date).toLocaleDateString('es-ES')}
primaryValue={formatters.currency(plan.total_estimated_cost)}
primaryValueLabel={`${plan.total_requirements} requerimientos`}
subtitle={`${new Date(plan.plan_date).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit', year: '2-digit' })} • ${plan.procurement_strategy}`}
primaryValue={plan.total_requirements}
primaryValueLabel="requerimientos"
secondaryInfo={{
label: 'Período',
value: `${new Date(plan.plan_period_start).toLocaleDateString('es-ES')} - ${new Date(plan.plan_period_end).toLocaleDateString('es-ES')}`
label: 'Presupuesto',
value: `${formatters.compact(plan.total_estimated_cost)}`
}}
progress={plan.planning_horizon_days ? {
label: `${plan.planning_horizon_days} días de horizonte`,
percentage: Math.min((plan.planning_horizon_days / 30) * 100, 100),
color: plan.planning_horizon_days > 14 ? '#10b981' : plan.planning_horizon_days > 7 ? '#f59e0b' : '#ef4444'
} : undefined}
metadata={[
`${plan.planning_horizon_days} días de horizonte`,
`Estrategia: ${plan.procurement_strategy}`,
...(plan.special_requirements ? [`"${plan.special_requirements}"`] : [])
`Período: ${new Date(plan.plan_period_start).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' })} - ${new Date(plan.plan_period_end).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' })}`,
`Creado: ${new Date(plan.created_at).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' })}`,
...(plan.special_requirements ? [`Req. especiales: ${plan.special_requirements}`] : [])
]}
actions={actions}
/>
@@ -541,24 +546,43 @@ const ProcurementPage: React.FC = () => {
isCritical: true
}}
title={requirement.product_name}
subtitle={requirement.requirement_number}
primaryValue={`${requirement.required_quantity} ${requirement.unit_of_measure}`}
primaryValueLabel="Cantidad requerida"
subtitle={`${requirement.requirement_number}${requirement.supplier_name || 'Sin proveedor'}`}
primaryValue={requirement.required_quantity}
primaryValueLabel={requirement.unit_of_measure}
secondaryInfo={{
label: 'Fecha límite',
value: new Date(requirement.required_by_date).toLocaleDateString('es-ES')
label: 'Límite',
value: new Date(requirement.required_by_date).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' })
}}
progress={requirement.current_stock_level && requirement.required_quantity ? {
label: `${Math.round((requirement.current_stock_level / requirement.required_quantity) * 100)}% cubierto`,
percentage: Math.min((requirement.current_stock_level / requirement.required_quantity) * 100, 100),
color: requirement.current_stock_level >= requirement.required_quantity ? '#10b981' : requirement.current_stock_level >= requirement.required_quantity * 0.5 ? '#f59e0b' : '#ef4444'
} : undefined}
metadata={[
`Stock actual: ${requirement.current_stock_level} ${requirement.unit_of_measure}`,
`Proveedor: ${requirement.supplier_name || 'No asignado'}`,
`Costo estimado: ${formatters.currency(requirement.estimated_total_cost || 0)}`
`Stock: ${requirement.current_stock_level || 0} ${requirement.unit_of_measure}`,
`Necesario: ${requirement.required_quantity - (requirement.current_stock_level || 0)} ${requirement.unit_of_measure}`,
`Costo: ${formatters.compact(requirement.estimated_total_cost || 0)}`,
`Días restantes: ${Math.ceil((new Date(requirement.required_by_date).getTime() - Date.now()) / (1000 * 60 * 60 * 24))}`
]}
actions={[
{
label: 'Ver Detalles',
icon: Eye,
variant: 'outline',
variant: 'primary',
priority: 'primary',
onClick: () => console.log('View requirement details')
},
{
label: 'Asignar Proveedor',
icon: Building2,
priority: 'secondary',
onClick: () => console.log('Assign supplier')
},
{
label: 'Comprar Ahora',
icon: ShoppingCart,
priority: 'secondary',
onClick: () => console.log('Purchase now')
}
]}
/>

View File

@@ -254,11 +254,11 @@ const RecipesPage: React.FC = () => {
statusIndicator={statusConfig}
title={recipe.name}
subtitle={`${statusConfig.text}${statusConfig.difficultyLabel}${statusConfig.isHighlight ? ' ★' + recipe.rating : ''}`}
primaryValue={formatters.currency(recipe.profit)}
primaryValueLabel="margen"
primaryValue={recipe.ingredients.length}
primaryValueLabel="ingredientes"
secondaryInfo={{
label: 'Precio de venta',
value: `${formatters.currency(recipe.price)} (costo: ${formatters.currency(recipe.cost)})`
label: 'Margen',
value: `${formatters.compact(recipe.profit)}`
}}
progress={{
label: 'Margen de beneficio',

View File

@@ -216,12 +216,12 @@ const SuppliersPage: React.FC = () => {
id={supplier.id}
statusIndicator={statusConfig}
title={supplier.name}
subtitle={supplier.supplier_code}
primaryValue={supplier.city || 'Sin ubicación'}
primaryValueLabel={getSupplierTypeText(supplier.supplier_type)}
subtitle={`${getSupplierTypeText(supplier.supplier_type)}${supplier.city || 'Sin ubicación'}`}
primaryValue={supplier.standard_lead_time || 0}
primaryValueLabel="días"
secondaryInfo={{
label: 'Condiciones',
value: getPaymentTermsText(supplier.payment_terms)
label: 'Pedido Min.',
value: `${formatters.compact(supplier.minimum_order_amount || 0)}`
}}
metadata={[
supplier.contact_person || 'Sin contacto',

View File

@@ -377,11 +377,11 @@ const TeamPage: React.FC = () => {
statusIndicator={getMemberStatusConfig(member)}
title={member.user?.full_name || member.user_full_name}
subtitle={member.user?.email || member.user_email}
primaryValue={member.is_active ? 'Activo' : 'Inactivo'}
primaryValueLabel="Estado"
primaryValue={Math.floor((Date.now() - new Date(member.joined_at).getTime()) / (1000 * 60 * 60 * 24))}
primaryValueLabel="días"
secondaryInfo={{
label: 'Se unió',
value: new Date(member.joined_at).toLocaleDateString('es-ES')
label: 'Estado',
value: member.is_active ? 'Activo' : 'Inactivo'
}}
metadata={[
`Email: ${member.user?.email || member.user_email}`,