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 */}
| Nom |
Prénom |
{filteredStudents.map(
(
student,
index // Utiliser les élèves filtrés
) => (
handleEleveSelection(student)}
>
|
{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}
| Nom |
Prénom |
Email |
{existingGuardians
.filter((guardian) =>
formData.selectedGuardians.includes(guardian.id)
)
.map((guardian) => (
|
{guardian.last_name}
|
{guardian.first_name}
|
{guardian.associated_profile_email}
|
))}
)}
)}
{showOnlyStep2 ? (
<>
>
) : (
<>
{step > 1 && (
)}
{step < steps.length ? (
) : (
)}
>
)}
setPopupVisible(false)}
onCancel={() => setPopupVisible(false)}
/>
);
};
export default InscriptionForm;