diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js index f3c904e..5f34679 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js @@ -21,7 +21,6 @@ import { Upload, } from 'lucide-react'; import Modal from '@/components/Modal'; -import InscriptionForm from '@/components/Inscription/InscriptionForm'; import { useEstablishment } from '@/context/EstablishmentContext'; import { diff --git a/Front-End/src/components/Inscription/InscriptionForm.js b/Front-End/src/components/Inscription/InscriptionForm.js deleted file mode 100644 index 7d2140e..0000000 --- a/Front-End/src/components/Inscription/InscriptionForm.js +++ /dev/null @@ -1,967 +0,0 @@ -import { useState, useEffect, useRef } from 'react'; -import { User, Mail } from 'lucide-react'; -import InputTextIcon from '@/components/InputTextIcon'; -import ToggleSwitch from '@/components/ToggleSwitch'; -import Button from '@/components/Button'; -import Table from '@/components/Table'; -import FeesSection from '@/components/Structure/Tarification/FeesSection'; -import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection'; -import SectionTitle from '@/components/SectionTitle'; -import ProgressStep from '@/components/ProgressStep'; -import logger from '@/utils/logger'; -import Popup from '@/components/Popup'; -import InputPhone from '../InputPhone'; -import { PhoneLabel } from '../PhoneLabel'; -import CheckBox from '@/components/CheckBox'; -import RadioList from '@/components/RadioList'; -import SelectChoice from '@/components/SelectChoice'; -import { getCurrentSchoolYear, getNextSchoolYear } from '@/utils/Date'; - -const InscriptionForm = ({ - students, - registrationDiscounts, - tuitionDiscounts, - registrationFees, - tuitionFees, - profiles, - onSubmit, - groups, - showOnlyStep2 = false, -}) => { - const [formData, setFormData] = useState(() => { - if (showOnlyStep2) { - return { - guardianLastName: '', - guardianFirstName: '', - guardianEmail: '', - guardianPhone: '', - selectedGuardians: [], - responsableType: 'new', - }; - } - return { - studentLastName: '', - studentFirstName: '', - guardianLastName: '', - guardianFirstName: '', - guardianEmail: '', - guardianPhone: '', - selectedGuardians: [], - responsableType: 'new', - autoMail: false, - selectedRegistrationDiscounts: [], - selectedRegistrationFees: registrationFees.map((fee) => fee.id), - selectedTuitionDiscounts: [], - selectedTuitionFees: [], - selectedFileGroup: null, // Ajout du groupe de fichiers sélectionné - schoolYear: getCurrentSchoolYear(), - }; - }); - - const [step, setStep] = useState(1); - const [selectedStudent, setSelectedEleve] = useState(''); - const [existingGuardians, setExistingGuardians] = useState([]); - const [totalRegistrationAmount, setTotalRegistrationAmount] = useState(0); - const [totalTuitionAmount, setTotalTuitionAmount] = useState(0); - const [filteredStudents, setFilteredStudents] = useState(students); - - const [popupVisible, setPopupVisible] = useState(false); - const [popupMessage, setPopupMessage] = useState(''); - - const formDataRef = useRef(formData); - - const stepTitles = { - 1: 'Nouvel élève', - 2: 'Nouveau Responsable', - 3: "Frais d'inscription", - 4: 'Frais de scolarité', - 5: 'Documents requis', - 6: 'Récapitulatif', - }; - - const steps = [ - 'Élève', - 'Responsable', - 'Inscription', - 'Scolarité', - 'Documents', - 'Récap', - ]; - - const isStep1Valid = formData.studentLastName && formData.studentFirstName; - const isStep2Valid = - formData.selectedGuardians.length > 0 || - (!formData.emailError && - formData.guardianEmail.length > 0 && - filteredStudents.length === 0); - const isStep3Valid = formData.selectedRegistrationFees?.length > 0; - const isStep4Valid = formData.selectedTuitionFees?.length > 0; - const isStep5Valid = formData.selectedFileGroup !== null; - const isStep6Valid = - isStep1Valid && - isStep2Valid && - isStep3Valid && - isStep4Valid && - isStep5Valid; - - const isStepValid = (stepNumber) => { - switch (stepNumber) { - case 1: - return isStep1Valid; - case 2: - return isStep2Valid; - case 3: - return isStep3Valid; - case 4: - return isStep4Valid; - case 5: - return isStep5Valid; - case 6: - return isStep6Valid; - default: - return false; - } - }; - - useEffect(() => { - if (!showOnlyStep2) { - // Calcul du montant total des frais d'inscription lors de l'initialisation - const initialTotalRegistrationAmount = calculateFinalRegistrationAmount( - registrationFees.map((fee) => fee.id), - [] - ); - setTotalRegistrationAmount(initialTotalRegistrationAmount); - } - }, [registrationDiscounts, registrationFees]); - - useEffect(() => { - formDataRef.current = formData; // Mettre à jour la référence à chaque changement de formData - }, [formData]); - - const handleToggleChange = () => { - setFormData({ ...formData, autoMail: !formData.autoMail }); - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prevState) => ({ - ...prevState, - [name]: value, - })); - }; - - const validateAndSubmit = async () => { - const existingProfile = profiles.find( - (profile) => profile.email === formData.guardianEmail - ); - - if (existingProfile) { - console.log('existingProfile : ', existingProfile); - await setFormData((prevData) => ({ - ...prevData, - guardianEmail: existingProfile.email, // Mettre à jour le champ guardianEmail avec l'email du profil - isExistingParentProfile: true, // Indiquer que le profil est un parent existant - existingProfileId: existingProfile.id, - })); - } - - // Utiliser la dernière version de formData via formDataRef - logger.debug('Submitting form data:', formDataRef.current); - onSubmit(formDataRef.current); - }; - - const nextStep = async () => { - if (step === 2) { - const existingProfile = profiles.find( - (profile) => profile.email === formData.guardianEmail - ); - - if (existingProfile) { - console.log('existingProfile : ', existingProfile); - await setFormData((prevData) => ({ - ...prevData, - guardianEmail: existingProfile.email, // Mettre à jour le champ guardianEmail avec l'email du profil - isExistingParentProfile: true, // Indiquer que le profil est un parent existant - existingProfileId: existingProfile.id, - })); - } - } - - if (!showOnlyStep2 && step < steps.length) { - setStep(step + 1); - } - }; - - const prevStep = () => { - if (!showOnlyStep2 && step > 1) { - setStep(step - 1); - } - }; - - const handleEleveSelection = (student) => { - setSelectedEleve(student); - setFormData((prevData) => ({ - ...prevData, - selectedGuardians: [], - })); - setExistingGuardians(student.guardians); - }; - - const handleResponsableSelection = (guardianId, guardianEmail) => { - setFormData((prevData) => { - const isSelected = prevData.selectedGuardians.includes(guardianId); - const selectedGuardians = isSelected - ? prevData.selectedGuardians.filter((id) => id !== guardianId) // Retirer le guardian si déjà sélectionné - : [...prevData.selectedGuardians, guardianId]; // Ajouter le guardian s'il n'est pas sélectionné - - // Mettre à jour l'email uniquement si un guardian est sélectionné - const updatedGuardianEmail = isSelected ? '' : guardianEmail; - - // Si aucun guardian n'est sélectionné, réinitialiser le tableau des élèves - if (selectedGuardians.length === 0) { - setFilteredStudents(students); // Réafficher tous les élèves - setSelectedEleve(null); - } - - return { - ...prevData, - selectedGuardians, - guardianEmail: updatedGuardianEmail, - }; - }); - }; - - const submit = () => { - setTimeout(() => { - logger.debug('Submitting form data:', formData); - onSubmit(formData); - }, 0); - }; - - const handleRegistrationFeeSelection = (feeId) => { - setFormData((prevData) => { - const selectedRegistrationFees = - prevData.selectedRegistrationFees.includes(feeId) - ? prevData.selectedRegistrationFees.filter((id) => id !== feeId) - : [...prevData.selectedRegistrationFees, feeId]; - const finalAmount = calculateFinalRegistrationAmount( - selectedRegistrationFees, - prevData.selectedRegistrationDiscounts - ); - setTotalRegistrationAmount(finalAmount); - return { ...prevData, selectedRegistrationFees }; - }); - }; - - const handleTuitionFeeSelection = (feeId) => { - setFormData((prevData) => { - const selectedTuitionFees = prevData.selectedTuitionFees.includes(feeId) - ? prevData.selectedTuitionFees.filter((id) => id !== feeId) - : [...prevData.selectedTuitionFees, feeId]; - const finalAmount = calculateFinalTuitionAmount( - selectedTuitionFees, - prevData.selectedTuitionDiscounts - ); - setTotalTuitionAmount(finalAmount); - return { ...prevData, selectedTuitionFees }; - }); - }; - - const handleRegistrationDiscountSelection = (discountId) => { - setFormData((prevData) => { - const selectedRegistrationDiscounts = - prevData.selectedRegistrationDiscounts.includes(discountId) - ? prevData.selectedRegistrationDiscounts.filter( - (id) => id !== discountId - ) - : [...prevData.selectedRegistrationDiscounts, discountId]; - const finalAmount = calculateFinalRegistrationAmount( - prevData.selectedRegistrationFees, - selectedRegistrationDiscounts - ); - setTotalRegistrationAmount(finalAmount); - return { ...prevData, selectedRegistrationDiscounts }; - }); - }; - - const handleTuitionDiscountSelection = (discountId) => { - setFormData((prevData) => { - const selectedTuitionDiscounts = - prevData.selectedTuitionDiscounts.includes(discountId) - ? prevData.selectedTuitionDiscounts.filter((id) => id !== discountId) - : [...prevData.selectedTuitionDiscounts, discountId]; - const finalAmount = calculateFinalTuitionAmount( - prevData.selectedTuitionFees, - selectedTuitionDiscounts - ); - setTotalTuitionAmount(finalAmount); - return { ...prevData, selectedTuitionDiscounts }; - }); - }; - - const calculateFinalRegistrationAmount = ( - selectedRegistrationFees, - selectedRegistrationDiscounts - ) => { - const totalFees = selectedRegistrationFees.reduce((sum, feeId) => { - const fee = registrationFees.find((f) => f.id === feeId); - if (fee && !isNaN(parseFloat(fee.base_amount))) { - return sum + parseFloat(fee.base_amount); - } - return sum; - }, 0); - - const totalDiscounts = selectedRegistrationDiscounts.reduce( - (sum, discountId) => { - const discount = registrationDiscounts.find((d) => d.id === discountId); - if (discount) { - if ( - discount.discount_type === 0 && - !isNaN(parseFloat(discount.amount)) - ) { - // Currency - return sum + parseFloat(discount.amount); - } else if ( - discount.discount_type === 1 && - !isNaN(parseFloat(discount.amount)) - ) { - // Percent - return sum + (totalFees * parseFloat(discount.amount)) / 100; - } - } - return sum; - }, - 0 - ); - - const finalAmount = totalFees - totalDiscounts; - - return finalAmount.toFixed(2); - }; - - const calculateFinalTuitionAmount = ( - selectedTuitionFees, - selectedTuitionDiscounts - ) => { - const totalFees = selectedTuitionFees.reduce((sum, feeId) => { - const fee = tuitionFees.find((f) => f.id === feeId); - if (fee && !isNaN(parseFloat(fee.base_amount))) { - return sum + parseFloat(fee.base_amount); - } - return sum; - }, 0); - - const totalDiscounts = selectedTuitionDiscounts.reduce( - (sum, discountId) => { - const discount = tuitionDiscounts.find((d) => d.id === discountId); - if (discount) { - if ( - discount.discount_type === 0 && - !isNaN(parseFloat(discount.amount)) - ) { - // Currency - return sum + parseFloat(discount.amount); - } else if ( - discount.discount_type === 1 && - !isNaN(parseFloat(discount.amount)) - ) { - // Percent - return sum + (totalFees * parseFloat(discount.amount)) / 100; - } - } - return sum; - }, - 0 - ); - - const finalAmount = totalFees - totalDiscounts; - - return finalAmount.toFixed(2); - }; - - return ( -
- {!showOnlyStep2 && ( - - )} - - {step === 1 && ( -
- {/* Sélection de l'année scolaire */} - - setFormData((prevData) => ({ - ...prevData, - schoolYear: e.target.value, - })) - } - className="w-full mt-4" - /> - - -
- )} - - {step === 2 && ( -
- {/* Nom, Prénom et Téléphone */} - - - - - {/* Email du responsable */} - { - const email = e.target.value; - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - - setFormData((prevData) => ({ - ...prevData, - guardianEmail: email, - emailError: - email.length > 0 && // Le champ de mail est non null - !emailRegex.test(email) && - filteredStudents.length === 0 // Format invalide ou aucun résultat - ? "Format d'email invalide ou aucun élève trouvé" - : '', - })); - - // Filtrer les responsables affichés dans le tableau - const filteredGuardians = students - .flatMap((student) => student.guardians) // Récupérer tous les guardians - .filter((guardian) => - guardian.associated_profile_email - .toLowerCase() - .includes(email.toLowerCase()) - ); - - // Filtrer les élèves en fonction des responsables - const filteredStudents = students.filter((student) => - student.guardians.some((guardian) => - filteredGuardians.some( - (filteredGuardian) => filteredGuardian.id === guardian.id - ) - ) - ); - - setFilteredStudents(filteredStudents); // Mettre à jour l'état des élèves filtrés - - // Réinitialiser existingGuardians et selectedStudent si l'élève sélectionné n'est plus dans le tableau - if ( - !filteredStudents.some( - (student) => student.id === selectedStudent?.id - ) - ) { - setSelectedEleve(null); // Réinitialiser l'élève sélectionné - setExistingGuardians([]); // Réinitialiser les responsables associés - setFormData((prevData) => ({ - ...prevData, - selectedGuardians: [], // Réinitialiser les responsables sélectionnés - })); - } - }} - errorMsg={formData.emailError} - className="w-full mt-4" - /> - - {/* Tableau des élèves */} -
-
- - - - - - - - - {filteredStudents.map( - ( - student, - index // Utiliser les élèves filtrés - ) => ( - handleEleveSelection(student)} - > - - - - ) - )} - -
NomPrénom
- {student.last_name} - - {student.first_name} -
-
- {selectedStudent && ( -
-

- Responsables associés à {selectedStudent.last_name}{' '} - {selectedStudent.first_name} : -

- {existingGuardians.map((guardian) => ( -
- - setFormData((prevData) => { - const isSelected = - prevData.selectedGuardians.includes(guardian.id); - const updatedSelectedGuardians = isSelected - ? prevData.selectedGuardians.filter( - (id) => id !== guardian.id - ) // Retirer le guardian si décoché - : [...prevData.selectedGuardians, guardian.id]; // Ajouter le guardian si coché - - return { - ...prevData, - selectedGuardians: updatedSelectedGuardians, - }; - }) - } - fieldName="selectedGuardians" - itemLabelFunc={() => - guardian.last_name && guardian.first_name - ? `${guardian.last_name} ${guardian.first_name} - ${guardian.associated_profile_email}` - : `${guardian.associated_profile_email}` - } - /> -
- ))} -
- )} -
-
- )} - - {step === 3 && ( -
- {registrationFees.length > 0 ? ( - <> -
- -
- -
- {registrationDiscounts.length > 0 ? ( - - ) : ( -

- Information - - {' '} - Aucune réduction n'a été créée sur les frais - d'inscription. - -

- )} -
- - MONTANT TOTAL, - }, - { - name: 'TOTAL', - transform: () => {totalRegistrationAmount} €, - }, - ]} - defaultTheme="bg-cyan-100" - /> - - ) : ( -

- Attention! - - {' '} - Aucun frais d'inscription n'a été créé. - -

- )} - - )} - - {step === 4 && ( -
- {tuitionFees.length > 0 ? ( - <> -
- -
- -
- {tuitionDiscounts.length > 0 ? ( - - ) : ( -

- Information - - {' '} - Aucune réduction n'a été créée sur les frais de - scolarité. - -

- )} -
- -
MONTANT TOTAL, - }, - { - name: 'TOTAL', - transform: () => {totalTuitionAmount} €, - }, - ]} - defaultTheme="bg-cyan-100" - /> - - ) : ( -

- Attention! - - {' '} - Aucun frais de scolarité n'a été créé. - -

- )} - - )} - - {step === 5 && ( -
- {groups.length > 0 ? ( -
-

Sélectionnez un groupe de documents

- ({ - id: group.id, - label: `${group.name}${ - group.description ? ` (${group.description})` : '' - }`, - }))} - formData={{ - ...formData, - selectedFileGroup: parseInt(formData.selectedFileGroup, 10), - }} - handleChange={(e) => { - const value = parseInt(e.target.value, 10); - setFormData((prevData) => ({ - ...prevData, - selectedFileGroup: value, - })); - }} - fieldName="selectedFileGroup" - className="mt-4" - /> -
- ) : ( -

- Attention! - - Aucun groupe de documents n'a été créé. - -

- )} -
- )} - - {step === steps.length && ( -
-
-
-

Élève

-
- - - - - - - - - - - - -
NomPrénom
- {formData.studentLastName} - - {formData.studentFirstName} -
- -
-

Responsable(s)

- {formData.responsableType === 'new' && ( - - - - - - - - - - - - - -
EmailTéléphone
- {formData.guardianEmail} - - -
- )} - {formData.responsableType === 'existing' && selectedStudent && ( -
-

- Associé(s) à : {selectedStudent.nom}{' '} - {selectedStudent.prenom} -

- - - - - - - - - - {existingGuardians - .filter((guardian) => - formData.selectedGuardians.includes(guardian.id) - ) - .map((guardian) => ( - - - - - - ))} - -
NomPrénomEmail
- {guardian.last_name} - - {guardian.first_name} - - {guardian.associated_profile_email} -
-
- )} -
-
-
- -
-
- )} - -
- {showOnlyStep2 ? ( - <> -
- - setPopupVisible(false)} - onCancel={() => setPopupVisible(false)} - /> - - ); -}; - -export default InscriptionForm;