diff --git a/src/components/registration/DynamicFormField.js b/src/components/registration/DynamicFormField.js index 1f416d7..5e097f2 100644 --- a/src/components/registration/DynamicFormField.js +++ b/src/components/registration/DynamicFormField.js @@ -47,6 +47,15 @@ const DynamicFormField = ({ const hasError = errors.length > 0; const errorMessage = errors[0]; + const formatPhoneNumber = (rawValue) => { + const digits = String(rawValue || '').replace(/\D/g, '').slice(0, 10); + if (digits.length <= 3) return digits; + if (digits.length <= 6) { + return `(${digits.slice(0, 3)}) ${digits.slice(3)}`; + } + return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`; + }; + // Common input className const inputClassName = `h-14 rounded-xl border-2 ${ hasError @@ -59,6 +68,11 @@ const DynamicFormField = ({ const { value: newValue, type: inputType, checked } = e.target; if (inputType === 'checkbox') { onChange(id, checked); + return; + } + if (type === 'phone') { + onChange(id, formatPhoneNumber(newValue)); + return; } else { onChange(id, newValue); } @@ -111,6 +125,8 @@ const DynamicFormField = ({ value={value || ''} onChange={handleInputChange} placeholder={placeholder} + inputMode={type === 'phone' ? 'numeric' : undefined} + maxLength={type === 'phone' ? 14 : undefined} className={inputClassName} data-testid={`field-${id}`} /> diff --git a/src/pages/admin/AdminRegistrationBuilder.js b/src/pages/admin/AdminRegistrationBuilder.js index 18ee294..104c60d 100644 --- a/src/pages/admin/AdminRegistrationBuilder.js +++ b/src/pages/admin/AdminRegistrationBuilder.js @@ -51,6 +51,7 @@ import { Zap, Copy, X, + Grip } from 'lucide-react'; // Field type icons @@ -319,11 +320,11 @@ const AdminRegistrationBuilder = () => { steps: prev.steps.map((s) => s.id === selectedStep ? { - ...s, - sections: s.sections - .filter((sec) => sec.id !== sectionId) - .map((sec, idx) => ({ ...sec, order: idx + 1 })), - } + ...s, + sections: s.sections + .filter((sec) => sec.id !== sectionId) + .map((sec, idx) => ({ ...sec, order: idx + 1 })), + } : s ), })); @@ -361,13 +362,13 @@ const AdminRegistrationBuilder = () => { steps: prev.steps.map((s) => s.id === selectedStep ? { - ...s, - sections: s.sections.map((sec) => - sec.id === selectedSection - ? { ...sec, fields: [...(sec.fields || []), newField] } - : sec - ), - } + ...s, + sections: s.sections.map((sec) => + sec.id === selectedSection + ? { ...sec, fields: [...(sec.fields || []), newField] } + : sec + ), + } : s ), })); @@ -395,18 +396,18 @@ const AdminRegistrationBuilder = () => { steps: prev.steps.map((s) => s.id === selectedStep ? { - ...s, - sections: s.sections.map((sec) => - sec.id === selectedSection - ? { - ...sec, - fields: sec.fields - .filter((f) => f.id !== fieldId) - .map((f, idx) => ({ ...f, order: idx + 1 })), - } - : sec - ), - } + ...s, + sections: s.sections.map((sec) => + sec.id === selectedSection + ? { + ...sec, + fields: sec.fields + .filter((f) => f.id !== fieldId) + .map((f, idx) => ({ ...f, order: idx + 1 })), + } + : sec + ), + } : s ), })); @@ -423,18 +424,18 @@ const AdminRegistrationBuilder = () => { steps: prev.steps.map((s) => s.id === selectedStep ? { - ...s, - sections: s.sections.map((sec) => - sec.id === selectedSection - ? { - ...sec, - fields: sec.fields.map((f) => - f.id === fieldId ? { ...f, ...updates } : f - ), - } - : sec - ), - } + ...s, + sections: s.sections.map((sec) => + sec.id === selectedSection + ? { + ...sec, + fields: sec.fields.map((f) => + f.id === fieldId ? { ...f, ...updates } : f + ), + } + : sec + ), + } : s ), })); @@ -492,132 +493,137 @@ const AdminRegistrationBuilder = () => { )} {/* Main Builder Layout */} -