From 5e62ee510074e30cd33802aae20d3d1c297619a3 Mon Sep 17 00:00:00 2001 From: Luc SORIGNET Date: Mon, 1 Sep 2025 12:09:19 +0200 Subject: [PATCH] feat: Ajout des composants manquant dans le FormTemplateBuilder [N3WTS-17] --- .../src/app/[locale]/admin/settings/page.js | 2 +- .../structure/SchoolClassManagement/page.js | 2 +- .../subscriptions/createSubscription/page.js | 2 +- .../src/components/Form/AddFieldModal.js | 263 +++++++++++++++++- .../src/components/{ => Form}/CheckBox.js | 6 +- Front-End/src/components/Form/FormRenderer.js | 247 +++++++++++++++- .../components/Form/FormTemplateBuilder.js | 28 +- Front-End/src/components/Form/FormTypes.js | 5 + .../src/components/PaymentPlanSelector.js | 2 +- .../Competencies/CompetenciesList.js | 2 +- .../Tarification/DiscountsSection.js | 2 +- .../Structure/Tarification/FeesSection.js | 2 +- 12 files changed, 525 insertions(+), 38 deletions(-) rename Front-End/src/components/{ => Form}/CheckBox.js (92%) diff --git a/Front-End/src/app/[locale]/admin/settings/page.js b/Front-End/src/app/[locale]/admin/settings/page.js index d037ad0..ac50dfa 100644 --- a/Front-End/src/app/[locale]/admin/settings/page.js +++ b/Front-End/src/app/[locale]/admin/settings/page.js @@ -4,7 +4,7 @@ import Tab from '@/components/Tab'; import TabContent from '@/components/TabContent'; import Button from '@/components/Form/Button'; import InputText from '@/components/Form/InputText'; -import CheckBox from '@/components/CheckBox'; // Import du composant CheckBox +import CheckBox from '@/components/Form/CheckBox'; // Import du composant CheckBox import logger from '@/utils/logger'; import { fetchSmtpSettings, diff --git a/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js b/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js index 737f36d..e01b141 100644 --- a/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js +++ b/Front-End/src/app/[locale]/admin/structure/SchoolClassManagement/page.js @@ -10,7 +10,7 @@ import logger from '@/utils/logger'; import { useClasses } from '@/context/ClassesContext'; import Button from '@/components/Form/Button'; import SelectChoice from '@/components/Form/SelectChoice'; -import CheckBox from '@/components/CheckBox'; +import CheckBox from '@/components/Form/CheckBox'; import { fetchAbsences, createAbsences, diff --git a/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js b/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js index 51bf505..d978e34 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/createSubscription/page.js @@ -10,7 +10,7 @@ import FeesSection from '@/components/Structure/Tarification/FeesSection'; import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection'; import SectionTitle from '@/components/SectionTitle'; import InputPhone from '@/components/Form/InputPhone'; -import CheckBox from '@/components/CheckBox'; +import CheckBox from '@/components/Form/CheckBox'; import RadioList from '@/components/Form/RadioList'; import SelectChoice from '@/components/Form/SelectChoice'; import Loader from '@/components/Loader'; diff --git a/Front-End/src/components/Form/AddFieldModal.js b/Front-End/src/components/Form/AddFieldModal.js index 63332e1..6d0eff1 100644 --- a/Front-End/src/components/Form/AddFieldModal.js +++ b/Front-End/src/components/Form/AddFieldModal.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useForm, Controller } from 'react-hook-form'; import InputTextIcon from './InputTextIcon'; import SelectChoice from './SelectChoice'; @@ -16,23 +16,69 @@ export default function AddFieldModal({ }) { const isEditing = editingIndex >= 0; - const [currentField, setCurrentField] = useState( - editingField || { - id: '', - label: '', - type: 'text', - required: false, - icon: '', - options: [], - text: '', - placeholder: '', - } - ); + const [currentField, setCurrentField] = useState({ + id: '', + label: '', + type: 'text', + required: false, + icon: '', + options: [], + text: '', + placeholder: '', + acceptTypes: '', + maxSize: 5, // 5MB par défaut + checked: false, + validation: { + pattern: '', + minLength: '', + maxLength: '', + }, + }); const [showIconPicker, setShowIconPicker] = useState(false); const [newOption, setNewOption] = useState(''); - const { control, handleSubmit, reset } = useForm(); + 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, + validation: { + pattern: '', + minLength: '', + maxLength: '', + }, + }; + + 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, + validation: defaultValues.validation, + }); + } + }, [isOpen, editingField, reset]); // Ajouter une option au select const addOption = () => { @@ -326,6 +372,195 @@ export default function AddFieldModal({ )} + {currentField.type === 'radio' && ( +
+ +
+ setNewOption(e.target.value)} + placeholder="Nouvelle option" + className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" + onKeyPress={(e) => + e.key === 'Enter' && (e.preventDefault(), addOption()) + } + /> +
+
+ {currentField.options.map((option, index) => ( +
+ {option} + +
+ ))} +
+
+ )} + + {currentField.type === 'phone' && ( + ( + { + onChange(e.target.value); + setCurrentField({ + ...currentField, + validation: { + ...currentField.validation, + pattern: e.target.value, + }, + }); + }} + /> + )} + /> + )} + + {currentField.type === 'file' && ( + <> + ( + { + onChange(e.target.value); + setCurrentField({ + ...currentField, + acceptTypes: e.target.value, + }); + }} + /> + )} + /> + ( + { + onChange(e.target.value); + setCurrentField({ + ...currentField, + maxSize: parseInt(e.target.value) || 5, + }); + }} + /> + )} + /> + + )} + + {currentField.type === 'checkbox' && ( + <> +
+ ( + { + onChange(e.target.checked); + setCurrentField({ + ...currentField, + checked: e.target.checked, + }); + }} + className="mr-2" + /> + )} + /> + +
+
+ ( + { + onChange(e.target.checked); + setCurrentField({ + ...currentField, + horizontal: e.target.checked, + }); + }} + className="mr-2" + /> + )} + /> + +
+ + )} + + {currentField.type === 'toggle' && ( +
+ ( + { + onChange(e.target.checked); + setCurrentField({ + ...currentField, + checked: e.target.checked, + }); + }} + className="mr-2" + /> + )} + /> + +
+ )} +