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

@ -31,8 +31,10 @@ class TeacherDetailSerializer(serializers.ModelSerializer):
class TeacherSerializer(serializers.ModelSerializer): class TeacherSerializer(serializers.ModelSerializer):
specialities = serializers.PrimaryKeyRelatedField(queryset=Speciality.objects.all(), many=True, required=False) specialities = serializers.PrimaryKeyRelatedField(queryset=Speciality.objects.all(), many=True, required=False)
specialities_details = serializers.SerializerMethodField()
associated_profile = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all(), required=True) associated_profile = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all(), required=True)
updated_date_formatted = serializers.SerializerMethodField() updated_date_formatted = serializers.SerializerMethodField()
droit = serializers.SerializerMethodField()
class Meta: class Meta:
model = Teacher model = Teacher
@ -67,6 +69,18 @@ class TeacherSerializer(serializers.ModelSerializer):
return local_time.strftime("%d-%m-%Y %H:%M") return local_time.strftime("%d-%m-%Y %H:%M")
def get_droit(self, obj):
if obj.associated_profile:
droit_id = obj.associated_profile.droit
return {
"label": obj.associated_profile.get_droit_display(),
"id": droit_id
}
return None
def get_specialities_details(self, obj):
return [{'name': speciality.name, 'color_code': speciality.color_code} for speciality in obj.specialities.all()]
class PlanningSerializer(serializers.ModelSerializer): class PlanningSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Planning model = Planning
@ -80,6 +94,7 @@ class PlanningSerializer(serializers.ModelSerializer):
class SchoolClassSerializer(serializers.ModelSerializer): class SchoolClassSerializer(serializers.ModelSerializer):
updated_date_formatted = serializers.SerializerMethodField() updated_date_formatted = serializers.SerializerMethodField()
teachers = serializers.PrimaryKeyRelatedField(queryset=Teacher.objects.all(), many=True, required=False) teachers = serializers.PrimaryKeyRelatedField(queryset=Teacher.objects.all(), many=True, required=False)
teachers_details = serializers.SerializerMethodField()
class Meta: class Meta:
model = SchoolClass model = SchoolClass
@ -150,6 +165,9 @@ class SchoolClassSerializer(serializers.ModelSerializer):
return instance return instance
def get_teachers_details(self, obj):
return [{'last_name': teacher.last_name, 'first_name': teacher.first_name} for teacher in obj.teachers.all()]
def get_updated_date_formatted(self, obj): def get_updated_date_formatted(self, obj):
utc_time = timezone.localtime(obj.updated_date) utc_time = timezone.localtime(obj.updated_date)
local_tz = pytz.timezone(settings.TZ_APPLI) local_tz = pytz.timezone(settings.TZ_APPLI)

View File

@ -11,6 +11,7 @@ import { BE_SCHOOL_SPECIALITIES_URL,
import DjangoCSRFToken from '@/components/DjangoCSRFToken' import DjangoCSRFToken from '@/components/DjangoCSRFToken'
import useCsrfToken from '@/hooks/useCsrfToken'; import useCsrfToken from '@/hooks/useCsrfToken';
import { ClassesProvider } from '@/context/ClassesContext'; import { ClassesProvider } from '@/context/ClassesContext';
import { fetchSpecialities, fetchTeachers, fetchClasses, fetchSchedules } from '@/app/lib/schoolAction';
export default function Page() { export default function Page() {
const [specialities, setSpecialities] = useState([]); const [specialities, setSpecialities] = useState([]);
@ -27,21 +28,20 @@ export default function Page() {
useEffect(() => { useEffect(() => {
// Fetch data for specialities // Fetch data for specialities
fetchSpecialities(); handleSpecialities();
// Fetch data for teachers // Fetch data for teachers
fetchTeachers(); handleTeachers();
// Fetch data for classes // Fetch data for classes
fetchClasses(); handleClasses();
// Fetch data for schedules // Fetch data for schedules
fetchSchedules(); handleSchedules();
}, []); }, []);
const fetchSpecialities = () => { const handleSpecialities = () => {
fetch(`${BE_SCHOOL_SPECIALITIES_URL}`) fetchSpecialities()
.then(response => response.json())
.then(data => { .then(data => {
setSpecialities(data); setSpecialities(data);
}) })
@ -50,9 +50,8 @@ export default function Page() {
}); });
}; };
const fetchTeachers = () => { const handleTeachers = () => {
fetch(`${BE_SCHOOL_TEACHERS_URL}`) fetchTeachers()
.then(response => response.json())
.then(data => { .then(data => {
setTeachers(data); setTeachers(data);
}) })
@ -61,9 +60,8 @@ export default function Page() {
}); });
}; };
const fetchClasses = () => { const handleClasses = () => {
fetch(`${BE_SCHOOL_SCHOOLCLASSES_URL}`) fetchClasses()
.then(response => response.json())
.then(data => { .then(data => {
setClasses(data); setClasses(data);
}) })
@ -72,9 +70,8 @@ export default function Page() {
}); });
}; };
const fetchSchedules = () => { const handleSchedules = () => {
fetch(`${BE_SCHOOL_PLANNINGS_URL}`) fetchSchedules()
.then(response => response.json())
.then(data => { .then(data => {
setSchedules(data); setSchedules(data);
}) })
@ -142,7 +139,6 @@ export default function Page() {
}); });
}; };
const handleDelete = (url, id, setDatas) => { const handleDelete = (url, id, setDatas) => {
fetch(`${url}/${id}`, { fetch(`${url}/${id}`, {
method:'DELETE', method:'DELETE',

View File

@ -1,9 +1,26 @@
import { import {
BE_SCHOOL_SCHOOLCLASSES_URL BE_SCHOOL_SPECIALITIES_URL,
BE_SCHOOL_TEACHERS_URL,
BE_SCHOOL_SCHOOLCLASSES_URL,
BE_SCHOOL_PLANNINGS_URL
} from '@/utils/Url'; } from '@/utils/Url';
export const fetchClasses = () => { export const fetchSpecialities = () => {
return fetch(`${BE_SCHOOL_SCHOOLCLASSES_URL}`) return fetch(`${BE_SCHOOL_SPECIALITIES_URL}`)
.then(response => response.json()) .then(response => response.json())
};
}; export const fetchTeachers = () => {
return fetch(`${BE_SCHOOL_TEACHERS_URL}`)
.then(response => response.json())
};
export const fetchClasses = () => {
return fetch(`${BE_SCHOOL_SCHOOLCLASSES_URL}`)
.then(response => response.json())
};
export const fetchSchedules = () => {
return fetch(`${BE_SCHOOL_PLANNINGS_URL}`)
.then(response => response.json())
};

View File

@ -6,7 +6,7 @@ const ClasseDetails = ({ classe }) => {
if (!classe) return null; if (!classe) return null;
const nombreElevesInscrits = classe.eleves.length; const nombreElevesInscrits = classe.eleves.length;
const capaciteTotale = classe.nombre_eleves; const capaciteTotale = classe.number_of_students;
const pourcentage = Math.round((nombreElevesInscrits / capaciteTotale) * 100); const pourcentage = Math.round((nombreElevesInscrits / capaciteTotale) * 100);
const getColor = (pourcentage) => { const getColor = (pourcentage) => {

View File

@ -8,7 +8,7 @@ import DjangoCSRFToken from '@/components/DjangoCSRFToken';
import FileUpload from '@/app/[locale]/admin/subscriptions/components/FileUpload'; import FileUpload from '@/app/[locale]/admin/subscriptions/components/FileUpload';
import Table from '@/components/Table'; import Table from '@/components/Table';
const niveaux = [ const levels = [
{ value:'1', label: 'TPS - Très Petite Section'}, { value:'1', label: 'TPS - Très Petite Section'},
{ value:'2', label: 'PS - Petite Section'}, { value:'2', label: 'PS - Petite Section'},
{ value:'3', label: 'MS - Moyenne Section'}, { value:'3', label: 'MS - Moyenne Section'},
@ -158,7 +158,7 @@ export default function InscriptionFormShared({
label="Niveau" label="Niveau"
selected={formData.level} selected={formData.level}
callback={(e) => updateFormField('level', e.target.value)} callback={(e) => updateFormField('level', e.target.value)}
choices={niveaux} choices={levels}
required required
/> />
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,34 +5,34 @@ const TeachersSelectionConfiguration = ({ formData, teachers, handleTeacherSelec
return ( return (
<div className="mt-4" style={{ maxHeight: '300px', overflowY: 'auto' }}> <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="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 <Table
columns={[ columns={[
{ {
name: 'Nom', name: 'Nom',
transform: (row) => row.nom, transform: (row) => row.last_name,
}, },
{ {
name: 'Prénom', name: 'Prénom',
transform: (row) => row.prenom, 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>
),
}, },
// {
// 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} data={teachers}
onRowClick={handleTeacherSelection} onRowClick={handleTeacherSelection}

View File

@ -9,11 +9,11 @@ const ClassesInformation = ({ selectedClass, isPastYear }) => {
return ( return (
<div className={`w-full p-6 shadow-lg rounded-full border relative ${isPastYear ? 'bg-gray-200 border-gray-600' : 'bg-emerald-200 border-emerald-500'}`}> <div className={`w-full p-6 shadow-lg rounded-full border relative ${isPastYear ? 'bg-gray-200 border-gray-600' : 'bg-emerald-200 border-emerald-500'}`}>
<div className={`border-b pb-4 ${isPastYear ? 'border-gray-600' : 'border-emerald-500'}`}> <div className={`border-b pb-4 ${isPastYear ? 'border-gray-600' : 'border-emerald-500'}`}>
<p className="text-gray-700 text-center"><strong>{selectedClass.tranche_age} ans</strong></p> <p className="text-gray-700 text-center"><strong>{selectedClass.age_range} ans</strong></p>
</div> </div>
<div className={`border-b pb-4 ${isPastYear ? 'border-gray-600' : 'border-emerald-500'}`}> <div className={`border-b pb-4 ${isPastYear ? 'border-gray-600' : 'border-emerald-500'}`}>
<div className="flex flex-wrap justify-center space-x-4"> <div className="flex flex-wrap justify-center space-x-4">
{selectedClass.enseignants.map((teacher) => ( {selectedClass.teachers.map((teacher) => (
<div key={teacher.id} className="relative group mt-4"> <div key={teacher.id} className="relative group mt-4">
<TeacherLabel nom={teacher.nom} prenom={teacher.prenom} /> <TeacherLabel nom={teacher.nom} prenom={teacher.prenom} />
<div className="absolute left-1/2 transform -translate-x-1/2 bottom-full mb-2 w-max px-4 py-2 text-white bg-gray-800 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300"> <div className="absolute left-1/2 transform -translate-x-1/2 bottom-full mb-2 w-max px-4 py-2 text-white bg-gray-800 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300">

View File

@ -7,13 +7,13 @@ const ClassesList = ({ classes, onClassSelect, selectedClassId }) => {
const currentSchoolYearStart = currentMonth >= 8 ? currentYear : currentYear - 1; const currentSchoolYearStart = currentMonth >= 8 ? currentYear : currentYear - 1;
const handleClassClick = (classe) => { const handleClassClick = (classe) => {
console.log(`Classe sélectionnée: ${classe.nom_ambiance}, Année scolaire: ${classe.annee_scolaire}`); console.log(`Classe sélectionnée: ${classe.nom_ambiance}, Année scolaire: ${classe.school_year}`);
onClassSelect(classe); onClassSelect(classe);
}; };
const categorizedClasses = classes.reduce((acc, classe) => { const categorizedClasses = classes.reduce((acc, classe) => {
const { annee_scolaire } = classe; const { school_year } = classe;
const [startYear] = annee_scolaire.split('-').map(Number); const [startYear] = school_year.split('-').map(Number);
const category = startYear >= currentSchoolYearStart ? 'Actives' : 'Anciennes'; const category = startYear >= currentSchoolYearStart ? 'Actives' : 'Anciennes';
if (!acc[category]) { if (!acc[category]) {
@ -45,7 +45,7 @@ const ClassesList = ({ classes, onClassSelect, selectedClassId }) => {
style={{ maxWidth: '400px' }} style={{ maxWidth: '400px' }}
> >
<div className="flex-1 text-sm font-medium">{classe.nom_ambiance}</div> <div className="flex-1 text-sm font-medium">{classe.nom_ambiance}</div>
<div className="flex-1 text-sm font-medium">{classe.annee_scolaire}</div> <div className="flex-1 text-sm font-medium">{classe.school_year}</div>
</div> </div>
))} ))}
</div> </div>
@ -63,7 +63,7 @@ const ClassesList = ({ classes, onClassSelect, selectedClassId }) => {
style={{ maxWidth: '400px' }} style={{ maxWidth: '400px' }}
> >
<div className="flex-1 text-sm font-medium">{classe.nom_ambiance}</div> <div className="flex-1 text-sm font-medium">{classe.nom_ambiance}</div>
<div className="flex-1 text-sm font-medium">{classe.annee_scolaire}</div> <div className="flex-1 text-sm font-medium">{classe.school_year}</div>
</div> </div>
))} ))}
</div> </div>

View File

@ -79,7 +79,7 @@ const PlanningClassView = ({ schedule, onDrop, selectedLevel, handleUpdatePlanni
const renderTimeSlots = () => { const renderTimeSlots = () => {
const timeSlots = []; const timeSlots = [];
for (let hour = parseInt(formData.plage_horaire[0], 10); hour <= parseInt(formData.plage_horaire[1], 10); hour++) { for (let hour = parseInt(formData.time_range[0], 10); hour <= parseInt(formData.time_range[1], 10); hour++) {
const hourString = hour.toString().padStart(2, '0'); const hourString = hour.toString().padStart(2, '0');
timeSlots.push( timeSlots.push(

View File

@ -22,7 +22,7 @@ const ScheduleManagement = ({ handleUpdatePlanning, classes }) => {
const [schedule, setSchedule] = useState(null); const [schedule, setSchedule] = useState(null);
const { getNiveauxTabs } = useClasses(); const { getNiveauxTabs } = useClasses();
const niveauxLabels = Array.isArray(selectedClass?.niveaux) ? getNiveauxTabs(selectedClass.niveaux) : []; const niveauxLabels = Array.isArray(selectedClass?.levels) ? getNiveauxTabs(selectedClass.levels) : [];
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const handleOpenModal = () => setIsModalOpen(true); const handleOpenModal = () => setIsModalOpen(true);
@ -94,8 +94,8 @@ const ScheduleManagement = ({ handleUpdatePlanning, classes }) => {
}; };
const categorizedClasses = classes.reduce((acc, classe) => { const categorizedClasses = classes.reduce((acc, classe) => {
const { annee_scolaire } = classe; const { school_year } = classe;
const [startYear] = annee_scolaire.split('-').map(Number); const [startYear] = school_year.split('-').map(Number);
const category = startYear >= currentSchoolYearStart ? 'Actives' : 'Anciennes'; const category = startYear >= currentSchoolYearStart ? 'Actives' : 'Anciennes';
if (!acc[category]) { if (!acc[category]) {
@ -153,7 +153,7 @@ const ScheduleManagement = ({ handleUpdatePlanning, classes }) => {
Spécialités Spécialités
</h2> </h2>
</div> </div>
<SpecialitiesList teachers={selectedClass ? selectedClass.enseignants : []} /> <SpecialitiesList teachers={selectedClass ? selectedClass.teachers : []} />
</div> </div>
</div> </div>

View File

@ -68,7 +68,7 @@ const SpecialityEventModal = ({ isOpen, onClose, selectedCell, existingEvent, ha
} }
// Transformer eventData pour correspondre au format du planning // Transformer eventData pour correspondre au format du planning
const selectedTeacherData = formData.enseignants.find(teacher => teacher.id === parseInt(eventData.teacherId, 10)); const selectedTeacherData = formData.teachers.find(teacher => teacher.id === parseInt(eventData.teacherId, 10));
const newCourse = { const newCourse = {
color: '#FF0000', // Vous pouvez définir la couleur de manière dynamique si nécessaire color: '#FF0000', // Vous pouvez définir la couleur de manière dynamique si nécessaire
teachers: selectedTeacherData ? [`${selectedTeacherData.nom} ${selectedTeacherData.prenom}`] : [], teachers: selectedTeacherData ? [`${selectedTeacherData.nom} ${selectedTeacherData.prenom}`] : [],
@ -121,10 +121,10 @@ const SpecialityEventModal = ({ isOpen, onClose, selectedCell, existingEvent, ha
}; };
const filteredTeachers = selectedSpeciality const filteredTeachers = selectedSpeciality
? formData.enseignants.filter(teacher => ? formData.teachers.filter(teacher =>
teacher.specialites_ids.includes(parseInt(selectedSpeciality, 10)) teacher.specialites.includes(parseInt(selectedSpeciality, 10))
) )
: formData.enseignants; : formData.teachers;
const handleSpecialityChange = (e) => { const handleSpecialityChange = (e) => {
const specialityId = e.target.value; const specialityId = e.target.value;
@ -164,7 +164,7 @@ const SpecialityEventModal = ({ isOpen, onClose, selectedCell, existingEvent, ha
selected={selectedSpeciality} selected={selectedSpeciality}
choices={[ choices={[
{ value: '', label: 'Sélectionner une spécialité' }, { value: '', label: 'Sélectionner une spécialité' },
...groupSpecialitiesBySubject(formData.enseignants).map((speciality) => ({ ...groupSpecialitiesBySubject(formData.teachers).map((speciality) => ({
value: speciality.id, value: speciality.id,
label: speciality.nom label: speciality.nom
})) }))

View File

@ -20,7 +20,7 @@ const ToggleSwitch = ({ label, checked, onChange }) => {
id="toggle" id="toggle"
checked={checked} checked={checked}
onChange={handleChange} onChange={handleChange}
className="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer border-emerald-500 checked:right-0 checked:border-emerald-500 checked:bg-emerald-500 hover:border-emerald-500 hover:bg-emerald-500 focus:outline-none focus:ring-0" className="hover:text-emerald-500 absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer border-emerald-500 checked:right-0 checked:border-emerald-500 checked:bg-emerald-500 hover:border-emerald-500 hover:bg-emerald-500 focus:outline-none focus:ring-0"
ref={inputRef} // Reference to the input element ref={inputRef} // Reference to the input element
/> />
<label <label

View File

@ -41,23 +41,23 @@ export const ClasseFormProvider = ({ children, initialClasse }) => {
const newFormData = { const newFormData = {
nom_ambiance: initialClasse.nom_ambiance || '', nom_ambiance: initialClasse.nom_ambiance || '',
tranche_age: initialClasse.tranche_age || '', age_range: initialClasse.age_range || '',
nombre_eleves: initialClasse.nombre_eleves || '', number_of_students: initialClasse.number_of_students || '',
langue_enseignement: initialClasse.langue_enseignement || 'Français', teaching_language: initialClasse.teaching_language || 'Français',
annee_scolaire: initialClasse.annee_scolaire || '', school_year: initialClasse.school_year || '',
enseignants: initialClasse.enseignants || [], teachers: initialClasse.teachers || [],
enseignants_ids: initialClasse.enseignants_ids || [], teachers_details: initialClasse.teachers_details || [],
type: initialClasse.type || 1, type: initialClasse.type || 1,
plage_horaire: initialClasse.plage_horaire || ['08:30', '17:30'], time_range: initialClasse.time_range || ['08:30', '17:30'],
jours_ouverture: initialClasse.jours_ouverture || [1, 2, 4, 5], opening_days: initialClasse.opening_days || [1, 2, 4, 5],
niveaux: initialClasse.niveaux || [], levels: initialClasse.levels || [],
plannings: plannings.length ? plannings.map(planning => ({ // plannings: plannings.length ? plannings.map(planning => ({
niveau: planning.planning.niveau, // niveau: planning.planning.niveau,
emploiDuTemps: planning.planning.emploiDuTemps // emploiDuTemps: planning.planning.emploiDuTemps
})) : (initialClasse.niveaux || []).map(niveau => ({ // })) : (initialClasse.levels || []).map(niveau => ({
niveau: niveau, // niveau: niveau,
emploiDuTemps: generateEmploiDuTemps(initialClasse.type || 1) // emploiDuTemps: generateEmploiDuTemps(initialClasse.type || 1)
})) // }))
}; };
setFormData(newFormData); setFormData(newFormData);

View File

@ -51,16 +51,16 @@ export const ClassesProvider = ({ children }) => {
7: 'dimanche' 7: 'dimanche'
}; };
const getNiveauxLabels = (niveaux) => { const getNiveauxLabels = (levels) => {
return niveaux.map(niveauId => { return levels.map(niveauId => {
const niveau = allNiveaux.find(n => n.id === niveauId); const niveau = allNiveaux.find(n => n.id === niveauId);
return niveau ? niveau.name : niveauId; return niveau ? niveau.name : niveauId;
}); });
}; };
const getNiveauxTabs = (niveaux) => { const getNiveauxTabs = (levels) => {
// Trier les niveaux par id // Trier les levels par id
const sortedNiveaux = niveaux.sort((a, b) => a - b); const sortedNiveaux = levels.sort((a, b) => a - b);
// Mapper les labels correspondants // Mapper les labels correspondants
return sortedNiveaux.map(niveauId => { return sortedNiveaux.map(niveauId => {
@ -87,7 +87,7 @@ export const ClassesProvider = ({ children }) => {
const getAmbianceText = (classe) => { const getAmbianceText = (classe) => {
const ambiance = classe.nom_ambiance ? classe.nom_ambiance : ''; const ambiance = classe.nom_ambiance ? classe.nom_ambiance : '';
const trancheAge = classe.tranche_age ? `${classe.tranche_age} ans` : ''; const trancheAge = classe.age_range ? `${classe.age_range} ans` : '';
if (ambiance && trancheAge) { if (ambiance && trancheAge) {
return `${ambiance} (${trancheAge})`; return `${ambiance} (${trancheAge})`;
@ -111,20 +111,17 @@ export const ClassesProvider = ({ children }) => {
}; };
const updatePlannings = (formData, existingPlannings) => { const updatePlannings = (formData, existingPlannings) => {
return formData.niveaux.map(niveau => { return formData.levels.map(niveau => {
let existingPlanning = existingPlannings.find(planning => planning.niveau === niveau); let existingPlanning = existingPlannings.find(planning => planning.niveau === niveau);
const emploiDuTemps = formData.jours_ouverture.reduce((acc, dayId) => { const emploiDuTemps = formData.opening_days.reduce((acc, dayId) => {
const dayName = selectedDays[dayId]; const dayName = selectedDays[dayId];
console.log('dayId:', dayId, 'dayName:', dayName); // Ajout de log pour vérifier les correspondances
if (dayName) { if (dayName) {
acc[dayName] = existingPlanning?.emploiDuTemps?.[dayName] || []; acc[dayName] = existingPlanning?.emploiDuTemps?.[dayName] || [];
} }
return acc; return acc;
}, {}); }, {});
console.log('Emploi du Temps initialisé :', emploiDuTemps);
let updatedPlanning; let updatedPlanning;
if (formData.type === 1) { if (formData.type === 1) {
updatedPlanning = { updatedPlanning = {
@ -170,8 +167,6 @@ export const ClassesProvider = ({ children }) => {
}; };
} }
console.log('Updated Planning:', updatedPlanning);
// Fusionner les plannings existants avec les nouvelles données // Fusionner les plannings existants avec les nouvelles données
return existingPlanning return existingPlanning
? { ...existingPlanning, ...updatedPlanning } ? { ...existingPlanning, ...updatedPlanning }
@ -179,10 +174,10 @@ export const ClassesProvider = ({ children }) => {
}); });
}; };
const groupSpecialitiesBySubject = (enseignants) => { const groupSpecialitiesBySubject = (teachers) => {
const groupedSpecialities = {}; const groupedSpecialities = {};
enseignants.forEach(teacher => { teachers.forEach(teacher => {
teacher.specialites.forEach(specialite => { teacher.specialites.forEach(specialite => {
if (!groupedSpecialities[specialite.id]) { if (!groupedSpecialities[specialite.id]) {
groupedSpecialities[specialite.id] = { groupedSpecialities[specialite.id] = {

View File

@ -6,8 +6,8 @@ export const useSpecialityForm = () => useContext(SpecialityFormContext);
export const SpecialityFormProvider = ({ children, initialSpeciality }) => { export const SpecialityFormProvider = ({ children, initialSpeciality }) => {
const [formData, setFormData] = useState(() => ({ const [formData, setFormData] = useState(() => ({
nom: initialSpeciality.nom || '', name: initialSpeciality.name || '',
codeCouleur: initialSpeciality.codeCouleur || '#FFFFFF', color_code: initialSpeciality.color_code || '#FFFFFF',
})); }));
return ( return (

View File

@ -6,14 +6,18 @@ export const useTeacherForm = () => useContext(TeacherFormContext);
export const TeacherFormProvider = ({ children, initialTeacher }) => { export const TeacherFormProvider = ({ children, initialTeacher }) => {
const [formData, setFormData] = useState(() => ({ const [formData, setFormData] = useState(() => ({
nom: initialTeacher.nom || '', last_name: initialTeacher.last_name || '',
prenom: initialTeacher.prenom || '', first_name: initialTeacher.first_name || '',
mail: initialTeacher.mail || '', email: initialTeacher.email || '',
specialites_ids: initialTeacher.specialites_ids || [], specialities: initialTeacher.specialities || [],
profilAssocie_id: initialTeacher.profilAssocie_id || '', associated_profile: initialTeacher.associated_profile || '',
droit: initialTeacher.droit || 0 droit: {
label: initialTeacher.droit?.label || '',
id: initialTeacher.droit?.id || 0
}
})); }));
return ( return (
<TeacherFormContext.Provider value={{ formData, setFormData }}> <TeacherFormContext.Provider value={{ formData, setFormData }}>
{children} {children}

3
package-lock.json generated
View File

@ -1,9 +1,12 @@
{ {
"name": "n3wt-school", "name": "n3wt-school",
"version": "0.0.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "n3wt-school",
"version": "0.0.1",
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.5.0", "@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0", "@commitlint/config-conventional": "^19.5.0",