feat: Ajout de la possibilité de supprimer une association

guardian/student + ajout de la possibilité de créer un guardian pour un
student + tri chrologique
This commit is contained in:
N3WT DE COMPET
2025-03-22 12:28:12 +01:00
parent 43ed495a9a
commit c9350a796b
12 changed files with 326 additions and 93 deletions

View File

@ -10,6 +10,7 @@ import ProfileDirectory from '@/components/ProfileDirectory';
export default function Page() {
const [profileRoles, setProfileRoles] = useState([]);
const [reloadFetch, setReloadFetch] = useState(false);
const csrfToken = useCsrfToken();
const { selectedEstablishmentId } = useEstablishment();
@ -19,7 +20,7 @@ export default function Page() {
// Fetch data for profileRoles
handleProfiles();
}
}, [selectedEstablishmentId]);
}, [selectedEstablishmentId, reloadFetch]);
const handleProfiles = () => {
fetchProfileRoles(selectedEstablishmentId)
@ -27,6 +28,7 @@ export default function Page() {
setProfileRoles(data);
})
.catch(error => logger.error('Error fetching profileRoles:', error));
setReloadFetch(false);
};
const handleEdit = (profileRole) => {
@ -56,8 +58,37 @@ export default function Page() {
const handleDissociate = (studentId, guardianId) => {
return dissociateGuardian(studentId, guardianId)
.then(() => {
.then((response) => {
logger.debug("Guardian dissociated successfully:", guardianId);
// Vérifier si le Guardian a été supprimé
const isGuardianDeleted = response?.isGuardianDeleted;
// Mettre à jour le modèle profileRoles
setProfileRoles(prevState =>
prevState.map(profileRole => {
if (profileRole.associated_person?.id === guardianId) {
if (isGuardianDeleted) {
// Si le Guardian est supprimé, retirer le profileRole
return null;
} else {
// Si le Guardian n'est pas supprimé, mettre à jour les élèves associés
const updatedStudents = profileRole.associated_person.students.filter(
student => student.id !== studentId
);
return {
...profileRole,
associated_person: {
...profileRole.associated_person,
students: updatedStudents, // Mettre à jour les élèves associés
},
};
}
}
setReloadFetch(true);
return profileRole; // Conserver les autres profileRoles
}).filter(Boolean) // Supprimer les entrées nulles
);
})
.catch(error => {
logger.error('Error dissociating guardian:', error);

View File

@ -15,7 +15,6 @@ import { MoreVertical, Send, Edit, Trash2, FileText, CheckCircle, Plus } from '
import Modal from '@/components/Modal';
import InscriptionForm from '@/components/Inscription/InscriptionForm'
import AffectationClasseForm from '@/components/AffectationClasseForm'
import { getSession } from 'next-auth/react';
import { useEstablishment } from '@/context/EstablishmentContext';
import {
@ -87,6 +86,7 @@ export default function Page({ params: { locale } }) {
const [tuitionFees, setTuitionFees] = useState([]);
const [groups, setGroups] = useState([]);
const [profiles, setProfiles] = useState([]);
const [isOpenAddGuardian, setIsOpenAddGuardian] = useState(false);
const csrfToken = useCsrfToken();
const { selectedEstablishmentId } = useEstablishment();
@ -100,6 +100,15 @@ export default function Page({ params: { locale } }) {
}
const handleOpenAddGuardian = (eleveSelected) => {
setIsOpenAddGuardian(true);
setStudent(eleveSelected);
};
const handleCloseAddGuardian = () => {
setIsOpenAddGuardian(false);
};
const openModalAssociationEleve = (eleveSelected) => {
setIsOpenAffectationClasse(true);
setStudent(eleveSelected);
@ -480,10 +489,94 @@ useEffect(()=>{
});
}
const updateRF = (updatedData) => {
logger.debug('updateRF updatedData:', updatedData);
const data = {
student: {
guardians: updatedData.selectedGuardians.length !== 0
? updatedData.selectedGuardians.map(guardianId => ({ id: guardianId }))
: (() => {
if (updatedData.isExistingParentProfile) {
return [{
profile_role_data: {
establishment: selectedEstablishmentId,
role_type: 2,
is_active: false,
profile: updatedData.existingProfileId, // Associer au profil existant
},
last_name: updatedData.guardianLastName,
first_name: updatedData.guardianFirstName,
birth_date: updatedData.guardianBirthDate,
address: updatedData.guardianAddress,
phone: updatedData.guardianPhone,
profession: updatedData.guardianProfession
}];
}
// Si aucun profil existant n'est trouvé, créer un nouveau profil
return [{
profile_role_data: {
establishment: selectedEstablishmentId,
role_type: 2,
is_active: false,
profile_data: {
email: updatedData.guardianEmail,
password: 'Provisoire01!',
username: updatedData.guardianEmail,
}
},
last_name: updatedData.guardianLastName,
first_name: updatedData.guardianFirstName,
birth_date: updatedData.guardianBirthDate,
address: updatedData.guardianAddress,
phone: updatedData.guardianPhone,
profession: updatedData.guardianProfession
}];
})(),
},
establishment: selectedEstablishmentId
};
editRegisterForm(student.id, data, csrfToken)
.then(data => {
// Mise à jour immédiate des données
setRegistrationFormsDataPending(prevState => [...(prevState || []), data]);
setTotalPending(prev => prev + 1);
if (updatedData.autoMail) {
sendConfirmRegisterForm(data.student.id, updatedData.studentLastName, updatedData.studentFirstName);
}
handleCloseAddGuardian();
// Forcer le rechargement complet des données
setReloadFetch(true);
})
.catch(error => {
logger.error('Error during updating registration form:', error);
});
}
const columns = [
{ name: t('studentName'), transform: (row) => row.student.last_name },
{ name: t('studentFistName'), transform: (row) => row.student.first_name },
{ name: t('mainContactMail'), transform: (row) => (row.student.guardians && row.student.guardians.length > 0) ? row.student.guardians[0].associated_profile_email : '' },
{
name: t('mainContactMail'),
transform: (row) => (
row.student.guardians && row.student.guardians.length > 0
? row.student.guardians[0].associated_profile_email
: (
<div className="flex justify-center h-full">
<button
className="flex items-center gap-2 text-blue-600 font-semibold hover:text-blue-800 transition duration-200 underline decoration-blue-600 hover:decoration-blue-800"
onClick={() => handleOpenAddGuardian(row.student)}
>
<span className="px-3 py-1 bg-blue-100 rounded-full hover:bg-blue-200 transition duration-200">
Ajouter un responsable
</span>
</button>
</div>
)
)
},
{ name: t('phone'), transform: (row) => formatPhoneNumber(row.student.guardians[0]?.phone) },
{ name: t('lastUpdateDate'), transform: (row) => row.formatted_last_update},
{ name: t('registrationFileStatus'), transform: (row) => (
@ -742,13 +835,29 @@ const columnsSubscribed = [
title="Affectation à une classe"
ContentComponent={() => (
<AffectationClasseForm
student={student}
students={students}
onSubmit={affectationClassFormSubmitHandler}
classes={classes}
/>
)}
/>
)}
{isOpenAddGuardian && (
<Modal
isOpen={isOpenAddGuardian}
setIsOpen={setIsOpenAddGuardian}
title="Ajouter un responsable"
ContentComponent={() => (
<InscriptionForm
students={students}
profiles={profiles}
onSubmit={updateRF}
currentStep={2}
showOnlyStep2={true}
/>
)}
/>
)}
</div>
);
}