Files
n3wt-school/Front-End/src/components/Evaluation/EvaluationList.js

154 lines
5.2 KiB
JavaScript

'use client';
import React, { useState } from 'react';
import { Trash2, Edit2, ClipboardList, ChevronDown, ChevronUp } from 'lucide-react';
import Button from '@/components/Form/Button';
import Popup from '@/components/Popup';
import { useNotification } from '@/context/NotificationContext';
export default function EvaluationList({
evaluations,
onDelete,
onEdit,
onGradeStudents,
}) {
const [expandedId, setExpandedId] = useState(null);
const [deletePopupVisible, setDeletePopupVisible] = useState(false);
const [evaluationToDelete, setEvaluationToDelete] = useState(null);
const { showNotification } = useNotification();
const handleDeleteClick = (evaluation) => {
setEvaluationToDelete(evaluation);
setDeletePopupVisible(true);
};
const handleConfirmDelete = () => {
if (evaluationToDelete && onDelete) {
onDelete(evaluationToDelete.id)
.then(() => {
showNotification('Évaluation supprimée avec succès', 'success', 'Succès');
setDeletePopupVisible(false);
setEvaluationToDelete(null);
})
.catch((error) => {
showNotification('Erreur lors de la suppression', 'error', 'Erreur');
});
}
};
// Grouper les évaluations par matière
const groupedBySpeciality = evaluations.reduce((acc, ev) => {
const key = ev.speciality_name || 'Sans matière';
if (!acc[key]) {
acc[key] = {
name: key,
color: ev.speciality_color || '#6B7280',
evaluations: [],
};
}
acc[key].evaluations.push(ev);
return acc;
}, {});
if (evaluations.length === 0) {
return (
<div className="text-center text-gray-500 py-8">
Aucune évaluation créée pour cette période
</div>
);
}
return (
<div className="space-y-4">
{Object.values(groupedBySpeciality).map((group) => (
<div
key={group.name}
className="border border-gray-200 rounded-lg overflow-hidden"
>
<div
className="flex items-center justify-between p-3 bg-gray-50 cursor-pointer"
onClick={() =>
setExpandedId(expandedId === group.name ? null : group.name)
}
>
<div className="flex items-center gap-2">
<span
className="w-3 h-3 rounded-full"
style={{ backgroundColor: group.color }}
/>
<span className="font-medium text-gray-800">{group.name}</span>
<span className="text-sm text-gray-500">
({group.evaluations.length} évaluation
{group.evaluations.length > 1 ? 's' : ''})
</span>
</div>
{expandedId === group.name ? (
<ChevronUp size={20} className="text-gray-500" />
) : (
<ChevronDown size={20} className="text-gray-500" />
)}
</div>
{expandedId === group.name && (
<div className="divide-y divide-gray-100">
{group.evaluations.map((evaluation) => (
<div
key={evaluation.id}
className="p-3 flex items-center justify-between hover:bg-gray-50"
>
<div className="flex-1">
<div className="font-medium text-gray-700">
{evaluation.name}
</div>
<div className="text-sm text-gray-500 flex gap-3">
{evaluation.date && (
<span>
{new Date(evaluation.date).toLocaleDateString('fr-FR')}
</span>
)}
<span>Note max: {evaluation.max_score}</span>
<span>Coef: {evaluation.coefficient}</span>
</div>
</div>
<div className="flex gap-2">
<Button
primary
onClick={() => onGradeStudents(evaluation)}
icon={<ClipboardList size={16} />}
text="Noter"
title="Noter les élèves"
/>
<button
onClick={() => onEdit && onEdit(evaluation)}
className="p-2 text-gray-500 hover:text-blue-600 hover:bg-blue-50 rounded"
title="Modifier"
>
<Edit2 size={16} />
</button>
<button
onClick={() => handleDeleteClick(evaluation)}
className="p-2 text-gray-500 hover:text-red-600 hover:bg-red-50 rounded"
title="Supprimer"
>
<Trash2 size={16} />
</button>
</div>
</div>
))}
</div>
)}
</div>
))}
<Popup
isOpen={deletePopupVisible}
message={`Êtes-vous sûr de vouloir supprimer l'évaluation "${evaluationToDelete?.name}" ?`}
onConfirm={handleConfirmDelete}
onCancel={() => {
setDeletePopupVisible(false);
setEvaluationToDelete(null);
}}
/>
</div>
);
}