Refactor components and modals

This commit is contained in:
Urtzi Alfaro
2025-09-26 07:46:25 +02:00
parent cf4405b771
commit d573c38621
80 changed files with 3421 additions and 4617 deletions

View File

@@ -1,7 +1,7 @@
import React, { useState, useMemo } from 'react';
import { Plus, AlertTriangle, Package, CheckCircle, Eye, Clock, Euro, ArrowRight, Minus, Edit, Trash2, Archive, TrendingUp, History } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor } from '../../../../components/ui';
import { LoadingSpinner } from '../../../../components/shared';
import { LoadingSpinner } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { PageHeader } from '../../../../components/layout';
import {

View File

@@ -3,10 +3,10 @@ import { useTranslation } from 'react-i18next';
import { Plus, AlertTriangle, Settings, CheckCircle, Eye, Wrench, Thermometer, Activity, Search, Filter, Bell, History, Calendar, Edit, Trash2 } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor } from '../../../../components/ui';
import { Badge } from '../../../../components/ui/Badge';
import { LoadingSpinner } from '../../../../components/shared';
import { LoadingSpinner } from '../../../../components/ui';
import { PageHeader } from '../../../../components/layout';
import { useCurrentTenant } from '../../../../stores/tenant.store';
import { Equipment } from '../../../../types/equipment';
import { Equipment } from '../../../../api/types/equipment';
import { EquipmentModal } from '../../../../components/domain/equipment/EquipmentModal';
const MOCK_EQUIPMENT: Equipment[] = [

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Plus, Clock, Package, Eye, Edit, CheckCircle, AlertCircle, Timer, Users, Loader, Euro } from 'lucide-react';
import { Button, Input, Card, Badge, StatsGrid, StatusCard, getStatusColor, StatusModal, Tabs } from '../../../../components/ui';
import { Button, Input, Card, Badge, StatsGrid, StatusCard, getStatusColor, EditViewModal, Tabs } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { PageHeader } from '../../../../components/layout';
import {
@@ -23,7 +23,7 @@ import { useOrders, useCustomers, useOrdersDashboard, useCreateOrder, useCreateC
import { useCurrentTenant } from '../../../../stores/tenant.store';
import { useAuthUser } from '../../../../stores/auth.store';
import { OrderFormModal } from '../../../../components/domain/orders';
import { useOrderEnums } from '../../../../utils/enumHelpers';
import { useTranslation } from 'react-i18next';
const OrdersPage: React.FC = () => {
const [activeTab, setActiveTab] = useState<'orders' | 'customers'>('orders');
@@ -40,7 +40,7 @@ const OrdersPage: React.FC = () => {
const currentTenant = useCurrentTenant();
const user = useAuthUser();
const tenantId = currentTenant?.id || user?.tenant_id || '';
const orderEnums = useOrderEnums();
const { t } = useTranslation(['orders', 'common']);
// API hooks for orders
const {
@@ -364,7 +364,7 @@ const OrdersPage: React.FC = () => {
`Entrega: ${order.requested_delivery_date ?
new Date(order.requested_delivery_date).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit' }) :
'Sin fecha'}`,
`${orderEnums.getDeliveryMethodLabel(order.delivery_method)}`,
`${t(`orders:delivery_methods.${order.delivery_method.toLowerCase()}`)}`,
...(paymentNote ? [paymentNote] : [])
]}
actions={[
@@ -405,7 +405,7 @@ const OrdersPage: React.FC = () => {
id={customer.id}
statusIndicator={statusConfig}
title={customer.name}
subtitle={orderEnums.getCustomerTypeLabel(customer.customer_type)}
subtitle={t(`orders:customer_types.${customer.customer_type.toLowerCase()}`)}
primaryValue={customer.total_orders}
primaryValueLabel="pedidos"
secondaryInfo={{
@@ -519,21 +519,30 @@ const OrdersPage: React.FC = () => {
value: selectedOrder.order_type || OrderType.STANDARD,
type: 'select',
editable: true,
options: orderEnums.getOrderTypeOptions()
options: Object.values(OrderType).map(value => ({
value,
label: t(`orders:order_types.${value.toLowerCase()}`)
}))
},
{
label: 'Prioridad',
value: selectedOrder.priority || PriorityLevel.NORMAL,
type: 'select',
editable: true,
options: orderEnums.getPriorityLevelOptions()
options: Object.values(PriorityLevel).map(value => ({
value,
label: t(`orders:priority_levels.${value.toLowerCase()}`)
}))
},
{
label: 'Método de Entrega',
value: selectedOrder.delivery_method || DeliveryMethod.PICKUP,
type: 'select',
editable: true,
options: orderEnums.getDeliveryMethodOptions()
options: Object.values(DeliveryMethod).map(value => ({
value,
label: t(`orders:delivery_methods.${value.toLowerCase()}`)
}))
},
{
label: 'Fecha del Pedido',
@@ -590,7 +599,10 @@ const OrdersPage: React.FC = () => {
value: selectedOrder.payment_status || PaymentStatus.PENDING,
type: 'select',
editable: true,
options: orderEnums.getPaymentStatusOptions()
options: Object.values(PaymentStatus).map(value => ({
value,
label: t(`orders:payment_status.${value.toLowerCase()}`)
}))
}
]
},
@@ -609,7 +621,7 @@ const OrdersPage: React.FC = () => {
];
return (
<StatusModal
<EditViewModal
isOpen={showForm}
onClose={() => {
setShowForm(false);
@@ -680,7 +692,10 @@ const OrdersPage: React.FC = () => {
value: selectedCustomer.customer_type || CustomerType.INDIVIDUAL,
type: 'select',
editable: true,
options: orderEnums.getCustomerTypeOptions()
options: Object.values(CustomerType).map(value => ({
value,
label: t(`orders:customer_types.${value.toLowerCase()}`)
}))
},
{
label: 'Email',
@@ -718,14 +733,20 @@ const OrdersPage: React.FC = () => {
value: selectedCustomer.preferred_delivery_method || DeliveryMethod.PICKUP,
type: 'select',
editable: true,
options: orderEnums.getDeliveryMethodOptions()
options: Object.values(DeliveryMethod).map(value => ({
value,
label: t(`orders:delivery_methods.${value.toLowerCase()}`)
}))
},
{
label: 'Términos de Pago',
value: selectedCustomer.payment_terms || PaymentTerms.IMMEDIATE,
type: 'select',
editable: true,
options: orderEnums.getPaymentTermsOptions()
options: Object.values(PaymentTerms).map(value => ({
value,
label: t(`orders:payment_terms.${value.toLowerCase()}`)
}))
},
{
label: 'Descuento (%)',
@@ -738,7 +759,10 @@ const OrdersPage: React.FC = () => {
value: selectedCustomer.customer_segment || CustomerSegment.REGULAR,
type: 'select',
editable: true,
options: orderEnums.getCustomerSegmentOptions()
options: Object.values(CustomerSegment).map(value => ({
value,
label: t(`orders:customer_segments.${value.toLowerCase()}`)
}))
},
{
label: 'Estado',
@@ -763,7 +787,7 @@ const OrdersPage: React.FC = () => {
];
return (
<StatusModal
<EditViewModal
isOpen={showForm}
onClose={() => {
setShowForm(false);

View File

@@ -2,7 +2,7 @@ import React, { useState, useMemo } from 'react';
import { Plus, Minus, ShoppingCart, CreditCard, Banknote, Calculator, User, Receipt, Package, Euro, TrendingUp, Clock, ToggleLeft, ToggleRight, Settings, Zap, Wifi, WifiOff, AlertCircle, CheckCircle, Loader, Eye, EyeOff, Info, Trash2 } from 'lucide-react';
import { Button, Input, Card, Badge, StatsGrid, StatusCard, getStatusColor, Tabs, Modal, Select } from '../../../../components/ui';
import { PageHeader } from '../../../../components/layout';
import { LoadingSpinner } from '../../../../components/shared';
import { LoadingSpinner } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { useIngredients } from '../../../../api/hooks/inventory';
import { useTenantId } from '../../../../hooks/useTenantId';

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { Plus, ShoppingCart, Truck, Euro, Calendar, Clock, CheckCircle, AlertCircle, Package, Eye, Loader, Edit, ArrowRight, X, Save, Building2, Play, Zap, User } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, EditViewModal } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { PageHeader } from '../../../../components/layout';
import { CreatePurchaseOrderModal } from '../../../../components/domain/procurement/CreatePurchaseOrderModal';
@@ -722,7 +722,7 @@ const ProcurementPage: React.FC = () => {
{/* Procurement Plan Modal */}
{showForm && selectedPlan && (
<StatusModal
<EditViewModal
isOpen={showForm}
onClose={() => {
setShowForm(false);

View File

@@ -1,9 +1,9 @@
import React, { useState, useMemo } from 'react';
import { Plus, Clock, AlertCircle, CheckCircle, Timer, ChefHat, Eye, Edit, Package, Zap, User, PlusCircle } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusModal, Toggle } from '../../../../components/ui';
import { Button, Input, Card, StatsGrid, EditViewModal, Toggle } from '../../../../components/ui';
import { statusColors } from '../../../../styles/colors';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { LoadingSpinner } from '../../../../components/shared';
import { LoadingSpinner } from '../../../../components/ui';
import { PageHeader } from '../../../../components/layout';
import { ProductionSchedule, CreateProductionBatchModal, ProductionStatusCard, QualityCheckModal, CompactProcessStageTracker } from '../../../../components/domain/production';
import { useCurrentTenant } from '../../../../stores/tenant.store';
@@ -23,7 +23,7 @@ import {
ProductionStatusEnum,
ProductionPriorityEnum
} from '../../../../api';
import { useProductionEnums } from '../../../../utils/enumHelpers';
import { useTranslation } from 'react-i18next';
import { ProcessStage } from '../../../../api/types/qualityTemplates';
const ProductionPage: React.FC = () => {
@@ -37,7 +37,7 @@ const ProductionPage: React.FC = () => {
const currentTenant = useCurrentTenant();
const tenantId = currentTenant?.id || '';
const productionEnums = useProductionEnums();
const { t } = useTranslation(['production', 'common']);
// API Data
const {
@@ -471,7 +471,7 @@ const ProductionPage: React.FC = () => {
{/* Production Batch Modal */}
{showBatchModal && selectedBatch && (
<StatusModal
<EditViewModal
isOpen={showBatchModal}
onClose={() => {
setShowBatchModal(false);
@@ -484,7 +484,7 @@ const ProductionPage: React.FC = () => {
subtitle={`Lote de Producción #${selectedBatch.batch_number}`}
statusIndicator={{
color: statusColors.inProgress.primary,
text: productionEnums.getProductionStatusLabel(selectedBatch.status),
text: t(`production:status.${selectedBatch.status.toLowerCase()}`),
icon: Package
}}
size="lg"
@@ -511,14 +511,20 @@ const ProductionPage: React.FC = () => {
value: selectedBatch.priority,
type: 'select',
editable: modalMode === 'edit',
options: productionEnums.getProductionPriorityOptions()
options: Object.values(ProductionPriorityEnum).map(value => ({
value,
label: t(`production:priority.${value.toLowerCase()}`)
}))
},
{
label: 'Estado',
value: selectedBatch.status,
type: 'select',
editable: modalMode === 'edit',
options: productionEnums.getProductionStatusOptions()
options: Object.values(ProductionStatusEnum).map(value => ({
value,
label: t(`production:status.${value.toLowerCase()}`)
}))
},
{
label: 'Personal Asignado',

View File

@@ -1,7 +1,7 @@
import React, { useState, useMemo } from 'react';
import { Plus, Star, Clock, Euro, Package, Eye, Edit, ChefHat, Timer, CheckCircle } from 'lucide-react';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, StatusModal } from '../../../../components/ui';
import { LoadingSpinner } from '../../../../components/shared';
import { Button, Input, Card, StatsGrid, StatusCard, getStatusColor, EditViewModal } from '../../../../components/ui';
import { LoadingSpinner } from '../../../../components/ui';
import { formatters } from '../../../../components/ui/Stats/StatsPresets';
import { PageHeader } from '../../../../components/layout';
import { useRecipes, useRecipeStatistics, useCreateRecipe, useUpdateRecipe, useDeleteRecipe } from '../../../../api/hooks/recipes';
@@ -549,7 +549,7 @@ const RecipesPage: React.FC = () => {
{/* Recipe Details Modal */}
{showForm && selectedRecipe && (
<StatusModal
<EditViewModal
isOpen={showForm}
onClose={() => {
setShowForm(false);

View File

@@ -1,13 +1,13 @@
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 { Button, Input, Card, Badge, StatsGrid, StatusCard, getStatusColor, EditViewModal } 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';
import { useTranslation } from 'react-i18next';
const SuppliersPage: React.FC = () => {
const [activeTab] = useState('all');
@@ -40,15 +40,15 @@ const SuppliersPage: React.FC = () => {
} = useSupplierStatistics(tenantId);
const suppliers = suppliersData || [];
const supplierEnums = useSupplierEnums();
const { t } = useTranslation(['suppliers', 'common']);
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 },
[SupplierStatus.ACTIVE]: { text: t(`suppliers:status.${status.toLowerCase()}`), icon: CheckCircle },
[SupplierStatus.INACTIVE]: { text: t(`suppliers:status.${status.toLowerCase()}`), icon: Timer },
[SupplierStatus.PENDING_APPROVAL]: { text: t(`suppliers:status.${status.toLowerCase()}`), icon: AlertCircle },
[SupplierStatus.SUSPENDED]: { text: t(`suppliers:status.${status.toLowerCase()}`), icon: AlertCircle },
[SupplierStatus.BLACKLISTED]: { text: t(`suppliers:status.${status.toLowerCase()}`), icon: AlertCircle },
};
const config = statusConfig[status];
@@ -65,11 +65,11 @@ const SuppliersPage: React.FC = () => {
};
const getSupplierTypeText = (type: SupplierType): string => {
return supplierEnums.getSupplierTypeLabel(type);
return t(`suppliers:types.${type.toLowerCase()}`);
};
const getPaymentTermsText = (terms: PaymentTerms): string => {
return supplierEnums.getPaymentTermsLabel(terms);
return t(`suppliers:payment_terms.${terms.toLowerCase()}`);
};
// Filtering is now handled by the API query parameters
@@ -348,14 +348,20 @@ const SuppliersPage: React.FC = () => {
value: selectedSupplier.supplier_type || SupplierType.INGREDIENTS,
type: 'select',
editable: true,
options: supplierEnums.getSupplierTypeOptions()
options: Object.values(SupplierType).map(value => ({
value,
label: t(`suppliers:types.${value.toLowerCase()}`)
}))
},
{
label: 'Condiciones de Pago',
value: selectedSupplier.payment_terms || PaymentTerms.NET_30,
type: 'select',
editable: true,
options: supplierEnums.getPaymentTermsOptions()
options: Object.values(PaymentTerms).map(value => ({
value,
label: t(`suppliers:payment_terms.${value.toLowerCase()}`)
}))
},
{
label: 'Tiempo de Entrega (días)',
@@ -420,7 +426,7 @@ const SuppliersPage: React.FC = () => {
];
return (
<StatusModal
<EditViewModal
isOpen={showForm}
onClose={() => {
setShowForm(false);