From daad12cf40ce3b628581892f9a894a0841baa5e3 Mon Sep 17 00:00:00 2001 From: N3WT DE COMPET Date: Sat, 26 Apr 2025 16:43:25 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Ordonnancement=20de=20l'inscription=20s?= =?UTF-8?q?ur=20plusieurs=20pages=20+=20contr=C3=B4le=20des=20champs=20rem?= =?UTF-8?q?plis=20dans=20le=20formulaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/[locale]/users/login/page.js | 7 +- .../Inscription/InscriptionFormShared.js | 304 +++++++++--------- .../Inscription/PaymentMethodSelector.js | 136 +++++--- .../Inscription/ResponsableInputFields.js | 75 ++++- .../components/Inscription/StudentInfoForm.js | 179 +++++++---- 5 files changed, 437 insertions(+), 264 deletions(-) diff --git a/Front-End/src/app/[locale]/users/login/page.js b/Front-End/src/app/[locale]/users/login/page.js index 2e6be43..47b1c8d 100644 --- a/Front-End/src/app/[locale]/users/login/page.js +++ b/Front-End/src/app/[locale]/users/login/page.js @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import DjangoCSRFToken from '@/components/DjangoCSRFToken'; import Logo from '@/components/Logo'; -import { useSearchParams, useRouter } from 'next/navigation'; +import { useRouter } from 'next/navigation'; import InputTextIcon from '@/components/InputTextIcon'; import Loader from '@/components/Loader'; // Importez le composant Loader import Button from '@/components/Button'; // Importez le composant Button @@ -16,7 +16,6 @@ import logger from '@/utils/logger'; import { useEstablishment } from '@/context/EstablishmentContext'; export default function Page() { - const searchParams = useSearchParams(); const [errorMessage, setErrorMessage] = useState(''); const [userFieldError, setUserFieldError] = useState(''); const [passwordFieldError, setPasswordFieldError] = useState(''); @@ -26,10 +25,6 @@ export default function Page() { const router = useRouter(); const csrfToken = useCsrfToken(); // Utilisez le hook useCsrfToken - function isOK(data) { - return data.errorMessage === ''; - } - function handleFormLogin(formData) { setIsLoading(true); setErrorMessage(''); diff --git a/Front-End/src/components/Inscription/InscriptionFormShared.js b/Front-End/src/components/Inscription/InscriptionFormShared.js index 445eba6..ad8fff6 100644 --- a/Front-End/src/components/Inscription/InscriptionFormShared.js +++ b/Front-End/src/components/Inscription/InscriptionFormShared.js @@ -1,10 +1,8 @@ // Import des dépendances nécessaires import React, { useState, useEffect } from 'react'; -import Loader from '@/components/Loader'; import Button from '@/components/Button'; import DjangoCSRFToken from '@/components/DjangoCSRFToken'; import { - fetchRegisterForm, fetchSchoolFileTemplatesFromRegistrationFiles, fetchParentFileTemplatesFromRegistrationFiles, } from '@/app/actions/subscriptionAction'; @@ -19,11 +17,12 @@ import { } from '@/app/actions/schoolAction'; import { BASE_URL } from '@/utils/Url'; import logger from '@/utils/logger'; -import StudentInfoForm, { - validateStudentInfo, -} from '@/components/Inscription/StudentInfoForm'; import FilesToUpload from '@/components/Inscription/FilesToUpload'; import { DocusealForm } from '@docuseal/react'; +import StudentInfoForm from '@/components/Inscription/StudentInfoForm'; +import ResponsableInputFields from '@/components/Inscription/ResponsableInputFields'; +import PaymentMethodSelector from '@/components/Inscription/PaymentMethodSelector'; +import ProgressStep from '@/components/ProgressStep'; /** * Composant de formulaire d'inscription partagé @@ -41,7 +40,6 @@ export default function InscriptionFormShared({ errors = {}, // Nouvelle prop pour les erreurs }) { // États pour gérer les données du formulaire - const [isLoading, setIsLoading] = useState(true); const [formData, setFormData] = useState({ id: '', last_name: '', @@ -67,44 +65,13 @@ export default function InscriptionFormShared({ const [schoolFileTemplates, setSchoolFileTemplates] = useState([]); const [parentFileTemplates, setParentFileTemplates] = useState([]); const [currentPage, setCurrentPage] = useState(1); + const [isSignatureComplete, setIsSignatureComplete] = useState(false); - const isCurrentPageValid = () => { - if (currentPage === 1) { - const isValid = validateStudentInfo(formData); - return isValid; - } - return true; - }; + const [isPage1Valid, setIsPage1Valid] = useState(false); + const [isPage2Valid, setIsPage2Valid] = useState(false); + const [isPage3Valid, setIsPage3Valid] = useState(false); - // Chargement initial des données - // Mettre à jour les données quand initialData change - useEffect(() => { - if (studentId) { - fetchRegisterForm(studentId).then((data) => { - logger.debug(data); - - setFormData({ - id: data?.student?.id || '', - last_name: data?.student?.last_name || '', - first_name: data?.student?.first_name || '', - address: data?.student?.address || '', - birth_date: data?.student?.birth_date || '', - birth_place: data?.student?.birth_place || '', - birth_postal_code: data?.student?.birth_postal_code || '', - nationality: data?.student?.nationality || '', - attending_physician: data?.student?.attending_physician || '', - level: data?.student?.level || '', - registration_payment: data?.registration_payment || '', - tuition_payment: data?.tuition_payment || '', - totalRegistrationFees: data?.totalRegistrationFees, - totalTuitionFees: data?.totalTuitionFees, - }); - setGuardians(data?.student?.guardians || []); - }); - - setIsLoading(false); - } - }, [studentId]); + const [hasInteracted, setHasInteracted] = useState(false); useEffect(() => { fetchSchoolFileTemplatesFromRegistrationFiles(studentId).then((data) => { @@ -159,11 +126,6 @@ export default function InscriptionFormShared({ ); }; - // Fonctions de gestion du formulaire et des fichiers - const updateFormField = (field, value) => { - setFormData((prev) => ({ ...prev, [field]: value })); - }; - const handleFileUpload = (file, selectedFile) => { if (!file || !selectedFile) { logger.error('Données manquantes pour le téléversement.'); @@ -265,19 +227,6 @@ export default function InscriptionFormShared({ onSubmit(data); }; - // Soumission du formulaire - const handleSave = (e) => { - e.preventDefault(); - const data = { - student: { - ...formData, - guardians, - }, - establishment: selectedEstablishmentId, - }; - onSubmit(data); - }; - const handleNextPage = () => { setCurrentPage(currentPage + 1); }; @@ -286,96 +235,163 @@ export default function InscriptionFormShared({ setCurrentPage(currentPage - 1); }; - // Affichage du loader pendant le chargement - if (isLoading) return ; + const stepTitles = { + 1: 'Elève', + 2: 'Responsables légaux', + 3: "Modalités de paiement", + 4: "Formulaires à signer", + 5: "Pièces à fournir", + 6: "Validation" + }; + + const steps = [ + 'Élève', + 'Responsable', + 'Paiement', + 'Formulaires', + 'Documents parent', + 'Validation' + ]; + + const isStepValid = (stepNumber) => { + switch (stepNumber) { + case 1: + return isPage1Valid; + case 2: + return isPage2Valid; + case 3: + return isPage3Valid; + default: + return false; + } + }; // Rendu du composant return (
-
- - {/* Page 1 : Informations de l'élève et Responsables */} + + +
+ {/* Page 1 : Informations sur l'élève */} {currentPage === 1 && ( )} + {/* Page 2 : Informations sur les responsables légaux */} + {currentPage === 2 && ( + + )} + + {/* Page 3 : Informations sur les modalités de paiement */} + {currentPage === 3 && ( + <> + + + )} + {/* Pages suivantes : Section Fichiers d'inscription */} - {currentPage > 1 && currentPage <= schoolFileTemplates.length + 1 && ( -
-
- {/* Titre du document */} -
-

- {schoolFileTemplates[currentPage - 2].name || - 'Document sans nom'} -

-

- {schoolFileTemplates[currentPage - 2].description || - 'Aucune description disponible pour ce document.'} -

-
+ {currentPage === 4 && ( +
+ {schoolFileTemplates.length > 0 && ( +
+ {/* Titre du document */} +
+

+ {schoolFileTemplates[currentPage - 2].name || + 'Document sans nom'} +

+

+ {schoolFileTemplates[currentPage - 2].description || + 'Aucune description disponible pour ce document.'} +

+
- {/* Affichage du formulaire ou du document */} - {schoolFileTemplates[currentPage - 2].file === null ? ( - { - downloadTemplate(schoolFileTemplates[currentPage - 2].slug) - .then((data) => fetch(data)) - .then((response) => response.blob()) - .then((blob) => { - const file = new File( - [blob], - `${schoolFileTemplates[currentPage - 2].name}.pdf`, - { type: blob.type } - ); - const updateData = new FormData(); - updateData.append('file', file); + {/* Affichage du formulaire ou du document */} + {schoolFileTemplates[currentPage - 2].file === null ? ( + { + downloadTemplate(schoolFileTemplates[currentPage - 2].slug) + .then((data) => fetch(data)) + .then((response) => response.blob()) + .then((blob) => { + const file = new File( + [blob], + `${schoolFileTemplates[currentPage - 2].name}.pdf`, + { type: blob.type } + ); + const updateData = new FormData(); + updateData.append('file', file); - return editRegistrationSchoolFileTemplates( - schoolFileTemplates[currentPage - 2].id, - updateData, - csrfToken - ); - }) - .then((data) => { - logger.debug('EDIT TEMPLATE : ', data); - }) - .catch((error) => { - logger.error('error editing template : ', error); - }); - }} - /> - ) : ( -