From 478d4232ee3b1255b928e7798b426eff48bdf106 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Nov 2025 07:30:01 +0000 Subject: [PATCH] feat: Rewrite CustomerWizard with all improvements - Added missing required field: customer_code with auto-generation - Removed duplicate Next buttons - using validate prop - Added ALL backend fields in advanced options section - Single streamlined step for better UX - Auto-generates customer code from name - All fields properly aligned with backend API - Tooltip for complex field - Proper validation - English labels --- .../unified-wizard/wizards/CustomerWizard.tsx | 924 +++++++----------- 1 file changed, 378 insertions(+), 546 deletions(-) diff --git a/frontend/src/components/domain/unified-wizard/wizards/CustomerWizard.tsx b/frontend/src/components/domain/unified-wizard/wizards/CustomerWizard.tsx index bc10d037..fd4195da 100644 --- a/frontend/src/components/domain/unified-wizard/wizards/CustomerWizard.tsx +++ b/frontend/src/components/domain/unified-wizard/wizards/CustomerWizard.tsx @@ -1,336 +1,65 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { WizardStep, WizardStepProps } from '../../../ui/WizardModal/WizardModal'; -import { - Users, - Mail, - Phone, - MapPin, - Building, - CreditCard, - Calendar, - AlertTriangle, - CheckCircle2, - Loader2, -} from 'lucide-react'; +import { Users, CheckCircle2, Loader2 } from 'lucide-react'; import { useTenant } from '../../../../stores/tenant.store'; import OrdersService from '../../../../api/services/orders'; import { showToast } from '../../../../utils/toast'; -import { isValidEmail, isValidSpanishPhone } from '../../../../utils/validation'; +import { AdvancedOptionsSection } from '../../../ui/AdvancedOptionsSection'; +import Tooltip from '../../../ui/Tooltip/Tooltip'; interface WizardDataProps extends WizardStepProps { data: Record; onDataChange: (data: Record) => void; } -// Step 1: Customer Details -const CustomerDetailsStep: React.FC = ({ data, onDataChange, onNext }) => { - const [customerData, setCustomerData] = useState({ - name: data.name || '', - customerType: data.customerType || 'retail', - contactPerson: data.contactPerson || '', - phone: data.phone || '', - email: data.email || '', - address: data.address || '', - city: data.city || '', - postalCode: data.postalCode || '', - country: data.country || 'España', - }); - - const [validationErrors, setValidationErrors] = useState>({}); - - const validatePhone = (phone: string) => { - if (phone && !isValidSpanishPhone(phone)) { - setValidationErrors(prev => ({ ...prev, phone: 'Formato de teléfono español inválido' })); - } else { - setValidationErrors(prev => { - const { phone, ...rest } = prev; - return rest; - }); - } - }; - - const validateEmail = (email: string) => { - if (email && !isValidEmail(email)) { - setValidationErrors(prev => ({ ...prev, email: 'Formato de email inválido' })); - } else { - setValidationErrors(prev => { - const { email, ...rest } = prev; - return rest; - }); - } - }; - - const handleContinue = () => { - // Validate before continuing - validatePhone(customerData.phone); - if (customerData.email) validateEmail(customerData.email); - - if (Object.keys(validationErrors).length === 0) { - onDataChange({ ...data, ...customerData }); - onNext(); - } - }; - - return ( -
-
- -

- Información del Cliente -

-

- Datos de contacto y ubicación -

-
- -
- {/* Basic Info */} -
-

- - Información Básica -

- -
-
- - setCustomerData({ ...customerData, name: e.target.value })} - placeholder="Ej: Restaurante El Molino" - className="w-full px-3 py-2 border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)]" - /> -
- -
- - -
- -
- - setCustomerData({ ...customerData, contactPerson: e.target.value })} - placeholder="Nombre del contacto" - className="w-full px-3 py-2 border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)]" - /> -
-
-
- - {/* Contact Info */} -
-

- - Datos de Contacto -

- -
-
- - setCustomerData({ ...customerData, phone: e.target.value })} - onBlur={(e) => validatePhone(e.target.value)} - placeholder="+34 123 456 789" - className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 bg-[var(--bg-primary)] text-[var(--text-primary)] ${ - validationErrors.phone - ? 'border-red-500 focus:ring-red-500' - : 'border-[var(--border-secondary)] focus:ring-[var(--color-primary)]' - }`} - /> - {validationErrors.phone && ( -

- - {validationErrors.phone} -

- )} -
- -
- - setCustomerData({ ...customerData, email: e.target.value })} - onBlur={(e) => validateEmail(e.target.value)} - placeholder="contacto@empresa.com" - className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 bg-[var(--bg-primary)] text-[var(--text-primary)] ${ - validationErrors.email - ? 'border-red-500 focus:ring-red-500' - : 'border-[var(--border-secondary)] focus:ring-[var(--color-primary)]' - }`} - /> - {validationErrors.email && ( -

- - {validationErrors.email} -

- )} -
-
-
- - {/* Address */} -
-

- - Dirección -

- -
-
- -