refactor: Revue de la modale permettant de créer un dossier

d'inscription
This commit is contained in:
N3WT DE COMPET
2025-01-26 15:43:11 +01:00
parent 1c4d96d4c3
commit 665625e028
5 changed files with 442 additions and 361 deletions

View File

@ -805,8 +805,7 @@ const handleFileUpload = ({file, name, is_required, order}) => {
<Modal
isOpen={isOpen}
setIsOpen={setIsOpen}
title={"Création d'un nouveau dossier d'inscription"}
size='sm:w-1/4'
title={"Nouveau dossier d'inscription"}
ContentComponent={() => (
<InscriptionForm students={students}
registrationDiscounts={registrationDiscounts}

View File

@ -5,9 +5,11 @@ 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 '../Structure/Tarification/DiscountsSection';
import DiscountsSection from '@/components/Structure/Tarification/DiscountsSection';
import Navigation from '@/components/Navigation';
import StepTitle from '@/components/StepTitle';
const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, registrationFees, tuitionFees, onSubmit }) => {
const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, registrationFees, tuitionFees, onSubmit, currentStep }) => {
const [formData, setFormData] = useState({
studentLastName: '',
studentFirstName: '',
@ -22,12 +24,47 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
selectedTuitionFees: []
});
const [step, setStep] = useState(1);
const [step, setStep] = useState(currentStep || 1);
const [selectedStudent, setSelectedEleve] = useState('');
const [existingGuardians, setExistingGuardians] = useState([]);
const [totalRegistrationAmount, setTotalRegistrationAmount] = useState(0);
const [totalTuitionAmount, setTotalTuitionAmount] = useState(0);
const maxStep = 6
const stepTitles = {
1: 'Nouvel élève',
2: 'Nouveau Responsable',
3: "Frais d'inscription",
4: 'Frais de scolarité',
5: 'Récapitulatif'
};
const steps = ['1', '2', '3', '4', 'Récap'];
const isStep1Valid = formData.studentLastName && formData.studentFirstName;
const isStep2Valid = (
(formData.responsableType === "new" && formData.guardianEmail.length > 0) ||
(formData.responsableType === "existing" && formData.selectedGuardians.length > 0)
);
const isStep3Valid = formData.selectedRegistrationFees.length > 0;
const isStep4Valid = formData.selectedTuitionFees.length > 0;
const isStep5Valid = isStep1Valid && isStep2Valid && isStep3Valid && isStep4Valid;
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;
default:
return false;
}
};
useEffect(() => {
// Calcul du montant total des frais d'inscription lors de l'initialisation
@ -39,6 +76,10 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
}, [registrationDiscounts, registrationFees]);
useEffect(() => {
setStep(currentStep || 1);
}, [currentStep]);
const handleToggleChange = () => {
setFormData({ ...formData, autoMail: !formData.autoMail });
};
@ -52,7 +93,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
};
const nextStep = () => {
if (step < maxStep) {
if (step < steps.length) {
setStep(step + 1);
}
};
@ -181,19 +222,18 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
return finalAmount.toFixed(2);
};
const isLabelAttenuated = (item) => {
return !formData.selectedRegistrationDiscounts.includes(parseInt(item.id));
};
const isLabelFunction = (item) => {
return item.name + ' : ' + item.amount
};
return (
<div className="space-y-4 mt-8">
<div className="space-y-4 mt-6">
<Navigation
steps={steps}
step={step}
setStep={setStep}
isStepValid={isStepValid}
stepTitles={stepTitles}
/>
{step === 1 && (
<div>
<h2 className="text-l font-bold mb-4">Nouvel élève</h2>
<div className="mt-6">
<InputTextIcon
name="studentLastName"
type="text"
@ -217,8 +257,16 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
{step === 2 && (
<div className="mt-6">
<h2 className="text-l font-bold mb-4">Responsable(s)</h2>
<div className="flex flex-col space-y-4">
<InputTextIcon
name="guardianPhone"
type="tel"
IconItem={Phone}
placeholder="Numéro de téléphone (optionnel)"
value={formData.guardianPhone}
onChange={handleChange}
className="w-full mt-4"
/>
<div className="flex flex-col space-y-4 mt-6">
<label className="flex items-center space-x-3">
<input
type="radio"
@ -304,23 +352,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
)}
{step === 3 && (
<div className="mt-6">
<h2 className="text-l font-bold mb-4">Téléphone (optionnel)</h2>
<InputTextIcon
name="guardianPhone"
type="tel"
IconItem={Phone}
placeholder="Numéro de téléphone"
value={formData.guardianPhone}
onChange={handleChange}
className="w-full mt-4"
/>
</div>
)}
{step === 4 && (
<div>
<h2 className="text-l font-bold mb-4">Frais d'inscription</h2>
{registrationFees.length > 0 ? (
<>
<div className="mb-4">
@ -332,7 +364,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
handleFeeSelection={handleRegistrationFeeSelection}
/>
</div>
<h2 className="text-l font-bold mb-4">Réductions</h2>
<StepTitle title='Réductions' />
<div className="mb-4">
{registrationDiscounts.length > 0 ? (
<DiscountsSection
@ -349,6 +381,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
</p>
)}
</div>
<StepTitle title='Montant total' />
<Table
data={[ {id: 1}]}
columns={[
@ -371,12 +404,10 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
</p>
)}
</div>
)}
{step === 5 && (
{step === 4 && (
<div>
<h2 className="text-l font-bold mb-4">Frais de scolarité</h2>
{tuitionFees.length > 0 ? (
<>
<div className="mb-4">
@ -388,7 +419,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
handleFeeSelection={handleTuitionFeeSelection}
/>
</div>
<h2 className="text-l font-bold mb-4">Réductions</h2>
<StepTitle title='Réductions' />
<div className="mb-4">
{tuitionDiscounts.length > 0 ? (
<DiscountsSection
@ -405,6 +436,7 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
</p>
)}
</div>
<StepTitle title='Montant total' />
<Table
data={[ {id: 1}]}
columns={[
@ -427,12 +459,10 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
</p>
)}
</div>
)}
{step === maxStep && (
{step === steps.length && (
<div>
<h2 className="text-l font-bold mb-4">Récapitulatif</h2>
<div className="space-y-4">
<section>
<h3 className="font-bold">Élève</h3>
@ -512,24 +542,31 @@ const InscriptionForm = ( { students, registrationDiscounts, tuitionDiscounts, r
secondary
name="Previous" />
)}
{step < maxStep ? (
{step < steps.length ? (
<Button text="Suivant"
onClick={nextStep}
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
(step === 1 && (!formData.studentLastName || !formData.studentFirstName)) ||
(step === 2 && formData.responsableType === "new" && !formData.guardianEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedGuardians.length === 0)
(
(step === 1 && !isStep1Valid) ||
(step === 2 && !isStep2Valid) ||
(step === 3 && !isStep3Valid) ||
(step === 4 && !isStep4Valid)
)
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
}`}
disabled={(step === 1 && (!formData.studentLastName || !formData.studentFirstName)) ||
(step === 2 && formData.responsableType === "new" && !formData.guardianEmail) ||
(step === 2 && formData.responsableType === "existing" && formData.selectedGuardians.length === 0)
disabled={
(
(step === 1 && !isStep1Valid) ||
(step === 2 && !isStep2Valid) ||
(step === 3 && !isStep3Valid) ||
(step === 4 && !isStep4Valid)
)
}
primary
name="Next" />
) : (
<Button text="Créer"
<Button text="Valider"
onClick={submit}
className="px-4 py-2 bg-emerald-500 text-white rounded-md shadow-sm hover:bg-emerald-600 focus:outline-none"
primary

View File

@ -1,13 +1,12 @@
import * as Dialog from '@radix-ui/react-dialog';
import Button from '@/components/Button';
const Modal = ({ isOpen, setIsOpen, title, ContentComponent, size }) => {
const Modal = ({ isOpen, setIsOpen, title, ContentComponent }) => {
return (
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
<Dialog.Content className="fixed inset-0 flex items-center justify-center">
<div className={`inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:p-6 ${size ? size : 'sm:w-full' }`} style={{ minWidth: '300px', width: 'auto' }}>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle" style={{ width: '600px', maxWidth: '90%' }}>
<div className="flex justify-between items-start">
<Dialog.Title className="text-xl font-medium text-gray-900">
{title}

View File

@ -0,0 +1,30 @@
import React from 'react';
import StepTitle from '@/components/StepTitle';
const Navigation = ({ steps, step, setStep, isStepValid, stepTitles }) => {
return (
<div className="relative mb-4">
<div className="relative flex justify-between">
{steps.map((stepLabel, index) => {
const isCurrentStep = step === index + 1;
return (
<div key={index} className="flex flex-col items-center">
<div className={`mb-4 ${isCurrentStep ? 'text-gray-500 font-extrabold' : 'text-gray-500'}`}>
{stepLabel}
</div>
<div
className={`w-4 h-4 rounded-full mb-4 ${isStepValid(index + 1) ? 'bg-emerald-500' : 'bg-yellow-300'} cursor-pointer`}
onClick={() => setStep(index + 1)}
style={{ transform: 'translateY(-50%)' }}
></div>
</div>
);
})}
</div>
<StepTitle title={stepTitles[step]} />
</div>
);
};
export default Navigation;

View File

@ -0,0 +1,16 @@
import React from 'react';
const StepTitle = ({ title }) => {
return (
<div className="relative mb-4">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-300"></div>
</div>
<div className="relative flex justify-center">
<div className="px-4 bg-white text-gray-500">{title}</div>
</div>
</div>
);
};
export default StepTitle;