diff --git a/Back-End/Subscriptions/serializers.py b/Back-End/Subscriptions/serializers.py index ea4d524..f506981 100644 --- a/Back-End/Subscriptions/serializers.py +++ b/Back-End/Subscriptions/serializers.py @@ -23,9 +23,18 @@ import pytz import Subscriptions.util as util class AbsenceManagementSerializer(serializers.ModelSerializer): + student_name = serializers.SerializerMethodField() + class Meta: model = AbsenceManagement fields = '__all__' + # Ajoute les nouveaux champs au retour JSON + extra_fields = ['student_name'] + + def get_student_name(self, obj): + if obj.student: + return f"{obj.student.first_name} {obj.student.last_name}" + return None class RegistrationSchoolFileMasterSerializer(serializers.ModelSerializer): id = serializers.IntegerField(required=False) diff --git a/Front-End/src/app/[locale]/admin/page.js b/Front-End/src/app/[locale]/admin/page.js index 47d4c51..043cccc 100644 --- a/Front-End/src/app/[locale]/admin/page.js +++ b/Front-End/src/app/[locale]/admin/page.js @@ -7,10 +7,15 @@ import ClasseDetails from '@/components/ClasseDetails'; import { fetchClasses } from '@/app/actions/schoolAction'; import StatCard from '@/components/StatCard'; import logger from '@/utils/logger'; -import { fetchRegisterForms } from '@/app/actions/subscriptionAction'; +import { + fetchRegisterForms, + fetchAbsences, +} from '@/app/actions/subscriptionAction'; import { fetchUpcomingEvents } from '@/app/actions/planningAction'; import { useEstablishment } from '@/context/EstablishmentContext'; import { useNotification } from '@/context/NotificationContext'; +import Attendance from '@/components/Grades/Attendance'; + // Composant EventCard pour afficher les événements const EventCard = ({ title, date, description, type }) => (
@@ -38,6 +43,7 @@ export default function DashboardPage() { }); const [classes, setClasses] = useState([]); + const [absencesToday, setAbsencesToday] = useState([]); const { selectedEstablishmentId, selectedEstablishmentTotalCapacity } = useEstablishment(); const { showNotification } = useNotification(); @@ -90,6 +96,27 @@ export default function DashboardPage() { }) .catch((error) => { logger.error('Error fetching upcoming events:', error); + }); + + // Fetch absences/retards du jour + fetchAbsences(selectedEstablishmentId) + .then((data) => { + const today = new Date().toISOString().split('T')[0]; + const absToday = (data || []).filter((a) => a.day === today); + // Mapping pour Attendance + setAbsencesToday( + absToday.map((a) => ({ + id: a.id, + date: a.day, + type: [1, 2].includes(a.reason) ? 'Absence' : 'Retard', + justified: [1, 3].includes(a.reason), + commentaire: a.commentaire, + student_name: a.student_name, + })) + ); + }) + .catch((error) => { + logger.error('Erreur lors du fetch des absences du jour:', error); }) .finally(() => { setIsLoading(false); // Fin du chargement @@ -137,7 +164,7 @@ export default function DashboardPage() { {t('inscriptionTrends')} {/* Insérer ici un composant de graphique */} -
+
@@ -150,6 +177,9 @@ export default function DashboardPage() { ))}
+ + {/* Ajout du composant Attendance en dessous, en lecture seule */} + ); } diff --git a/Front-End/src/components/Grades/Attendance.js b/Front-End/src/components/Grades/Attendance.js index cf42c6d..715a561 100644 --- a/Front-End/src/components/Grades/Attendance.js +++ b/Front-End/src/components/Grades/Attendance.js @@ -5,7 +5,12 @@ import Button from '@/components/Button'; import Popup from '@/components/Popup'; import { useNotification } from '@/context/NotificationContext'; -export default function Attendance({ absences, onToggleJustify, onDelete }) { +export default function Attendance({ + absences, + onToggleJustify, + onDelete, + readOnly, +}) { const [popupVisible, setPopupVisible] = useState(false); const [popupMessage, setPopupMessage] = useState(''); const [removePopupVisible, setRemovePopupVisible] = useState(false); @@ -32,6 +37,11 @@ export default function Attendance({ absences, onToggleJustify, onDelete }) { + {readOnly && absence.student_name && ( +
+ {absence.student_name} +
+ )}
{absence.type}
- {/* Actions à droite */} -
- onToggleJustify(absence)} - label="Justifiée" - /> -
+ {/* Actions masquées en lecture seule */} + {!readOnly && ( +
+ onToggleJustify(absence)} + label="Justifiée" + /> +
+ )} ))}