From 502dae8dfa71592e4f0476f5094919dead3037e3 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Nov 2025 09:50:33 +0000 Subject: [PATCH] fix: Critical - Remove infinite re-render loops from all wizards CRITICAL BUG FIX: The useEffect hooks syncing wizard state with parent were causing infinite re-render loops, completely blocking all UI interactions (text inputs, clicks, selections, etc.). Root cause: useEffect(() => onDataChange({...data, ...localState}), [localState]) creates infinite loop because localState is recreated on every render, triggering the effect again, which updates parent, which re-renders component, repeat forever. Solution: Remove problematic useEffect sync hooks and instead: 1. Create handler functions that update both local state AND parent state together 2. Call these handlers directly in onChange events (not in useEffect) 3. Only sync auto-generated fields (SKU, order number) in useEffect with proper deps Files fixed: - InventoryWizard.tsx: Added handleDataChange() function, updated all onChange - QualityTemplateWizard.tsx: Added handleDataChange() function, updated all onChange - CustomerOrderWizard.tsx: Fixed all 3 steps: * Step 1: handleCustomerChange(), handleNewCustomerChange() * Step 2: updateOrderItems() * Step 3: handleOrderDataChange() Testing: All text inputs, select dropdowns, checkboxes, and buttons now work correctly. UI is responsive and performant without infinite re-rendering. This was blocking all user interactions - highest priority fix. --- .../wizards/CustomerOrderWizard.tsx | 169 ++++++++++-------- .../wizards/InventoryWizard.tsx | 99 +++++----- .../wizards/QualityTemplateWizard.tsx | 61 ++++--- 3 files changed, 175 insertions(+), 154 deletions(-) diff --git a/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx b/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx index 3a226ba0..7e15dd14 100644 --- a/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx +++ b/frontend/src/components/domain/unified-wizard/wizards/CustomerOrderWizard.tsx @@ -46,18 +46,30 @@ const CustomerSelectionStep: React.FC = ({ data, onDataChange } fetchCustomers(); }, []); - // Sync with parent wizard state in real-time - useEffect(() => { + // Update parent whenever customer selection changes + const handleCustomerChange = (newCustomer: any, newShowForm: boolean) => { + setSelectedCustomer(newCustomer); + setShowNewCustomerForm(newShowForm); onDataChange({ ...data, - customer: selectedCustomer, - showNewCustomerForm, - newCustomerName: newCustomer.name, - newCustomerType: newCustomer.type, - newCustomerPhone: newCustomer.phone, - newCustomerEmail: newCustomer.email, + customer: newCustomer, + showNewCustomerForm: newShowForm, }); - }, [selectedCustomer, showNewCustomerForm, newCustomer]); + }; + + // Update new customer data + const handleNewCustomerChange = (updates: any) => { + const updated = { ...newCustomer, ...updates }; + setNewCustomer(updated); + onDataChange({ + ...data, + showNewCustomerForm, + newCustomerName: updated.name, + newCustomerType: updated.type, + newCustomerPhone: updated.phone, + newCustomerEmail: updated.email, + }); + }; const fetchCustomers = async () => { if (!currentTenant?.id) return; @@ -84,8 +96,7 @@ const CustomerSelectionStep: React.FC = ({ data, onDataChange } ); const handleSelectCustomer = (customer: any) => { - setSelectedCustomer(customer); - setShowNewCustomerForm(false); + handleCustomerChange(customer, false); }; return ( @@ -188,7 +199,7 @@ const CustomerSelectionStep: React.FC = ({ data, onDataChange } {/* Create New Customer Button */}