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'; 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é }; }); 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 && (
)} {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)} > ) )}
Nom Pré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

Nom Prénom
{formData.studentLastName} {formData.studentFirstName}

Responsable(s)

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

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

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