import React, { useState } from 'react'; import { Plus, Building2, Phone, Mail, Eye, Edit, CheckCircle, AlertCircle, Timer, Users, Euro, Loader } from 'lucide-react'; import { Button, Input, Card, Badge, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui'; import { formatters } from '../../../../components/ui/Stats/StatsPresets'; import { PageHeader } from '../../../../components/layout'; import { SupplierStatus, SupplierType, PaymentTerms } from '../../../../api/types/suppliers'; import { useSuppliers, useSupplierStatistics } from '../../../../api/hooks/suppliers'; import { useCurrentTenant } from '../../../../stores/tenant.store'; import { useAuthUser } from '../../../../stores/auth.store'; import { useSupplierEnums } from '../../../../utils/enumHelpers'; const SuppliersPage: React.FC = () => { const [activeTab] = useState('all'); const [searchTerm, setSearchTerm] = useState(''); const [showForm, setShowForm] = useState(false); const [modalMode, setModalMode] = useState<'view' | 'edit'>('view'); const [selectedSupplier, setSelectedSupplier] = useState(null); const [isCreating, setIsCreating] = useState(false); // Get tenant ID from tenant store (preferred) or auth user (fallback) const currentTenant = useCurrentTenant(); const user = useAuthUser(); const tenantId = currentTenant?.id || user?.tenant_id || ''; // API hooks const { data: suppliersData, isLoading: suppliersLoading, error: suppliersError } = useSuppliers(tenantId, { search_term: searchTerm || undefined, status: activeTab !== 'all' ? activeTab as any : undefined, limit: 100 }); const { data: statisticsData, isLoading: statisticsLoading, error: statisticsError } = useSupplierStatistics(tenantId); const suppliers = suppliersData || []; const supplierEnums = useSupplierEnums(); const getSupplierStatusConfig = (status: SupplierStatus) => { const statusConfig = { [SupplierStatus.ACTIVE]: { text: supplierEnums.getSupplierStatusLabel(status), icon: CheckCircle }, [SupplierStatus.INACTIVE]: { text: supplierEnums.getSupplierStatusLabel(status), icon: Timer }, [SupplierStatus.PENDING_APPROVAL]: { text: supplierEnums.getSupplierStatusLabel(status), icon: AlertCircle }, [SupplierStatus.SUSPENDED]: { text: supplierEnums.getSupplierStatusLabel(status), icon: AlertCircle }, [SupplierStatus.BLACKLISTED]: { text: supplierEnums.getSupplierStatusLabel(status), icon: AlertCircle }, }; const config = statusConfig[status]; const Icon = config?.icon; return { color: getStatusColor(status === SupplierStatus.ACTIVE ? 'completed' : status === SupplierStatus.PENDING_APPROVAL ? 'pending' : 'cancelled'), text: config?.text || status, icon: Icon, isCritical: status === SupplierStatus.BLACKLISTED, isHighlight: status === SupplierStatus.PENDING_APPROVAL }; }; const getSupplierTypeText = (type: SupplierType): string => { return supplierEnums.getSupplierTypeLabel(type); }; const getPaymentTermsText = (terms: PaymentTerms): string => { return supplierEnums.getPaymentTermsLabel(terms); }; // Filtering is now handled by the API query parameters const filteredSuppliers = suppliers; const supplierStats = statisticsData || { total_suppliers: 0, active_suppliers: 0, pending_suppliers: 0, avg_quality_rating: 0, avg_delivery_rating: 0, total_spend: 0 }; const stats = [ { title: 'Total Proveedores', value: supplierStats.total_suppliers, variant: 'default' as const, icon: Building2, }, { title: 'Activos', value: supplierStats.active_suppliers, variant: 'success' as const, icon: CheckCircle, }, { title: 'Pendientes', value: supplierStats.pending_suppliers, variant: 'warning' as const, icon: AlertCircle, }, { title: 'Gasto Total', value: formatters.currency(supplierStats.total_spend), variant: 'info' as const, icon: Euro, }, { title: 'Calidad Media', value: supplierStats.avg_quality_rating?.toFixed(1) || '0.0', variant: 'success' as const, icon: CheckCircle, }, { title: 'Entrega Media', value: supplierStats.avg_delivery_rating?.toFixed(1) || '0.0', variant: 'info' as const, icon: Building2, }, ]; // Loading state if (suppliersLoading || statisticsLoading) { return (

Cargando proveedores...

); } // Error state if (suppliersError || statisticsError) { return (

Error al cargar los proveedores

{(suppliersError as any)?.message || (statisticsError as any)?.message || 'Error desconocido'}

); } return (
{ setSelectedSupplier({ name: '', contact_person: '', email: '', phone: '', city: '', country: '', supplier_code: '', supplier_type: SupplierType.INGREDIENTS, payment_terms: PaymentTerms.NET_30, standard_lead_time: 3, minimum_order_amount: 0, credit_limit: 0, currency: 'EUR' }); setIsCreating(true); setModalMode('edit'); setShowForm(true); } } ]} /> {/* Stats Grid */} {/* Simplified Controls */}
setSearchTerm(e.target.value)} className="w-full" />
{/* Suppliers Grid */}
{filteredSuppliers.map((supplier) => { const statusConfig = getSupplierStatusConfig(supplier.status); return ( { setSelectedSupplier(supplier); setIsCreating(false); setModalMode('view'); setShowForm(true); } }, // Secondary action - Edit supplier { label: 'Editar', icon: Edit, priority: 'secondary', onClick: () => { setSelectedSupplier(supplier); setIsCreating(false); setModalMode('edit'); setShowForm(true); } } ]} /> ); })}
{/* Empty State */} {filteredSuppliers.length === 0 && (

No se encontraron proveedores

Intenta ajustar la búsqueda o crear un nuevo proveedor

)} {/* Supplier Details Modal */} {showForm && selectedSupplier && (() => { const sections = [ { title: 'Información de Contacto', icon: Users, fields: [ { label: 'Nombre', value: selectedSupplier.name || '', type: 'text', highlight: true, editable: true, required: true, placeholder: 'Nombre del proveedor' }, { label: 'Persona de Contacto', value: selectedSupplier.contact_person || '', type: 'text', editable: true, placeholder: 'Nombre del contacto' }, { label: 'Email', value: selectedSupplier.email || '', type: 'email', editable: true, placeholder: 'email@ejemplo.com' }, { label: 'Teléfono', value: selectedSupplier.phone || '', type: 'tel', editable: true, placeholder: '+34 123 456 789' }, { label: 'Ciudad', value: selectedSupplier.city || '', type: 'text', editable: true, placeholder: 'Ciudad' }, { label: 'País', value: selectedSupplier.country || '', type: 'text', editable: true, placeholder: 'País' } ] }, { title: 'Información Comercial', icon: Building2, fields: [ { label: 'Código de Proveedor', value: selectedSupplier.supplier_code || '', type: 'text', highlight: true, editable: true, placeholder: 'Código único' }, { label: 'Tipo de Proveedor', value: selectedSupplier.supplier_type || SupplierType.INGREDIENTS, type: 'select', editable: true, options: supplierEnums.getSupplierTypeOptions() }, { label: 'Condiciones de Pago', value: selectedSupplier.payment_terms || PaymentTerms.NET_30, type: 'select', editable: true, options: supplierEnums.getPaymentTermsOptions() }, { label: 'Tiempo de Entrega (días)', value: selectedSupplier.standard_lead_time || 3, type: 'number', editable: true, placeholder: '3' }, { label: 'Pedido Mínimo', value: selectedSupplier.minimum_order_amount || 0, type: 'currency', editable: true, placeholder: '0.00' }, { label: 'Límite de Crédito', value: selectedSupplier.credit_limit || 0, type: 'currency', editable: true, placeholder: '0.00' } ] }, { title: 'Rendimiento y Estadísticas', icon: Euro, fields: [ { label: 'Moneda', value: selectedSupplier.currency || 'EUR', type: 'text', editable: true, placeholder: 'EUR' }, { label: 'Fecha de Creación', value: selectedSupplier.created_at, type: 'datetime', highlight: true }, { label: 'Última Actualización', value: selectedSupplier.updated_at, type: 'datetime' } ] }, ...(selectedSupplier.notes ? [{ title: 'Notas', fields: [ { label: 'Observaciones', value: selectedSupplier.notes, type: 'list', span: 2 as const, editable: true, placeholder: 'Notas sobre el proveedor' } ] }] : []) ]; return ( { setShowForm(false); setSelectedSupplier(null); setModalMode('view'); setIsCreating(false); }} mode={modalMode} onModeChange={setModalMode} title={isCreating ? 'Nuevo Proveedor' : selectedSupplier.name || 'Proveedor'} subtitle={isCreating ? 'Crear nuevo proveedor' : `Proveedor ${selectedSupplier.supplier_code || ''}`} statusIndicator={isCreating ? undefined : getSupplierStatusConfig(selectedSupplier.status)} size="lg" sections={sections} showDefaultActions={true} onSave={async () => { // TODO: Implement save functionality console.log('Saving supplier:', selectedSupplier); }} onFieldChange={(sectionIndex, fieldIndex, value) => { // Update the selectedSupplier state when fields change const newSupplier = { ...selectedSupplier }; const section = sections[sectionIndex]; const field = section.fields[fieldIndex]; // Map field labels to supplier properties const fieldMapping: { [key: string]: string } = { 'Nombre': 'name', 'Persona de Contacto': 'contact_person', 'Email': 'email', 'Teléfono': 'phone', 'Ciudad': 'city', 'País': 'country', 'Código de Proveedor': 'supplier_code', 'Tipo de Proveedor': 'supplier_type', 'Condiciones de Pago': 'payment_terms', 'Tiempo de Entrega (días)': 'standard_lead_time', 'Pedido Mínimo': 'minimum_order_amount', 'Límite de Crédito': 'credit_limit', 'Moneda': 'currency', 'Observaciones': 'notes' }; const propertyName = fieldMapping[field.label]; if (propertyName) { newSupplier[propertyName] = value; setSelectedSupplier(newSupplier); } }} /> ); })()}
); }; export default SuppliersPage;