Files
n3wt-school/Front-End/src/components/Inscription/ResponsableInputFields.js

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>
);
}