chore: Ajout des présences dans le dashboard

This commit is contained in:
N3WT DE COMPET
2025-05-25 19:33:20 +02:00
parent 98763dc90a
commit d877c956b7
3 changed files with 97 additions and 46 deletions

View File

@ -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)

View File

@ -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 }) => (
<div className="bg-stone-50 p-4 rounded-lg shadow-sm border border-gray-100 mb-4">
@ -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')}
</h2>
{/* Insérer ici un composant de graphique */}
<div className="h-64 bg-gray-50 rounded flex items-center justify-center">
<div className="h-64 bg-gray-50 rounded flex items-center justify-center mb-6">
<TrendingUp size={48} className="text-gray-300" />
</div>
</div>
@ -150,6 +177,9 @@ export default function DashboardPage() {
))}
</div>
</div>
{/* Ajout du composant Attendance en dessous, en lecture seule */}
<Attendance absences={absencesToday} readOnly={true} />
</div>
);
}

View File

@ -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 }) {
<time className="mb-1 text-xs font-normal leading-none text-gray-400">
{absence.date}
</time>
{readOnly && absence.student_name && (
<div className="mb-1 text-sm font-semibold text-gray-700">
{absence.student_name}
</div>
)}
<div className="flex items-center gap-2">
<span className="font-medium">{absence.type}</span>
<span
@ -44,7 +54,8 @@ export default function Attendance({ absences, onToggleJustify, onDelete }) {
{absence.commentaire}
</div>
</div>
{/* Actions à droite */}
{/* Actions masquées en lecture seule */}
{!readOnly && (
<div className="flex flex-col items-end gap-2 min-w-[110px]">
<ToggleSwitch
name={`justified-${idx}`}
@ -87,6 +98,7 @@ export default function Attendance({ absences, onToggleJustify, onDelete }) {
title="Evaluez l'élève"
/>
</div>
)}
</div>
</li>
))}