refactor: Partie FRONT / School

This commit is contained in:
N3WT DE COMPET
2025-01-12 16:45:41 +01:00
parent 41aa9d55d3
commit 24352efad3
25 changed files with 217 additions and 186 deletions

View File

@ -13,7 +13,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
const { formData, setFormData } = useClasseForm();
const { getNiveauNameById, schoolYears, getNiveauxLabels, getNiveauxTabs, generateAgeToNiveaux, niveauxPremierCycle, niveauxSecondCycle, niveauxTroisiemeCycle, typeEmploiDuTemps, updatePlannings } = useClasses();
const [selectedTeachers, setSelectedTeachers] = useState(formData.enseignants_ids);
const [selectedTeachers, setSelectedTeachers] = useState(formData.teachers);
const handleTeacherSelection = (teacher) => {
setSelectedTeachers(prevState =>
@ -23,21 +23,21 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
);
setFormData(prevState => ({
...prevState,
enseignants_ids: prevState.enseignants_ids.includes(teacher.id)
? prevState.enseignants_ids.filter(id => id !== teacher.id)
: [...prevState.enseignants_ids, teacher.id]
teachers: prevState.teachers.includes(teacher.id)
? prevState.teachers.filter(id => id !== teacher.id)
: [...prevState.teachers, teacher.id]
}));
};
const handleTimeChange = (e, index) => {
const { value } = e.target;
setFormData(prevState => {
const updatedTimes = [...prevState.plage_horaire];
const updatedTimes = [...prevState.time_range];
updatedTimes[index] = value;
const updatedFormData = {
...prevState,
plage_horaire: updatedTimes,
time_range: updatedTimes,
};
const existingPlannings = prevState.plannings || [];
@ -53,12 +53,12 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
setFormData((prevState) => {
const updatedJoursOuverture = checked
? [...prevState.jours_ouverture, dayId]
: prevState.jours_ouverture.filter((id) => id !== dayId);
? [...prevState.opening_days, dayId]
: prevState.opening_days.filter((id) => id !== dayId);
const updatedFormData = {
...prevState,
jours_ouverture: updatedJoursOuverture,
opening_days: updatedJoursOuverture,
};
const existingPlannings = prevState.plannings || [];
@ -82,7 +82,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
? [...(prevState[name] || []), parseInt(value)]
: (prevState[name] || []).filter(v => v !== parseInt(value));
newState[name] = newValues;
} else if (name === 'tranche_age') {
} else if (name === 'age_range') {
const [minAgeStr, maxAgeStr] = value.split('-');
const minAge = minAgeStr ? parseInt(minAgeStr) : null;
const maxAge = minAgeStr ? parseInt(maxAgeStr) : null;
@ -92,7 +92,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
newState = {
...prevState,
[name]: value,
niveaux: selectedNiveaux.length > 0 ? selectedNiveaux : [],
levels: selectedNiveaux.length > 0 ? selectedNiveaux : [],
};
} else if (type === 'radio') {
newState[name] = parseInt(value, 10);
@ -111,7 +111,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
onSubmit(formData);
};
const [minAge, maxAge] = formData.tranche_age.length === 2 ? formData.tranche_age : [null, null];
const [minAge, maxAge] = formData.age_range.length === 2 ? formData.age_range : [null, null];
const selectedAgeGroup = generateAgeToNiveaux(minAge, maxAge);
return (
@ -136,11 +136,11 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
</div>
<div>
<InputTextIcon
name="tranche_age"
name="age_range"
type="text"
IconItem={Maximize2}
placeholder="Tranche d'âge (ex: 3-6)"
value={formData.tranche_age}
value={formData.age_range}
onChange={handleChange}
className="w-full"
/>
@ -156,7 +156,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
items={niveauxPremierCycle}
formData={formData}
handleChange={handleChange}
fieldName="niveaux"
fieldName="levels"
labelAttenuated={(item) => !selectedAgeGroup.includes(parseInt(item.id))}
className="w-full"
/>
@ -164,7 +164,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
items={niveauxSecondCycle}
formData={formData}
handleChange={handleChange}
fieldName="niveaux"
fieldName="levels"
labelAttenuated={(item) => !selectedAgeGroup.includes(parseInt(item.id))}
className="w-full"
/>
@ -172,7 +172,7 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
items={niveauxTroisiemeCycle}
formData={formData}
handleChange={handleChange}
fieldName="niveaux"
fieldName="levels"
labelAttenuated={(item) => !selectedAgeGroup.includes(parseInt(item.id))}
className="w-full"
/>
@ -186,11 +186,11 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
<label className="block text-lg font-medium text-gray-700">Capacité</label>
<div className="space-y-4">
<InputTextIcon
name="nombre_eleves"
name="number_of_students"
type="number"
IconItem={UserPlus}
placeholder="Capacité max"
value={formData.nombre_eleves}
value={formData.number_of_students}
onChange={handleChange}
className="w-full"
/>
@ -202,9 +202,9 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
<label className="block text-lg font-medium text-gray-700">Année scolaire</label>
<div className="space-y-4">
<SelectChoice
name="annee_scolaire"
name="school_year"
placeholder="Sélectionner l'année scolaire"
selected={formData.annee_scolaire}
selected={formData.school_year}
callback={handleChange}
choices={schoolYears}
IconItem={Calendar}
@ -235,12 +235,12 @@ const ClassForm = ({ onSubmit, isNew, teachers }) => {
text={`${isNew ? "Créer" : "Modifier"}`}
onClick={handleSubmit}
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
(formData.niveaux.length === 0 || !formData.annee_scolaire || !formData.nombre_eleves || formData.enseignants_ids.length === 0)
(formData.levels.length === 0 || !formData.school_year || !formData.number_of_students || formData.teachers.length === 0)
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
}`}
primary
disabled={(formData.niveaux.length === 0 || !formData.annee_scolaire || !formData.nombre_eleves || formData.enseignants_ids.length === 0)}
disabled={(formData.levels.length === 0 || !formData.school_year || !formData.number_of_students || formData.teachers.length === 0)}
type="submit"
name="Create"
/>

View File

@ -11,7 +11,7 @@ import { ClasseFormProvider } from '@/context/ClasseFormContext';
import { useClasses } from '@/context/ClassesContext';
const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleEdit, handleDelete }) => {
const ClassesSection = ({ classes, teachers, handleCreate, handleEdit, handleDelete }) => {
const { getNiveauxLabels } = useClasses();
const [isOpen, setIsOpen] = useState(false);
@ -67,8 +67,8 @@ const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleE
{
name: 'AMBIANCE',
transform: (row) => {
const ambiance = row.nom_ambiance ? row.nom_ambiance : '';
const trancheAge = row.tranche_age ? `${row.tranche_age} ans` : '';
const ambiance = row.atmosphere_name ? row.atmosphere_name : '';
const trancheAge = row.age_range ? `${row.age_range} ans` : '';
if (ambiance && trancheAge) {
return `${ambiance} (${trancheAge})`;
@ -84,11 +84,11 @@ const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleE
{
name: 'NIVEAUX',
transform: (row) => {
const niveauxLabels = Array.isArray(row.niveaux) ? getNiveauxLabels(row.niveaux) : [];
const levelLabels = Array.isArray(row.levels) ? getNiveauxLabels(row.levels) : [];
return (
<div className="flex flex-wrap justify-center items-center space-x-2">
{niveauxLabels.length > 0
? niveauxLabels.map((label, index) => (
{levelLabels.length > 0
? levelLabels.map((label, index) => (
<LevelLabel key={index} label={label} index={index} />
))
: 'Aucun niveau'}
@ -96,19 +96,19 @@ const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleE
);
}
},
{ name: 'CAPACITÉ MAX', transform: (row) => row.nombre_eleves },
{ name: 'ANNÉE SCOLAIRE', transform: (row) => row.annee_scolaire },
{ name: 'CAPACITÉ MAX', transform: (row) => row.number_of_students },
{ name: 'ANNÉE SCOLAIRE', transform: (row) => row.school_year },
{
name: 'ENSEIGNANTS',
transform: (row) => (
<div key={row.id} className="flex flex-wrap justify-center items-center space-x-2">
{row.enseignants.map((teacher, index) => (
<TeacherLabel key={teacher.id} nom={teacher.nom} prenom={teacher.prenom} index={index} />
{row.teachers_details.map((teacher, index) => (
<TeacherLabel key={teacher.id} nom={teacher.last_name} prenom={teacher.first_name} index={index} />
))}
</div>
)
},
{ name: 'DATE DE CREATION', transform: (row) => row.dateCreation_formattee },
{ name: 'DATE DE CREATION', transform: (row) => row.updated_date_formatted },
{
name: 'ACTIONS', transform: (row) => (
<DropdownMenu
@ -151,7 +151,7 @@ const ClassesSection = ({ classes, specialities, teachers, handleCreate, handleE
<Users className="w-8 h-8 mr-2" />
{editingClass ? (
<>
{editingClass.nom_ambiance} - {editingClass.tranche_age[0]} à {editingClass.tranche_age[1]} ans
{editingClass.nom_ambiance} - {editingClass.age_range[0]} à {editingClass.age_range[1]} ans
</>
) : ''}
</div>

View File

@ -15,7 +15,7 @@ const PlanningConfiguration = ({ formData, handleChange, handleTimeChange, handl
];
const isLabelAttenuated = (item) => {
return !formData.jours_ouverture.includes(parseInt(item.id));
return !formData.opening_days.includes(parseInt(item.id));
};
return (
@ -36,8 +36,8 @@ const PlanningConfiguration = ({ formData, handleChange, handleTimeChange, handl
{/* Plage horaire */}
<div className="w-1/2">
<TimeRange
startTime={formData.plage_horaire[0]}
endTime={formData.plage_horaire[1]}
startTime={formData.time_range[0]}
endTime={formData.time_range[1]}
onStartChange={(e) => handleTimeChange(e, 0)}
onEndChange={(e) => handleTimeChange(e, 1)}
/>
@ -47,7 +47,7 @@ const PlanningConfiguration = ({ formData, handleChange, handleTimeChange, handl
items={daysOfWeek}
formData={formData}
handleChange={handleJoursChange}
fieldName="jours_ouverture"
fieldName="opening_days"
horizontal={true}
labelAttenuated={isLabelAttenuated}
/>

View File

@ -52,14 +52,14 @@ const SpecialitiesSection = ({ specialities, handleCreate, handleEdit, handleDel
transform: (row) => (
<div
className="inline-block px-3 py-1 rounded-full font-bold text-white"
style={{ backgroundColor: row.codeCouleur }}
title={row.codeCouleur}
style={{ backgroundColor: row. color_code }}
title={row. color_code}
>
<span className="font-bold text-white">{row.nom.toUpperCase()}</span>
<span className="font-bold text-white">{row.name.toUpperCase()}</span>
</div>
)
},
{ name: 'DATE DE CREATION', transform: (row) => row.dateCreation_formattee },
{ name: 'DATE DE CREATION', transform: (row) => row.updated_date_formatted },
{ name: 'ACTIONS', transform: (row) => (
<DropdownMenu
buttonContent={<MoreVertical size={20} className="text-gray-400 hover:text-gray-600" />}

View File

@ -27,10 +27,10 @@ const SpecialityForm = ({ onSubmit, isNew }) => {
<div>
<InputTextIcon
type="text"
name="nom"
name="name"
IconItem={BookOpen}
placeholder="Nom de la spécialité"
value={formData.nom}
value={formData.name}
onChange={handleChange}
className="w-full mt-4"
/>
@ -38,10 +38,10 @@ const SpecialityForm = ({ onSubmit, isNew }) => {
<div className="mt-4">
<InputColorIcon
type="color"
name="codeCouleur"
name="color_code"
IconItem={Palette}
placeholder="Nom de la spécialité"
value={formData.codeCouleur}
value={formData.color_code}
onChange={handleChange}
className="w-full mt-4"
/>
@ -50,12 +50,12 @@ const SpecialityForm = ({ onSubmit, isNew }) => {
<Button text={`${isNew ? "Créer" : "Modifier"}`}
onClick={handleSubmit}
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
!formData.nom
!formData.name
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
}`}
primary
disabled={!formData.nom}
disabled={!formData.name}
type="submit"
name="Create" />
</div>

View File

@ -30,7 +30,6 @@ const StructureManagement = ({ specialities, setSpecialities, teachers, setTeach
<ClassesSection
classes={classes}
specialities={specialities}
teachers={teachers}
handleCreate={(newData) => handleCreate(`${BE_SCHOOL_SCHOOLCLASS_URL}`, newData, setClasses)}
handleEdit={(id, updatedData) => handleEdit(`${BE_SCHOOL_SCHOOLCLASS_URL}`, id, updatedData, setClasses)}

View File

@ -10,7 +10,7 @@ const TeacherForm = ({ onSubmit, isNew, specialities }) => {
const { formData, setFormData } = useTeacherForm();
const handleToggleChange = () => {
setFormData({ ...formData, droit: 1-formData.droit });
setFormData({ ...formData, droit: 1-formData.droit.id });
};
const handleChange = (e) => {
@ -39,45 +39,45 @@ const TeacherForm = ({ onSubmit, isNew, specialities }) => {
onSubmit(formData, isNew);
};
const getSpecialityLabel = (speciality) => {
return `${speciality.nom}`;
const getSpecialityLabel = (speciality) => {
return `${speciality.name}`;
};
const isLabelAttenuated = (item) => {
return !formData.specialites_ids.includes(parseInt(item.id));
return !formData.specialities.includes(parseInt(item.id));
};
return (
<form onSubmit={handleSubmit} className="space-y-4 mt-8">
<div>
<InputTextIcon
name="nom"
name="last_name"
type="text"
IconItem={GraduationCap}
placeholder="Nom de l'enseignant"
value={formData.nom}
value={formData.last_name}
onChange={handleChange}
className="w-full"
/>
</div>
<div>
<InputTextIcon
name="prenom"
name="first_name"
type="text"
IconItem={GraduationCap}
placeholder="Prénom de l'enseignant"
value={formData.prenom}
value={formData.first_name}
onChange={handleChange}
className="w-full"
/>
</div>
<div>
<InputTextIcon
name="mail"
name="email"
type="email"
IconItem={Mail}
placeholder="Email de l'enseignant"
value={formData.mail}
value={formData.email}
onChange={handleChange}
className="w-full mt-4"
/>
@ -87,7 +87,7 @@ const TeacherForm = ({ onSubmit, isNew, specialities }) => {
items={specialities}
formData={formData}
handleChange={handleChange}
fieldName="specialites_ids"
fieldName="specialities"
label="Spécialités"
icon={BookOpen}
className="w-full mt-4"
@ -98,7 +98,7 @@ const TeacherForm = ({ onSubmit, isNew, specialities }) => {
<div className='mt-4'>
<ToggleSwitch
label="Administrateur"
checked={formData.droit}
checked={formData.droit.id}
onChange={handleToggleChange}
/>
</div>
@ -106,12 +106,12 @@ const TeacherForm = ({ onSubmit, isNew, specialities }) => {
<Button text={`${isNew ? "Créer" : "Modifier"}`}
onClick={handleSubmit}
className={`px-4 py-2 rounded-md shadow-sm focus:outline-none ${
(!formData.nom || !formData.prenom || !formData.mail || formData.specialites_ids.length === 0)
(!formData.last_name || !formData.first_name || !formData.email || formData.specialities.length === 0)
? "bg-gray-300 text-gray-700 cursor-not-allowed"
: "bg-emerald-500 text-white hover:bg-emerald-600"
}`}
primary
disabled={(!formData.nom || !formData.prenom || !formData.mail || formData.specialites_ids.length === 0)}
disabled={(!formData.last_name || !formData.first_name || !formData.email || formData.specialities.length === 0)}
type="submit"
name="Create" />
</div>

View File

@ -4,12 +4,11 @@ import Table from '@/components/Table';
import DropdownMenu from '@/components/DropdownMenu';
import Modal from '@/components/Modal';
import TeacherForm from '@/components/Structure/Configuration/TeacherForm';
import useCsrfToken from '@/hooks/useCsrfToken';
import { TeacherFormProvider } from '@/context/TeacherFormContext';
import { createProfile, updateProfile } from '@/app/lib/authAction';
const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, specialities }) => {
const TeachersSection = ({ teachers, specialities , handleCreate, handleEdit, handleDelete}) => {
const [isOpen, setIsOpen] = useState(false);
const [editingTeacher, setEditingTeacher] = useState(null);
@ -30,12 +29,12 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
if (editingTeacher) {
// Modification du profil
const data = {
email: updatedData.mail,
username: updatedData.mail,
email: updatedData.email,
username: updatedData.email,
droit:updatedData.droit
}
updateProfile(updatedData.profilAssocie_id,data,csrfToken)
updateProfile(updatedData.associated_profile,data,csrfToken)
.then(response => {
console.log('Success:', response);
console.log('UpdateData:', updatedData);
@ -50,9 +49,9 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
// Création d'un profil associé à l'adresse mail du responsable saisie
// Le profil est inactif
const data = {
email: updatedData.mail,
email: updatedData.email,
password: 'Provisoire01!',
username: updatedData.mail,
username: updatedData.email,
is_active: 1, // On rend le profil actif : on considère qu'au moment de la configuration de l'école un abonnement a été souscrit
droit:updatedData.droit
}
@ -62,7 +61,7 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
console.log('UpdateData:', updatedData);
if (response.id) {
let idProfil = response.id;
updatedData.profilAssocie_id = idProfil;
updatedData.associated_profile = idProfil;
handleCreate(updatedData);
}
})
@ -92,21 +91,21 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
<div className="bg-white rounded-lg border border-gray-200 max-w-8xl ml-0">
<Table
columns={[
{ name: 'NOM', transform: (row) => row.nom },
{ name: 'PRENOM', transform: (row) => row.prenom },
{ name: 'MAIL', transform: (row) => row.mail },
{ name: 'NOM', transform: (row) => row.last_name },
{ name: 'PRENOM', transform: (row) => row.first_name },
{ name: 'MAIL', transform: (row) => row.email },
{
name: 'SPÉCIALITÉS',
transform: (row) => (
<div key={row.id} className="flex flex-wrap justify-center items-center space-x-2">
{row.specialites.map(specialite => (
{row.specialities_details.map((speciality,index) => (
<span
key={specialite.id}
key={`${speciality.id}-${index}`}
className="px-3 py-1 rounded-full font-bold text-white"
style={{ backgroundColor: specialite.codeCouleur }}
title={specialite.nom}
style={{ backgroundColor: speciality.color_code }}
title={speciality.name}
>
{specialite.nom}
{speciality.name}
</span>
))}
</div>
@ -115,12 +114,12 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
{
name: 'TYPE PROFIL',
transform: (row) => {
if (row.profilAssocie) {
const badgeClass = row.DroitLabel === 'ECOLE' ? 'bg-blue-100 text-blue-600' : 'bg-red-100 text-red-600';
if (row.associated_profile) {
const badgeClass = row.droit.label === 'ECOLE' ? 'bg-blue-100 text-blue-600' : 'bg-red-100 text-red-600';
return (
<div key={row.id} className="flex justify-center items-center space-x-2">
<span className={`px-3 py-1 rounded-full font-bold ${badgeClass}`}>
{row.DroitLabel}
{row.droit.label}
</span>
</div>
);
@ -129,7 +128,7 @@ const TeachersSection = ({ teachers, handleCreate, handleEdit, handleDelete, spe
}
}
},
{ name: 'DATE DE CREATION', transform: (row) => row.dateCreation_formattee },
{ name: 'DATE DE CREATION', transform: (row) => row.updated_date_formatted },
{ name: 'ACTIONS', transform: (row) => (
<DropdownMenu
buttonContent={<MoreVertical size={20} className="text-gray-400 hover:text-gray-600" />}

View File

@ -5,34 +5,34 @@ const TeachersSelectionConfiguration = ({ formData, teachers, handleTeacherSelec
return (
<div className="mt-4" style={{ maxHeight: '300px', overflowY: 'auto' }}>
<label className="mt-6 block text-2xl font-medium text-gray-700 mb-2">Enseignants</label>
<label className={`block text-sm font-medium mb-4`}>Sélection : <span className={`${formData.enseignants_ids.length !== 0 ? 'text-emerald-400' : 'text-red-300'}`}>{formData.enseignants_ids.length}</span></label>
<label className={`block text-sm font-medium mb-4`}>Sélection : <span className={`${formData.teachers.length !== 0 ? 'text-emerald-400' : 'text-red-300'}`}>{formData.teachers.length}</span></label>
<Table
columns={[
{
name: 'Nom',
transform: (row) => row.nom,
transform: (row) => row.last_name,
},
{
name: 'Prénom',
transform: (row) => row.prenom,
},
{
name: 'Spécialités',
transform: (row) => (
<div className="flex flex-wrap items-center">
{row.specialites.map(specialite => (
<span key={specialite.id} className="flex items-center mr-2 mb-1">
<div
className="w-4 h-4 rounded-full mr-2"
style={{ backgroundColor: specialite.codeCouleur }}
title={specialite.nom}
></div>
<span>{specialite.nom}</span>
</span>
))}
</div>
),
transform: (row) => row.first_name,
},
// {
// name: 'Spécialités',
// transform: (row) => (
// <div className="flex flex-wrap items-center">
// {row.specialites.map(specialite => (
// <span key={specialite.id} className="flex items-center mr-2 mb-1">
// <div
// className="w-4 h-4 rounded-full mr-2"
// style={{ backgroundColor: specialite.codeCouleur }}
// title={specialite.nom}
// ></div>
// <span>{specialite.nom}</span>
// </span>
// ))}
// </div>
// ),
// },
]}
data={teachers}
onRowClick={handleTeacherSelection}