mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Ordonnancement de l'inscription sur plusieurs pages + contrôle des
champs remplis dans le formulaire
This commit is contained in:
@ -1,79 +1,135 @@
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import InputText from '@/components/InputText';
|
||||
import SelectChoice from '@/components/SelectChoice';
|
||||
import ResponsableInputFields from '@/components/Inscription/ResponsableInputFields';
|
||||
import PaymentMethodSelector from '@/components/Inscription/PaymentMethodSelector';
|
||||
import Loader from '@/components/Loader';
|
||||
import {
|
||||
fetchRegisterForm
|
||||
} from '@/app/actions/subscriptionAction';
|
||||
import logger from '@/utils/logger';
|
||||
import SectionHeader from '@/components/SectionHeader';
|
||||
import { User } from 'lucide-react';
|
||||
|
||||
const levels = [
|
||||
{ value: '1', label: 'TPS - Très Petite Section' },
|
||||
{ value: '2', label: 'PS - Petite Section' },
|
||||
{ value: '3', label: 'MS - Moyenne Section' },
|
||||
{ value: '4', label: 'GS - Grande Section' },
|
||||
{ value: '5', label: 'CP' },
|
||||
{ value: '6', label: 'CE1' },
|
||||
{ value: '7', label: 'CE2' },
|
||||
{ value: '8', label: 'CM1' },
|
||||
{ value: '9', label: 'CM2' },
|
||||
];
|
||||
|
||||
const paymentModesOptions = [
|
||||
{ id: 1, name: 'Prélèvement SEPA' },
|
||||
{ id: 2, name: 'Virement' },
|
||||
{ id: 3, name: 'Chèque' },
|
||||
{ id: 4, name: 'Espèce' },
|
||||
];
|
||||
|
||||
// Fonction de validation pour vérifier les champs requis
|
||||
export function validateStudentInfo(formData) {
|
||||
const requiredFields = [
|
||||
'last_name',
|
||||
'first_name',
|
||||
'nationality',
|
||||
'birth_date',
|
||||
'birth_place',
|
||||
'birth_postal_code',
|
||||
'address',
|
||||
'attending_physician',
|
||||
'level',
|
||||
];
|
||||
|
||||
const isValid = requiredFields.every((field) => {
|
||||
const value = formData[field];
|
||||
return typeof value === 'string' ? value.trim() !== '' : Boolean(value);
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
export default function StudentInfoForm({
|
||||
studentId,
|
||||
formData,
|
||||
updateFormField,
|
||||
guardians,
|
||||
setFormData,
|
||||
setGuardians,
|
||||
registrationPaymentModes,
|
||||
tuitionPaymentModes,
|
||||
errors,
|
||||
setIsPageValid,
|
||||
hasInteracted,
|
||||
setHasInteracted
|
||||
}) {
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (studentId && !hasInteracted) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [studentId, hasInteracted]);
|
||||
|
||||
useEffect(() => {
|
||||
const isValid = !Object.keys(formData).some((field) => getLocalError(field) !== '');
|
||||
setIsPageValid(isValid);
|
||||
}, [formData, hasInteracted, setIsPageValid]);
|
||||
|
||||
const getError = (field) => {
|
||||
return errors?.student?.[field]?.[0];
|
||||
};
|
||||
|
||||
const getLocalError = (field) => {
|
||||
if (!hasInteracted) {
|
||||
return ''; // Ne pas afficher les erreurs locales au premier chargement
|
||||
}
|
||||
if (
|
||||
// Student Form
|
||||
( field === 'last_name' && (!formData.last_name || formData.last_name.trim() === '') ) ||
|
||||
( field === 'first_name' && (!formData.first_name || formData.first_name.trim() === '') ) ||
|
||||
( field === 'nationality' && (!formData.nationality || formData.nationality.trim() === '') ) ||
|
||||
( field === 'birth_date' && (!formData.birth_date || formData.birth_date.trim() === '') ) ||
|
||||
( field === 'birth_place' && (!formData.birth_place || formData.birth_place.trim() === '') ) ||
|
||||
( field === 'birth_postal_code' && (!formData.birth_postal_code || String(formData.birth_postal_code).trim() === '') ) ||
|
||||
( field === 'address' && (!formData.address || formData.address.trim() === '') ) ||
|
||||
( field === 'attending_physician' && (!formData.attending_physician || formData.attending_physician.trim() === '') ) ||
|
||||
( field === 'level' && (!formData.level || String(formData.level).trim() === '') )
|
||||
) {
|
||||
return 'Champs requis';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
const onChange = (field, value) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
|
||||
// Marquer que l'utilisateur a interagi avec le formulaire
|
||||
if (!hasInteracted) {
|
||||
setHasInteracted(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Affichage du loader pendant le chargement
|
||||
if (isLoading) return <Loader />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
||||
<h2 className="text-xl font-bold mb-4 text-gray-800">
|
||||
Informations de l'élève
|
||||
</h2>
|
||||
<SectionHeader
|
||||
icon={User}
|
||||
title={`Informations de l'élève`}
|
||||
description={`Remplissez les champs requis`}
|
||||
/>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<InputText
|
||||
name="last_name"
|
||||
label="Nom"
|
||||
value={formData.last_name}
|
||||
onChange={(e) => updateFormField('last_name', e.target.value)}
|
||||
onChange={(e) => onChange('last_name', e.target.value)}
|
||||
required
|
||||
errorMsg={getError('last_name')}
|
||||
errorMsg={getError('last_name') || getLocalError('last_name')}
|
||||
/>
|
||||
<InputText
|
||||
name="first_name"
|
||||
label="Prénom"
|
||||
value={formData.first_name}
|
||||
onChange={(e) => updateFormField('first_name', e.target.value)}
|
||||
errorMsg={getError('first_name')}
|
||||
onChange={(e) => onChange('first_name', e.target.value)}
|
||||
errorMsg={getError('first_name') || getLocalError('first_name')}
|
||||
required
|
||||
/>
|
||||
<InputText
|
||||
@ -81,43 +137,44 @@ export default function StudentInfoForm({
|
||||
label="Nationalité"
|
||||
value={formData.nationality}
|
||||
required
|
||||
onChange={(e) => updateFormField('nationality', e.target.value)}
|
||||
onChange={(e) => onChange('nationality', e.target.value)}
|
||||
errorMsg={getError('nationality') || getLocalError('nationality')}
|
||||
/>
|
||||
<InputText
|
||||
name="birth_date"
|
||||
type="date"
|
||||
label="Date de Naissance"
|
||||
value={formData.birth_date}
|
||||
onChange={(e) => updateFormField('birth_date', e.target.value)}
|
||||
onChange={(e) => onChange('birth_date', e.target.value)}
|
||||
required
|
||||
errorMsg={getError('birth_date')}
|
||||
errorMsg={getError('birth_date') || getLocalError('birth_date')}
|
||||
/>
|
||||
<InputText
|
||||
name="birth_place"
|
||||
label="Lieu de Naissance"
|
||||
value={formData.birth_place}
|
||||
onChange={(e) => updateFormField('birth_place', e.target.value)}
|
||||
onChange={(e) => onChange('birth_place', e.target.value)}
|
||||
required
|
||||
errorMsg={getError('birth_place')}
|
||||
errorMsg={getError('birth_place') || getLocalError('birth_place')}
|
||||
/>
|
||||
<InputText
|
||||
name="birth_postal_code"
|
||||
label="Code Postal de Naissance"
|
||||
value={formData.birth_postal_code}
|
||||
onChange={(e) =>
|
||||
updateFormField('birth_postal_code', e.target.value)
|
||||
onChange('birth_postal_code', e.target.value)
|
||||
}
|
||||
required
|
||||
errorMsg={getError('birth_postal_code')}
|
||||
errorMsg={getError('birth_postal_code') || getLocalError('birth_postal_code')}
|
||||
/>
|
||||
<div className="md:col-span-2">
|
||||
<InputText
|
||||
name="address"
|
||||
label="Adresse"
|
||||
value={formData.address}
|
||||
onChange={(e) => updateFormField('address', e.target.value)}
|
||||
onChange={(e) => onChange('address', e.target.value)}
|
||||
required
|
||||
errorMsg={getError('address')}
|
||||
errorMsg={getError('address') || getLocalError('address')}
|
||||
/>
|
||||
</div>
|
||||
<InputText
|
||||
@ -125,25 +182,25 @@ export default function StudentInfoForm({
|
||||
label="Médecin Traitant"
|
||||
value={formData.attending_physician}
|
||||
onChange={(e) =>
|
||||
updateFormField('attending_physician', e.target.value)
|
||||
onChange('attending_physician', e.target.value)
|
||||
}
|
||||
required
|
||||
errorMsg={getError('attending_physician')}
|
||||
errorMsg={getError('attending_physician') || getLocalError('attending_physician')}
|
||||
/>
|
||||
<SelectChoice
|
||||
name="level"
|
||||
label="Niveau"
|
||||
placeHolder="Sélectionner un niveau"
|
||||
selected={formData.level}
|
||||
callback={(e) => updateFormField('level', e.target.value)}
|
||||
callback={(e) => onChange('level', e.target.value)}
|
||||
choices={levels}
|
||||
required
|
||||
errorMsg={getError('level')}
|
||||
errorMsg={getError('level') || getLocalError('level')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
||||
{/* <div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
||||
<h2 className="text-xl font-bold mb-4 text-gray-800">Responsables</h2>
|
||||
<ResponsableInputFields
|
||||
guardians={guardians}
|
||||
@ -170,25 +227,27 @@ export default function StudentInfoForm({
|
||||
formData={formData}
|
||||
title="Frais d'inscription"
|
||||
name="registration_payment"
|
||||
updateFormField={updateFormField}
|
||||
onChange={onChange}
|
||||
selected={formData.registration_payment}
|
||||
paymentModes={registrationPaymentModes}
|
||||
paymentModesOptions={paymentModesOptions}
|
||||
amount={formData.totalRegistrationFees}
|
||||
getError={getError}
|
||||
getLocalError={getLocalError}
|
||||
/>
|
||||
|
||||
<PaymentMethodSelector
|
||||
formData={formData}
|
||||
title="Frais de scolarité"
|
||||
name="tuition_payment"
|
||||
updateFormField={updateFormField}
|
||||
onChange={onChange}
|
||||
selected={formData.tuition_payment}
|
||||
paymentModes={tuitionPaymentModes}
|
||||
paymentModesOptions={paymentModesOptions}
|
||||
amount={formData.totalTuitionFees}
|
||||
getError={getError}
|
||||
/>
|
||||
getLocalError={getLocalError}
|
||||
/> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user