mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-04-03 16:51:26 +00:00
279 lines
9.0 KiB
JavaScript
279 lines
9.0 KiB
JavaScript
import InputText from '@/components/Form/InputText';
|
|
import InputPhone from '@/components/Form/InputPhone';
|
|
import React, { useEffect } from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
import { Trash2, Plus, Users } from 'lucide-react';
|
|
import SectionHeader from '@/components/SectionHeader';
|
|
import { useEstablishment } from '@/context/EstablishmentContext';
|
|
import logger from '@/utils/logger';
|
|
|
|
export default function ResponsableInputFields({
|
|
guardians,
|
|
setGuardians,
|
|
profiles,
|
|
errors,
|
|
setIsPageValid,
|
|
enable = true,
|
|
}) {
|
|
const t = useTranslations('ResponsableInputFields');
|
|
const { selectedEstablishmentId } = useEstablishment();
|
|
const MAX_GUARDIANS = 2;
|
|
|
|
useEffect(() => {
|
|
const isValid =
|
|
guardians.length > 0 &&
|
|
guardians.every((guardian, index) => {
|
|
return !Object.keys(guardian).some(
|
|
(field) => getLocalError(index, field) !== ''
|
|
);
|
|
});
|
|
|
|
setIsPageValid(isValid);
|
|
}, [guardians, setIsPageValid]);
|
|
|
|
const getError = (index, field) => {
|
|
return errors[index]?.[field]?.[0];
|
|
};
|
|
|
|
const getLocalError = (index, field) => {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
|
|
if (
|
|
// Student Form
|
|
(field === 'last_name' &&
|
|
(!guardians[index].last_name ||
|
|
guardians[index].last_name.trim() === '')) ||
|
|
(field === 'first_name' &&
|
|
(!guardians[index].first_name ||
|
|
guardians[index].first_name.trim() === '')) ||
|
|
(field === 'associated_profile_email' &&
|
|
(!guardians[index].associated_profile_email ||
|
|
guardians[index].associated_profile_email.trim() === '' ||
|
|
!emailRegex.test(guardians[index].associated_profile_email))) ||
|
|
(field === 'birth_date' &&
|
|
(!guardians[index].birth_date ||
|
|
guardians[index].birth_date.trim() === '' ||
|
|
!dateRegex.test(guardians[index].birth_date))) ||
|
|
(field === 'profession' &&
|
|
(!guardians[index].profession ||
|
|
guardians[index].profession.trim() === '')) ||
|
|
(field === 'address' &&
|
|
(!guardians[index].address || guardians[index].address.trim() === ''))
|
|
) {
|
|
return 'Champs requis';
|
|
}
|
|
return '';
|
|
};
|
|
|
|
const onGuardiansChange = (id, field, value) => {
|
|
const updatedGuardians = guardians.map((guardian) => {
|
|
if (guardian.id === id) {
|
|
const updatedGuardian = { ...guardian, [field]: value };
|
|
|
|
// Synchroniser profile_data.email et profile_data.username avec associated_profile_email
|
|
if (field === 'associated_profile_email') {
|
|
const existingProfile = profiles?.find(
|
|
(profile) => profile.email === value
|
|
);
|
|
if (existingProfile) {
|
|
updatedGuardian.profile_role_data.profile = existingProfile.id;
|
|
delete updatedGuardian.profile_role_data.profile_data;
|
|
} else {
|
|
updatedGuardian.profile_role_data.profile_data.email = value;
|
|
updatedGuardian.profile_role_data.profile_data.username = value;
|
|
delete updatedGuardian.profile_role_data.profile;
|
|
}
|
|
}
|
|
|
|
return updatedGuardian;
|
|
}
|
|
return guardian;
|
|
});
|
|
|
|
setGuardians(updatedGuardians);
|
|
};
|
|
|
|
const addGuardian = () => {
|
|
setGuardians([
|
|
...guardians,
|
|
{
|
|
profile_role_data: {
|
|
establishment: selectedEstablishmentId,
|
|
role_type: 2,
|
|
is_active: true,
|
|
profile_data: {
|
|
email: '',
|
|
password: 'Provisoire01!',
|
|
username: '',
|
|
},
|
|
},
|
|
last_name: '',
|
|
first_name: '',
|
|
birth_date: '',
|
|
address: '',
|
|
phone: '',
|
|
profession: '',
|
|
},
|
|
]);
|
|
};
|
|
|
|
const deleteGuardian = (index) => {
|
|
const updatedGuardians = guardians.filter((_, i) => i !== index);
|
|
setGuardians(updatedGuardians);
|
|
};
|
|
|
|
return (
|
|
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
|
|
<SectionHeader
|
|
icon={Users}
|
|
title={'Responsables légaux'}
|
|
description={'Remplissez les champs requis'}
|
|
/>
|
|
{guardians.map((item, index) => (
|
|
<div className="p-6 " key={index}>
|
|
<div className="flex justify-between items-center mb-4">
|
|
<h3 className="text-xl font-bold">
|
|
{t('responsable')} {index + 1}
|
|
</h3>
|
|
{guardians.length > 1 && (
|
|
<Trash2
|
|
className="w-5 h-5 text-red-500 cursor-pointer hover:text-red-700 transition-colors"
|
|
onClick={() => deleteGuardian(index)}
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
<input type="hidden" name="idResponsable" value={item.id} />
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
<InputText
|
|
name="nomResponsable"
|
|
type="text"
|
|
label={t('lastname')}
|
|
value={item.last_name || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'last_name', event.target.value);
|
|
}}
|
|
errorMsg={getError('last_name')}
|
|
errorLocalMsg={getLocalError(index, 'last_name')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
<InputText
|
|
name="prenomResponsable"
|
|
type="text"
|
|
label={t('firstname')}
|
|
value={item.first_name || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'first_name', event.target.value);
|
|
}}
|
|
errorMsg={getError('first_name')}
|
|
errorLocalMsg={getLocalError(index, 'first_name')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
<InputText
|
|
name="mailResponsable"
|
|
type="email"
|
|
label={t('email')}
|
|
value={item.associated_profile_email || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(
|
|
item.id,
|
|
'associated_profile_email',
|
|
event.target.value
|
|
);
|
|
}}
|
|
errorMsg={getError('associated_profile_email')}
|
|
errorLocalMsg={getLocalError(index, 'associated_profile_email')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
<InputPhone
|
|
name="telephoneResponsable"
|
|
label="phone"
|
|
value={item.phone || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'phone', event.target.value);
|
|
}}
|
|
errorMsg={getError('phone')}
|
|
errorLocalMsg={getLocalError(index, 'phone')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
<InputText
|
|
name="dateNaissanceResponsable"
|
|
type="date"
|
|
label={t('birthdate')}
|
|
value={item.birth_date || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'birth_date', event.target.value);
|
|
}}
|
|
errorMsg={getError('birth_date')}
|
|
errorLocalMsg={getLocalError(index, 'birth_date')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
<InputText
|
|
name="professionResponsable"
|
|
type="text"
|
|
label={t('profession')}
|
|
value={item.profession || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'profession', event.target.value);
|
|
}}
|
|
errorMsg={getError('profession')}
|
|
errorLocalMsg={getLocalError(index, 'profession')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 gap-4">
|
|
<InputText
|
|
name="adresseResponsable"
|
|
type="text"
|
|
label={t('address')}
|
|
value={item.address || ''}
|
|
onChange={(event) => {
|
|
onGuardiansChange(item.id, 'address', event.target.value);
|
|
}}
|
|
errorMsg={getError('address')}
|
|
errorLocalMsg={getLocalError(index, 'address')}
|
|
required
|
|
enable={enable}
|
|
/>
|
|
</div>
|
|
</div>
|
|
))}
|
|
|
|
{enable && (
|
|
<div className="flex justify-center">
|
|
<Plus
|
|
className={`w-8 h-8 ${
|
|
guardians.length >= MAX_GUARDIANS
|
|
? 'text-gray-400 cursor-not-allowed'
|
|
: 'text-green-500 cursor-pointer hover:text-green-700'
|
|
} transition-colors border-2 ${
|
|
guardians.length >= MAX_GUARDIANS
|
|
? 'border-gray-400'
|
|
: 'border-green-500 hover:border-green-700'
|
|
} rounded-full p-1`}
|
|
onClick={(e) => {
|
|
if (guardians.length < MAX_GUARDIANS) {
|
|
addGuardian(e);
|
|
}
|
|
}}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|