diff --git a/Back-End/Auth/views.py b/Back-End/Auth/views.py index cd5c385..eb14f77 100644 --- a/Back-End/Auth/views.py +++ b/Back-End/Auth/views.py @@ -77,8 +77,7 @@ class ProfileView(APIView): return JsonResponse(profil_serializer.data, safe=False) - - return JsonResponse(profil_serializer.errors, safe=False) + return JsonResponse(profil_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) def put(self, request, _id): data=JSONParser().parse(request) @@ -88,7 +87,7 @@ class ProfileView(APIView): profil_serializer.save() return JsonResponse("Updated Successfully", safe=False) - return JsonResponse(profil_serializer.errors, safe=False) + return JsonResponse(profil_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, _id): return bdd.delete_object(Profile, _id) diff --git a/Front-End/src/app/[locale]/admin/structure/page.js b/Front-End/src/app/[locale]/admin/structure/page.js index e76e5ed..46ca74e 100644 --- a/Front-End/src/app/[locale]/admin/structure/page.js +++ b/Front-End/src/app/[locale]/admin/structure/page.js @@ -6,7 +6,17 @@ import FeesManagement from '@/components/Structure/Tarification/FeesManagement'; import DjangoCSRFToken from '@/components/DjangoCSRFToken'; import useCsrfToken from '@/hooks/useCsrfToken'; import { ClassesProvider } from '@/context/ClassesContext'; -import { fetchSpecialities, fetchTeachers, fetchClasses, fetchSchedules, fetchRegistrationDiscounts, fetchTuitionDiscounts, fetchRegistrationFees, fetchTuitionFees } from '@/app/lib/schoolAction'; +import { createDatas, + updateDatas, + removeDatas, + fetchSpecialities, + fetchTeachers, + fetchClasses, + fetchSchedules, + fetchRegistrationDiscounts, + fetchTuitionDiscounts, + fetchRegistrationFees, + fetchTuitionFees } from '@/app/lib/schoolAction'; import SidebarTabs from '@/components/SidebarTabs'; export default function Page() { @@ -111,23 +121,7 @@ export default function Page() { }; const handleCreate = (url, newData, setDatas) => { - return fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - body: JSON.stringify(newData), - credentials: 'include' - }) - .then(response => { - if (!response.ok) { - return response.json().then(errorData => { - throw errorData; - }); - } - return response.json(); - }) + return createDatas(url, newData, csrfToken) .then(data => { setDatas(prevState => [...prevState, data]); return data; @@ -139,23 +133,7 @@ export default function Page() { }; const handleEdit = (url, id, updatedData, setDatas) => { - return fetch(`${url}/${id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - body: JSON.stringify(updatedData), - credentials: 'include' - }) - .then(response => { - if (!response.ok) { - return response.json().then(errorData => { - throw errorData; - }); - } - return response.json(); - }) + return updateDatas(url, id, updatedData, csrfToken) .then(data => { setDatas(prevState => prevState.map(item => item.id === id ? data : item)); return data; @@ -167,22 +145,7 @@ export default function Page() { }; const handleDelete = (url, id, setDatas) => { - return fetch(`${url}/${id}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrfToken - }, - credentials: 'include' - }) - .then(response => { - if (!response.ok) { - return response.json().then(errorData => { - throw errorData; - }); - } - return response.json(); - }) + return removeDatas(url, id, csrfToken) .then(data => { setDatas(prevState => prevState.filter(item => item.id !== id)); return data; diff --git a/Front-End/src/app/lib/schoolAction.js b/Front-End/src/app/lib/schoolAction.js index 7035cab..2c91893 100644 --- a/Front-End/src/app/lib/schoolAction.js +++ b/Front-End/src/app/lib/schoolAction.js @@ -58,4 +58,42 @@ export const fetchRegistrationFees = () => { export const fetchTuitionFees = () => { return fetch(`${BE_SCHOOL_FEES_URL}/tuition`) .then(requestResponseHandler) +}; + +export const createDatas = (url, newData, csrfToken) => { + return fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrfToken + }, + body: JSON.stringify(newData), + credentials: 'include' + }) + .then(requestResponseHandler) +}; + +export const updateDatas = (url, id, updatedData, csrfToken) => { + return fetch(`${url}/${id}`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrfToken + }, + body: JSON.stringify(updatedData), + credentials: 'include' + }) + .then(requestResponseHandler) + }; + +export const removeDatas = (url, id, csrfToken) => { + return fetch(`${url}/${id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrfToken + }, + credentials: 'include' + }) + .then(requestResponseHandler) }; \ No newline at end of file diff --git a/Front-End/src/components/Structure/Configuration/ClassesSection.js b/Front-End/src/components/Structure/Configuration/ClassesSection.js index c9d7aaf..e7af1ad 100644 --- a/Front-End/src/components/Structure/Configuration/ClassesSection.js +++ b/Front-End/src/components/Structure/Configuration/ClassesSection.js @@ -139,6 +139,11 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi return choices; }; + // Récupération des messages d'erreur + const getError = (field) => { + return localErrors?.[field]?.[0]; + }; + const handleAddClass = () => { setNewClass({ id: Date.now(), atmosphere_name: '', age_range: '', levels: [], number_of_students: '', school_year: '', teachers: [] }); setFormData({ atmosphere_name: '', age_range: '', levels: [], number_of_students: '', school_year: '', teachers: [] }); @@ -169,7 +174,11 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi setLocalErrors({}); }) .catch((error) => { - console.error(error); + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); + } }); } else { setPopupMessage("Tous les champs doivent être remplis et valides"); @@ -187,7 +196,11 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi setLocalErrors({}); }) .catch((error) => { - console.error(error); + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); + } }); } else { setPopupMessage("Tous les champs doivent être remplis et valides"); @@ -247,7 +260,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi value={currentData.atmosphere_name} onChange={handleChange} placeholder="Nom d'ambiance" - errorMsg={localErrors && localErrors.atmosphere_name && Array.isArray(localErrors.atmosphere_name) ? localErrors.atmosphere_name[0] : ''} + errorMsg={getError('atmosphere_name')} /> ); case 'TRANCHE D\'AGE': @@ -257,7 +270,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi value={currentData.age_range} onChange={handleChange} placeholder="Tranche d'âge (ex: 3-6)" - errorMsg={localErrors && localErrors.age_range && Array.isArray(localErrors.age_range) ? localErrors.age_range[0] : ''} + errorMsg={getError('age_range')} /> ) case 'NIVEAUX': @@ -267,7 +280,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi options={allNiveaux} selectedOptions={currentData.levels ? currentData.levels.map(levelId => allNiveaux.find(level => level.id === levelId)) : []} onChange={handleMultiSelectChange} - errorMsg={localErrors && localErrors.levels && Array.isArray(localErrors.levels) ? localErrors.levels[0] : ''} + errorMsg={getError('levels')} /> ); case 'CAPACITE': @@ -278,7 +291,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi value={currentData.number_of_students} onChange={handleChange} placeholder="Capacité" - errorMsg={localErrors && localErrors.number_of_students && Array.isArray(localErrors.number_of_students) ? localErrors.number_of_students[0] : ''} + errorMsg={getError('number_of_students')} /> ) case 'ANNÉE SCOLAIRE' : @@ -290,7 +303,7 @@ const ClassesSection = ({ classes, setClasses, teachers, handleCreate, handleEdi choices={getSchoolYearChoices()} callback={handleChange} selected={currentData.school_year || ''} - errorMsg={localErrors && localErrors.school_year && Array.isArray(localErrors.school_year) ? localErrors.school_year[0] : ''} + errorMsg={getError('school_year')} IconItem={null} disabled={false} /> diff --git a/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js b/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js index 762bbca..b3ae3bd 100644 --- a/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js +++ b/Front-End/src/components/Structure/Configuration/SpecialitiesSection.js @@ -16,6 +16,11 @@ const SpecialitiesSection = ({ specialities, setSpecialities, handleCreate, hand const [popupVisible, setPopupVisible] = useState(false); const [popupMessage, setPopupMessage] = useState(""); + // Récupération des messages d'erreur + const getError = (field) => { + return localErrors?.[field]?.[0]; + }; + const handleAddSpeciality = () => { setNewSpeciality({ id: Date.now(), name: '', color_code: '' }); }; @@ -39,11 +44,11 @@ const SpecialitiesSection = ({ specialities, setSpecialities, handleCreate, hand setNewSpeciality(null); setLocalErrors({}); }) - .catch(error => { - if (error && typeof error === 'object') { - setLocalErrors(error); - } else { - console.error(error); + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); } }); } else { @@ -61,11 +66,11 @@ const SpecialitiesSection = ({ specialities, setSpecialities, handleCreate, hand setEditingSpeciality(null); setLocalErrors({}); }) - .catch(error => { - if (error && typeof error === 'object') { - setLocalErrors(error); - } else { - console.error(error); + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); } }); } else { @@ -111,7 +116,7 @@ const SpecialitiesSection = ({ specialities, setSpecialities, handleCreate, hand onTextChange={handleChange} onColorChange={handleChange} placeholder="Nom de la spécialité" - errorMsg={localErrors && localErrors.name && Array.isArray(localErrors.name) ? localErrors.name[0] : ''} + errorMsg={getError('name')} /> ); case 'ACTIONS': diff --git a/Front-End/src/components/Structure/Configuration/TeachersSection.js b/Front-End/src/components/Structure/Configuration/TeachersSection.js index 27746bc..801ea06 100644 --- a/Front-End/src/components/Structure/Configuration/TeachersSection.js +++ b/Front-End/src/components/Structure/Configuration/TeachersSection.js @@ -98,6 +98,11 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha const [popupVisible, setPopupVisible] = useState(false); const [popupMessage, setPopupMessage] = useState(""); + // Récupération des messages d'erreur + const getError = (field) => { + return localErrors?.[field]?.[0]; + }; + const handleAddTeacher = () => { setNewTeacher({ id: Date.now(), last_name: '', first_name: '', email: '', specialities: [], droit: 0 }); setFormData({ last_name: '', first_name: '', email: '', specialities: [], droit: 0 }); @@ -133,14 +138,22 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha setTeachers([createdTeacher, ...teachers]); setNewTeacher(null); setLocalErrors({}); + }) + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); + } }); } + setLocalErrors({}); }) - .catch(error => { - if (error && typeof error === 'object') { - setLocalErrors(error); - } else { - console.error(error); + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); } }); } else { @@ -165,9 +178,20 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha setEditingTeacher(null); setFormData({}); }) + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); + } + }); }) - .catch(error => { - console.error(error); + .catch((error) => { + console.error('Error:', error.message); + if (error.details) { + console.error('Form errors:', error.details); + setLocalErrors(error.details); + } }); } else { @@ -184,8 +208,6 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha parsedValue = checked ? 1 : 0; } - console.log(`handleChange - name: ${name}, parsedValue: ${parsedValue}, type: ${type}, checked: ${checked}`); - if (editingTeacher) { setFormData((prevData) => ({ ...prevData, @@ -237,7 +259,7 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha value={currentData.last_name} onChange={handleChange} placeholder="Nom de l'enseignant" - errorMsg={localErrors && localErrors.last_name && Array.isArray(localErrors.last_name) ? localErrors.last_name[0] : ''} + errorMsg={getError('last_name')} /> ); @@ -256,7 +278,7 @@ const TeachersSection = ({ teachers, setTeachers, specialities, handleCreate, ha value={currentData.email} onChange={handleChange} placeholder="Email de l'enseignant" - errorMsg={localErrors && localErrors.email && Array.isArray(localErrors.email) ? localErrors.email[0] : ''} + errorMsg={getError('email')} /> ); case 'SPECIALITES':