diff --git a/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx b/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx index 7e15dd14..a1ab0c7b 100644 --- a/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx +++ b/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { WizardStep, WizardStepProps } from '../../../ui/WizardModal/WizardModal'; import { AdvancedOptionsSection } from '../../../ui/AdvancedOptionsSection'; import Tooltip from '../../../ui/Tooltip/Tooltip'; @@ -526,6 +526,8 @@ const OrderItemsStep: React.FC = ({ data, onDataChange }) => { // Step 3: Delivery & Payment with ALL fields const DeliveryPaymentStep: React.FC = ({ data, onDataChange }) => { + const hasGeneratedOrderNumRef = useRef(false); + const [orderData, setOrderData] = useState({ // Required fields requestedDeliveryDate: data.requestedDeliveryDate || '', @@ -603,14 +605,24 @@ const DeliveryPaymentStep: React.FC = ({ data, onDataChange }) }); // Auto-generate order number if not provided + // Only watches orderNumber field to avoid unnecessary re-renders useEffect(() => { - if (!orderData.orderNumber) { + // Only auto-generate order number if: + // 1. We haven't generated before + // 2. Order number is empty + if (!hasGeneratedOrderNumRef.current && !orderData.orderNumber) { + hasGeneratedOrderNumRef.current = true; const orderNum = `ORD-${Date.now().toString().slice(-8)}`; const newData = { ...orderData, orderNumber: orderNum }; setOrderData(newData); onDataChange({ ...data, ...newData }); } - }, [orderData.orderNumber]); + + // If user manually clears the order number, allow regeneration + if (hasGeneratedOrderNumRef.current && !orderData.orderNumber) { + hasGeneratedOrderNumRef.current = false; + } + }, [orderData.orderNumber]); // Only watch orderNumber - prevents unnecessary interference // Update parent whenever order data changes const handleOrderDataChange = (newOrderData: any) => { diff --git a/frontend/src/components/domain/unified-wizard/wizards/InventoryWizard.tsx b/frontend/src/components/domain/unified-wizard/wizards/InventoryWizard.tsx index b980adbb..1a37382a 100644 --- a/frontend/src/components/domain/unified-wizard/wizards/InventoryWizard.tsx +++ b/frontend/src/components/domain/unified-wizard/wizards/InventoryWizard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { WizardStep, WizardStepProps } from '../../../ui/WizardModal/WizardModal'; import { AdvancedOptionsSection } from '../../../ui/AdvancedOptionsSection'; import Tooltip from '../../../ui/Tooltip/Tooltip'; @@ -11,6 +11,8 @@ interface WizardDataProps extends WizardStepProps { // Single comprehensive step with all fields const InventoryDetailsStep: React.FC = ({ data, onDataChange }) => { + const hasGeneratedSkuRef = useRef(false); + const [inventoryData, setInventoryData] = useState({ // Required fields name: data.name || '', @@ -79,14 +81,25 @@ const InventoryDetailsStep: React.FC = ({ data, onDataChange }) }); // Auto-generate SKU from name if not provided + // Only watches SKU field to avoid interfering with typing in name field useEffect(() => { - if (!inventoryData.sku && inventoryData.name) { + // Only auto-generate SKU if: + // 1. We haven't generated before + // 2. SKU is empty + // 3. Name has at least 3 characters (so we can take substring) + if (!hasGeneratedSkuRef.current && !inventoryData.sku && inventoryData.name && inventoryData.name.length >= 3) { + hasGeneratedSkuRef.current = true; const sku = `SKU-${inventoryData.name.substring(0, 3).toUpperCase()}-${Date.now().toString().slice(-4)}`; const newData = { ...inventoryData, sku }; setInventoryData(newData); onDataChange({ ...data, ...newData }); } - }, [inventoryData.name, inventoryData.sku]); + + // If user manually clears the SKU, allow regeneration + if (hasGeneratedSkuRef.current && !inventoryData.sku) { + hasGeneratedSkuRef.current = false; + } + }, [inventoryData.sku]); // Only watch SKU, not name - prevents interference with typing // Update parent whenever local state changes const handleDataChange = (newInventoryData: any) => { diff --git a/frontend/src/components/domain/unified-wizard/wizards/QualityTemplateWizard.tsx b/frontend/src/components/domain/unified-wizard/wizards/QualityTemplateWizard.tsx index 4e750d7f..40743c00 100644 --- a/frontend/src/components/domain/unified-wizard/wizards/QualityTemplateWizard.tsx +++ b/frontend/src/components/domain/unified-wizard/wizards/QualityTemplateWizard.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { WizardStep, WizardStepProps } from '../../../ui/WizardModal/WizardModal'; import { AdvancedOptionsSection } from '../../../ui/AdvancedOptionsSection'; import Tooltip from '../../../ui/Tooltip/Tooltip'; @@ -11,6 +11,8 @@ interface WizardDataProps extends WizardStepProps { // Single comprehensive step with all fields const QualityTemplateDetailsStep: React.FC = ({ data, onDataChange }) => { + const hasGeneratedCodeRef = useRef(false); + const [templateData, setTemplateData] = useState({ // Required fields name: data.name || '', @@ -51,14 +53,25 @@ const QualityTemplateDetailsStep: React.FC = ({ data, onDataCha }); // Auto-generate template code from name if not provided + // Only watches templateCode field to avoid interfering with typing in name field useEffect(() => { - if (!templateData.templateCode && templateData.name) { + // Only auto-generate template code if: + // 1. We haven't generated before + // 2. Template code is empty + // 3. Name has at least 3 characters (so we can take substring) + if (!hasGeneratedCodeRef.current && !templateData.templateCode && templateData.name && templateData.name.length >= 3) { + hasGeneratedCodeRef.current = true; const code = `TPL-${templateData.name.substring(0, 3).toUpperCase()}-${Date.now().toString().slice(-4)}`; const newData = { ...templateData, templateCode: code }; setTemplateData(newData); onDataChange({ ...data, ...newData }); } - }, [templateData.name, templateData.templateCode]); + + // If user manually clears the template code, allow regeneration + if (hasGeneratedCodeRef.current && !templateData.templateCode) { + hasGeneratedCodeRef.current = false; + } + }, [templateData.templateCode]); // Only watch templateCode, not name - prevents interference with typing // Update parent whenever local state changes const handleDataChange = (newTemplateData: any) => {