Improve frontend 3
This commit is contained in:
@@ -3,6 +3,12 @@ import { Sparkles } from 'lucide-react';
|
||||
import { WizardModal, WizardStep } from '../../ui/WizardModal/WizardModal';
|
||||
import { ItemTypeSelector, ItemType } from './ItemTypeSelector';
|
||||
import { AnyWizardData } from './types';
|
||||
import { useTenant } from '../../../stores/tenant.store';
|
||||
import { useCreatePurchaseOrder } from '../../../api/hooks/purchase-orders';
|
||||
import { useCreateProductionBatch } from '../../../api/hooks/production';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import type { ProductionBatchCreate } from '../../../api/types/production';
|
||||
import { ProductionPriorityEnum } from '../../../api/types/production';
|
||||
|
||||
// Import specific wizards
|
||||
import { InventoryWizardSteps, ProductTypeStep, BasicInfoStep, StockConfigStep } from './wizards/InventoryWizard';
|
||||
@@ -14,6 +20,8 @@ import { CustomerOrderWizardSteps } from './wizards/CustomerOrderWizard';
|
||||
import { CustomerWizardSteps } from './wizards/CustomerWizard';
|
||||
import { TeamMemberWizardSteps } from './wizards/TeamMemberWizard';
|
||||
import { SalesEntryWizardSteps } from './wizards/SalesEntryWizard';
|
||||
import { PurchaseOrderWizardSteps } from './wizards/PurchaseOrderWizard';
|
||||
import { ProductionBatchWizardSteps } from './wizards/ProductionBatchWizard';
|
||||
|
||||
interface UnifiedAddWizardProps {
|
||||
isOpen: boolean;
|
||||
@@ -33,6 +41,14 @@ export const UnifiedAddWizard: React.FC<UnifiedAddWizardProps> = ({
|
||||
initialItemType || null
|
||||
);
|
||||
const [wizardData, setWizardData] = useState<AnyWizardData>({});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Get current tenant
|
||||
const { currentTenant } = useTenant();
|
||||
|
||||
// API hooks
|
||||
const createPurchaseOrderMutation = useCreatePurchaseOrder();
|
||||
const createProductionBatchMutation = useCreateProductionBatch();
|
||||
|
||||
// Use a ref to store the current data - this allows step components
|
||||
// to always access the latest data without causing the steps array to be recreated
|
||||
@@ -48,6 +64,7 @@ export const UnifiedAddWizard: React.FC<UnifiedAddWizardProps> = ({
|
||||
setSelectedItemType(initialItemType || null);
|
||||
setWizardData({});
|
||||
dataRef.current = {};
|
||||
setIsSubmitting(false);
|
||||
onClose();
|
||||
}, [onClose, initialItemType]);
|
||||
|
||||
@@ -66,17 +83,101 @@ export const UnifiedAddWizard: React.FC<UnifiedAddWizardProps> = ({
|
||||
setWizardData(newData);
|
||||
}, []);
|
||||
|
||||
// Handle wizard completion
|
||||
// Handle wizard completion with API submission
|
||||
const handleWizardComplete = useCallback(
|
||||
(data?: any) => {
|
||||
if (selectedItemType) {
|
||||
// On completion, sync the ref to state for submission
|
||||
setWizardData(dataRef.current);
|
||||
onComplete?.(selectedItemType, dataRef.current);
|
||||
async () => {
|
||||
if (!selectedItemType || !currentTenant?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
const finalData = dataRef.current as any; // Cast to any for flexible data access
|
||||
|
||||
// Handle Purchase Order submission
|
||||
if (selectedItemType === 'purchase-order') {
|
||||
const subtotal = (finalData.items || []).reduce(
|
||||
(sum: number, item: any) => sum + (item.subtotal || 0),
|
||||
0
|
||||
);
|
||||
|
||||
await createPurchaseOrderMutation.mutateAsync({
|
||||
tenantId: currentTenant.id,
|
||||
data: {
|
||||
supplier_id: finalData.supplier_id,
|
||||
required_delivery_date: finalData.required_delivery_date,
|
||||
priority: finalData.priority || 'normal',
|
||||
subtotal: String(subtotal),
|
||||
tax_amount: String(finalData.tax_amount || 0),
|
||||
shipping_cost: String(finalData.shipping_cost || 0),
|
||||
discount_amount: String(finalData.discount_amount || 0),
|
||||
notes: finalData.notes || undefined,
|
||||
items: (finalData.items || []).map((item: any) => ({
|
||||
inventory_product_id: item.inventory_product_id,
|
||||
ordered_quantity: item.ordered_quantity,
|
||||
unit_price: String(item.unit_price),
|
||||
unit_of_measure: item.unit_of_measure,
|
||||
})),
|
||||
},
|
||||
});
|
||||
toast.success('Orden de compra creada exitosamente');
|
||||
}
|
||||
|
||||
// Handle Production Batch submission
|
||||
if (selectedItemType === 'production-batch') {
|
||||
// Convert staff_assigned from string to array
|
||||
const staffArray = finalData.staff_assigned_string
|
||||
? finalData.staff_assigned_string.split(',').map((s: string) => s.trim()).filter((s: string) => s.length > 0)
|
||||
: [];
|
||||
|
||||
const batchData: ProductionBatchCreate = {
|
||||
product_id: finalData.product_id,
|
||||
product_name: finalData.product_name,
|
||||
recipe_id: finalData.recipe_id || undefined,
|
||||
planned_start_time: finalData.planned_start_time,
|
||||
planned_end_time: finalData.planned_end_time,
|
||||
planned_quantity: Number(finalData.planned_quantity),
|
||||
planned_duration_minutes: Number(finalData.planned_duration_minutes),
|
||||
priority: (finalData.priority || ProductionPriorityEnum.MEDIUM) as ProductionPriorityEnum,
|
||||
is_rush_order: finalData.is_rush_order || false,
|
||||
is_special_recipe: finalData.is_special_recipe || false,
|
||||
production_notes: finalData.production_notes || undefined,
|
||||
batch_number: finalData.batch_number || undefined,
|
||||
order_id: finalData.order_id || undefined,
|
||||
forecast_id: finalData.forecast_id || undefined,
|
||||
equipment_used: [],
|
||||
staff_assigned: staffArray,
|
||||
station_id: finalData.station_id || undefined,
|
||||
};
|
||||
|
||||
await createProductionBatchMutation.mutateAsync({
|
||||
tenantId: currentTenant.id,
|
||||
batchData,
|
||||
});
|
||||
toast.success('Lote de producción creado exitosamente');
|
||||
}
|
||||
|
||||
// Call the parent's onComplete callback
|
||||
onComplete?.(selectedItemType, finalData);
|
||||
|
||||
// Close the modal
|
||||
handleClose();
|
||||
} catch (error: any) {
|
||||
console.error('Error submitting wizard data:', error);
|
||||
toast.error(error.message || 'Error al crear el elemento');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
handleClose();
|
||||
},
|
||||
[selectedItemType, onComplete, handleClose]
|
||||
[
|
||||
selectedItemType,
|
||||
currentTenant,
|
||||
createPurchaseOrderMutation,
|
||||
createProductionBatchMutation,
|
||||
onComplete,
|
||||
handleClose,
|
||||
]
|
||||
);
|
||||
|
||||
// Get wizard steps based on selected item type
|
||||
@@ -120,6 +221,10 @@ export const UnifiedAddWizard: React.FC<UnifiedAddWizardProps> = ({
|
||||
return TeamMemberWizardSteps(dataRef, setWizardData);
|
||||
case 'sales-entry':
|
||||
return SalesEntryWizardSteps(dataRef, setWizardData);
|
||||
case 'purchase-order':
|
||||
return PurchaseOrderWizardSteps(dataRef, setWizardData);
|
||||
case 'production-batch':
|
||||
return ProductionBatchWizardSteps(dataRef, setWizardData);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@@ -141,6 +246,8 @@ export const UnifiedAddWizard: React.FC<UnifiedAddWizardProps> = ({
|
||||
'customer': 'Agregar Cliente',
|
||||
'team-member': 'Agregar Miembro del Equipo',
|
||||
'sales-entry': 'Registrar Ventas',
|
||||
'purchase-order': 'Crear Orden de Compra',
|
||||
'production-batch': 'Crear Lote de Producción',
|
||||
};
|
||||
|
||||
return titleMap[selectedItemType] || 'Agregar Contenido';
|
||||
|
||||
Reference in New Issue
Block a user