mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Bilan de compétence d'un élève [#16]
This commit is contained in:
@ -0,0 +1,114 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSearchParams, useRouter } from 'next/navigation';
|
||||
import Button from '@/components/Button';
|
||||
import GradeView from '@/components/Grades/GradeView';
|
||||
import {
|
||||
fetchStudentCompetencies,
|
||||
editStudentCompetencies,
|
||||
} from '@/app/actions/subscriptionAction';
|
||||
import SectionHeader from '@/components/SectionHeader';
|
||||
import { Award } from 'lucide-react';
|
||||
import { useCsrfToken } from '@/context/CsrfContext';
|
||||
|
||||
// À remplacer par un fetch réel des compétences selon l'élève
|
||||
const mockCompetencies = [
|
||||
{ id: 1, name: 'Lire un texte court', score: null },
|
||||
{ id: 2, name: 'Résoudre un problème simple', score: null },
|
||||
{ id: 3, name: 'Exprimer une idée à l’oral', score: null },
|
||||
];
|
||||
|
||||
export default function StudentCompetenciesPage() {
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
const csrfToken = useCsrfToken();
|
||||
const [studentCompetencies, setStudentCompetencies] = useState([]);
|
||||
const [grades, setGrades] = useState({});
|
||||
const studentId = searchParams.get('studentId');
|
||||
|
||||
useEffect(() => {
|
||||
fetchStudentCompetencies(studentId)
|
||||
.then((data) => {
|
||||
setStudentCompetencies(data);
|
||||
})
|
||||
.catch((error) =>
|
||||
logger.error('Error fetching studentCompetencies:', error)
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (studentCompetencies.data) {
|
||||
const initialGrades = {};
|
||||
studentCompetencies.data.forEach((domaine) => {
|
||||
domaine.categories.forEach((cat) => {
|
||||
cat.competences.forEach((comp) => {
|
||||
initialGrades[comp.competence_id] = comp.score ?? 0;
|
||||
});
|
||||
});
|
||||
});
|
||||
setGrades(initialGrades);
|
||||
}
|
||||
}, [studentCompetencies.data]);
|
||||
|
||||
const handleScoreChange = (competencyId, score) => {
|
||||
setCompetencies((prev) =>
|
||||
prev.map((comp) => (comp.id === competencyId ? { ...comp, score } : comp))
|
||||
);
|
||||
};
|
||||
|
||||
const handleGradeChange = (competenceId, level) => {
|
||||
setGrades((prev) => ({
|
||||
...prev,
|
||||
[competenceId]: level,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
const data = Object.entries(grades).map(([competenceId, score]) => ({
|
||||
studentId,
|
||||
competenceId,
|
||||
grade: score,
|
||||
}));
|
||||
|
||||
editStudentCompetencies(data, csrfToken)
|
||||
.then(() => {
|
||||
alert('Bilan de compétence enregistré !');
|
||||
router.back();
|
||||
})
|
||||
.catch((error) => {
|
||||
alert("Erreur lors de l'enregistrement du bilan");
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col p-4">
|
||||
<SectionHeader
|
||||
icon={Award}
|
||||
title="Bilan de compétence"
|
||||
description="Evaluez les compétence de l'élève"
|
||||
/>
|
||||
<div className="flex-1 min-h-0 flex flex-col">
|
||||
<form
|
||||
className="flex-1 min-h-0 flex flex-col"
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
handleSubmit();
|
||||
}}
|
||||
>
|
||||
{/* Zone scrollable pour les compétences */}
|
||||
<div className="flex-1 min-h-0 overflow-y-auto">
|
||||
<GradeView
|
||||
data={studentCompetencies.data}
|
||||
grades={grades}
|
||||
onGradeChange={handleGradeChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end">
|
||||
<Button text="Enregistrer le bilan" primary type="submit" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user