import React, { useState, useEffect } from 'react'; import { useForm, Controller } from 'react-hook-form'; import InputTextIcon from './InputTextIcon'; import SelectChoice from './SelectChoice'; import Button from './Button'; import FileUpload from './FileUpload'; import IconSelector from './IconSelector'; import * as LucideIcons from 'lucide-react'; import { FIELD_TYPES } from './FormTypes'; import FIELD_TYPES_WITH_ICONS from './FieldTypesWithIcons'; export default function AddFieldModal({ isOpen, onClose, onSubmit, editingField = null, editingIndex = -1, hasMasterFile = false, onMasterFileUpload, }) { const isEditing = editingIndex >= 0; const [currentField, setCurrentField] = useState({ id: '', label: '', type: 'text', required: false, icon: '', options: [], text: '', placeholder: '', acceptTypes: '', maxSize: 5, // 5MB par défaut checked: false, masterFileToUpload: null, validation: { pattern: '', minLength: '', maxLength: '', }, }); const [showIconPicker, setShowIconPicker] = useState(false); const [newOption, setNewOption] = useState(''); const { control, handleSubmit, reset, setValue } = useForm(); // Mettre à jour l'état et les valeurs du formulaire lorsque editingField change useEffect(() => { if (isOpen) { const defaultValues = editingField || { id: '', label: '', type: 'text', required: false, icon: '', options: [], text: '', placeholder: '', acceptTypes: '', maxSize: 5, checked: false, masterFileToUpload: null, signatureData: '', backgroundColor: '#ffffff', penColor: '#000000', penWidth: 2, validation: { pattern: '', minLength: '', maxLength: '', }, }; // Si un type a été présélectionné depuis le sélecteur de type if (editingField && !isEditing) { // S'assurer que le type est correctement défini if (typeof editingField.type === 'string') { defaultValues.type = editingField.type; } else if (editingField.value) { defaultValues.type = editingField.value; } } setCurrentField(defaultValues); // Réinitialiser le formulaire avec les valeurs de l'élément à éditer reset({ type: defaultValues.type, label: defaultValues.label, placeholder: defaultValues.placeholder, required: defaultValues.required, icon: defaultValues.icon, text: defaultValues.text, acceptTypes: defaultValues.acceptTypes, maxSize: defaultValues.maxSize, checked: defaultValues.checked, signatureData: defaultValues.signatureData, backgroundColor: defaultValues.backgroundColor, penColor: defaultValues.penColor, penWidth: defaultValues.penWidth, validation: defaultValues.validation, }); } }, [isOpen, editingField, reset, isEditing]); // Ajouter une option au select const addOption = (e) => { // Arrêter la propagation de l'événement pour éviter que le clic n'atteigne l'arrière-plan if (e) { e.preventDefault(); e.stopPropagation(); } if (newOption.trim()) { // Vérifie si options existe et est un tableau, sinon initialise comme tableau vide const currentOptions = Array.isArray(currentField.options) ? currentField.options : []; setCurrentField({ ...currentField, options: [...currentOptions, newOption.trim()], }); setNewOption(''); } }; // Supprimer une option du select const removeOption = (index) => { // Vérifie si options existe et est un tableau, sinon initialise comme tableau vide const currentOptions = Array.isArray(currentField.options) ? currentField.options : []; const newOptions = currentOptions.filter((_, i) => i !== index); setCurrentField({ ...currentField, options: newOptions }); }; // Sélectionner une icône const selectIcon = (iconName) => { setCurrentField({ ...currentField, icon: iconName }); // Mettre à jour la valeur dans le formulaire const iconField = control._fields.icon; if (iconField && iconField.onChange) { iconField.onChange(iconName); } }; const handleFieldSubmit = (data) => { onSubmit(data, currentField, editingIndex); onClose(); }; if (!isOpen) return null; return (

{isEditing ? 'Modifier le champ' : 'Ajouter un champ'}

( { const newType = e.target.value; onChange(newType); // Assurons-nous que les options restent un tableau si on sélectionne select ou radio let updatedOptions = currentField.options; // Si options n'existe pas ou n'est pas un tableau, initialiser comme tableau vide if (!updatedOptions || !Array.isArray(updatedOptions)) { updatedOptions = []; } setCurrentField({ ...currentField, type: newType, options: updatedOptions, }); }} choices={FIELD_TYPES_WITH_ICONS} placeHolder="Sélectionner un type" required showIcons={true} customSelect={true} /> )} /> {![ 'paragraph', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6', ].includes(currentField.type) && ( <> ( { onChange(e.target.value); setCurrentField({ ...currentField, label: e.target.value, }); }} required /> )} /> ( { onChange(e.target.value); setCurrentField({ ...currentField, placeholder: e.target.value, }); }} /> )} />
( { onChange(e.target.checked); setCurrentField({ ...currentField, required: e.target.checked, }); }} className="mr-2" /> )} />
{(currentField.type === 'text' || currentField.type === 'email' || currentField.type === 'date') && (
(
{currentField.icon && LucideIcons[currentField.icon] ? ( <> {React.createElement( LucideIcons[currentField.icon], { size: 20, className: 'text-gray-600', } )} {currentField.icon} ) : ( Aucune icône sélectionnée )}
)} />
)} )} {[ 'paragraph', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6', ].includes(currentField.type) && ( (