amelioration notes
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Dashboard élève - VERSION AMÉLIORÉE
|
* Dashboard élève - VERSION FINALE CORRECTE
|
||||||
* Avec historique des 4 dernières évaluations et graphique de progression
|
* Basé sur la structure BDD réelle analysée le 02/01/2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once __DIR__ . '/../config/config.php';
|
require_once __DIR__ . '/../config/config.php';
|
||||||
@ -76,8 +76,11 @@ $query4Dernieres = "SELECT
|
|||||||
e.titre,
|
e.titre,
|
||||||
e.description,
|
e.description,
|
||||||
te.note,
|
te.note,
|
||||||
|
te.note_sur,
|
||||||
te.pourcentage,
|
te.pourcentage,
|
||||||
te.date_fin
|
te.temps_passe,
|
||||||
|
te.date_fin,
|
||||||
|
(SELECT COUNT(*) FROM questions WHERE id_evaluation = e.id_evaluation) as nb_questions
|
||||||
FROM tentatives_eleves te
|
FROM tentatives_eleves te
|
||||||
INNER JOIN evaluations e ON te.id_evaluation = e.id_evaluation
|
INNER JOIN evaluations e ON te.id_evaluation = e.id_evaluation
|
||||||
WHERE te.id_eleve = ?
|
WHERE te.id_eleve = ?
|
||||||
@ -87,22 +90,12 @@ $query4Dernieres = "SELECT
|
|||||||
|
|
||||||
$dernieresEvals = $db->fetchAll($query4Dernieres, [$user['id_utilisateur']]);
|
$dernieresEvals = $db->fetchAll($query4Dernieres, [$user['id_utilisateur']]);
|
||||||
|
|
||||||
// Ajouter le nombre de questions pour chaque évaluation
|
// Calculer la moyenne des 4 dernières (arrondie au demi-point supérieur)
|
||||||
foreach ($dernieresEvals as &$eval) {
|
|
||||||
$queryNbQuestions = "SELECT COUNT(*) as nb FROM questions WHERE id_evaluation = ?";
|
|
||||||
$result = $db->fetchOne($queryNbQuestions, [$eval['id_evaluation']]);
|
|
||||||
$eval['nb_questions'] = $result['nb'] ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculer la moyenne des 4 dernières
|
|
||||||
$moyenne4Dernieres = 0;
|
$moyenne4Dernieres = 0;
|
||||||
if (!empty($dernieresEvals)) {
|
if (!empty($dernieresEvals)) {
|
||||||
$notes = array_filter(array_column($dernieresEvals, 'note'), function($n) {
|
$somme = array_sum(array_column($dernieresEvals, 'note'));
|
||||||
return $n !== null && is_numeric($n);
|
$moyenne_brute = $somme / count($dernieresEvals);
|
||||||
});
|
$moyenne4Dernieres = ceil($moyenne_brute * 2) / 2; // Arrondi demi-point sup
|
||||||
if (!empty($notes)) {
|
|
||||||
$moyenne4Dernieres = array_sum($notes) / count($notes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupérer TOUTES les évaluations terminées pour le graphique
|
// Récupérer TOUTES les évaluations terminées pour le graphique
|
||||||
@ -127,7 +120,6 @@ $queryStats = "SELECT
|
|||||||
COUNT(CASE WHEN t.statut = 'terminee' THEN 1 END) as nb_evaluations_terminees,
|
COUNT(CASE WHEN t.statut = 'terminee' THEN 1 END) as nb_evaluations_terminees,
|
||||||
AVG(CASE WHEN t.statut = 'terminee' THEN t.note ELSE NULL END) as moyenne_generale
|
AVG(CASE WHEN t.statut = 'terminee' THEN t.note ELSE NULL END) as moyenne_generale
|
||||||
FROM tentatives_eleves t
|
FROM tentatives_eleves t
|
||||||
INNER JOIN evaluations e ON t.id_evaluation = e.id_evaluation
|
|
||||||
WHERE t.id_eleve = ?";
|
WHERE t.id_eleve = ?";
|
||||||
|
|
||||||
$stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
$stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
||||||
@ -136,6 +128,11 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
'moyenne_generale' => null
|
'moyenne_generale' => null
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Arrondir la moyenne générale au demi-point supérieur
|
||||||
|
if ($stats['moyenne_generale'] !== null) {
|
||||||
|
$stats['moyenne_generale'] = ceil($stats['moyenne_generale'] * 2) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
@ -262,16 +259,12 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
border-bottom: 2px solid #f0f0f0;
|
border-bottom: 2px solid #f0f0f0;
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dernieres-evals-grid {
|
.dernieres-evals-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.eval-card-small {
|
.eval-card-small {
|
||||||
@ -297,10 +290,12 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.eval-card-small .chapitre {
|
.eval-card-small .description {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
height: 32px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-display-large {
|
.note-display-large {
|
||||||
@ -311,7 +306,7 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
}
|
}
|
||||||
|
|
||||||
.note-fraction {
|
.note-fraction {
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
color: #666;
|
color: #666;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
@ -326,6 +321,7 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #999;
|
color: #999;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moyenne-4 {
|
.moyenne-4 {
|
||||||
@ -334,6 +330,9 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moyenne-4 h3 {
|
.moyenne-4 h3 {
|
||||||
@ -486,13 +485,6 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
border-color: #2196f3;
|
border-color: #2196f3;
|
||||||
color: #1565c0;
|
color: #1565c0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-data-message {
|
|
||||||
text-align: center;
|
|
||||||
padding: 40px;
|
|
||||||
color: #999;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -530,7 +522,7 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
<h3>📊 Moyenne générale</h3>
|
<h3>📊 Moyenne générale</h3>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<?= $stats['moyenne_generale'] !== null
|
<?= $stats['moyenne_generale'] !== null
|
||||||
? number_format($stats['moyenne_generale'], 2) . '/20'
|
? number_format($stats['moyenne_generale'], 1) . '/20'
|
||||||
: '-' ?>
|
: '-' ?>
|
||||||
</div>
|
</div>
|
||||||
<?php if (!empty($toutesEvals) && count($toutesEvals) > 1): ?>
|
<?php if (!empty($toutesEvals) && count($toutesEvals) > 1): ?>
|
||||||
@ -553,35 +545,40 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
<!-- HISTORIQUE 4 DERNIÈRES ÉVALUATIONS -->
|
<!-- HISTORIQUE 4 DERNIÈRES ÉVALUATIONS -->
|
||||||
<?php if (!empty($dernieresEvals)): ?>
|
<?php if (!empty($dernieresEvals)): ?>
|
||||||
<div class="historique-section">
|
<div class="historique-section">
|
||||||
<h2 class="section-title">
|
<h2 class="section-title">📋 Mes 4 dernières évaluations</h2>
|
||||||
<span>📋 Mes 4 dernières évaluations</span>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="dernieres-evals-grid">
|
<div class="dernieres-evals-grid">
|
||||||
<?php foreach ($dernieresEvals as $eval): ?>
|
<?php foreach ($dernieresEvals as $eval):
|
||||||
|
// Arrondir la note au demi-point supérieur
|
||||||
|
$note_arrondie = ceil($eval['note'] * 2) / 2;
|
||||||
|
|
||||||
|
// Calculer le nombre de questions réussies
|
||||||
|
$questions_reussies = ($eval['note'] / 20) * $eval['nb_questions'];
|
||||||
|
?>
|
||||||
<div class="eval-card-small">
|
<div class="eval-card-small">
|
||||||
<h4 title="<?= htmlspecialchars($eval['titre']) ?>">
|
<h4 title="<?= htmlspecialchars($eval['titre']) ?>">
|
||||||
<?= htmlspecialchars($eval['titre']) ?>
|
<?= htmlspecialchars($eval['titre']) ?>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="chapitre">
|
<div class="description">
|
||||||
<?= !empty($eval['description']) ? htmlspecialchars(substr($eval['description'], 0, 50)) . (strlen($eval['description']) > 50 ? '...' : '') : 'Évaluation terminée' ?>
|
<?= htmlspecialchars($eval['description'] ?? '') ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="note-display-large">
|
<div class="note-display-large">
|
||||||
<div>
|
<div>
|
||||||
<?php if ($eval['nb_questions'] > 0): ?>
|
|
||||||
<div class="note-fraction">
|
<div class="note-fraction">
|
||||||
<?= round($eval['pourcentage'] * $eval['nb_questions'] / 100, 1) ?>/<?= $eval['nb_questions'] ?> questions
|
<?= number_format($questions_reussies, 1) ?>/<?= $eval['nb_questions'] ?> questions
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
|
||||||
<div class="note-sur-20">
|
<div class="note-sur-20">
|
||||||
<?= number_format($eval['note'], 2) ?>/20
|
<?= number_format($note_arrondie, 1) ?>/20
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right;">
|
||||||
<div class="note-fraction">
|
<div class="note-fraction">
|
||||||
<?= round($eval['pourcentage']) ?>%
|
<?= round($eval['pourcentage']) ?>%
|
||||||
</div>
|
</div>
|
||||||
|
<div style="font-size: 11px; color: #999; margin-top: 3px;">
|
||||||
|
⏱️ <?= gmdate('i:s', $eval['temps_passe'] ?? 0) ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -592,12 +589,10 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<!-- Moyenne des 4 dernières -->
|
<!-- Moyenne des 4 dernières -->
|
||||||
<?php if ($moyenne4Dernieres > 0): ?>
|
|
||||||
<div class="moyenne-4">
|
<div class="moyenne-4">
|
||||||
<h3>Moyenne sur ces <?= count($dernieresEvals) ?> évaluation<?= count($dernieresEvals) > 1 ? 's' : '' ?></h3>
|
<h3>Moyenne sur ces 4 évaluations</h3>
|
||||||
<div class="value"><?= number_format($moyenne4Dernieres, 2) ?>/20</div>
|
<div class="value"><?= number_format($moyenne4Dernieres, 1) ?>/20</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -634,6 +629,7 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p>
|
<p>
|
||||||
<strong>Durée :</strong> <?= $eval['duree_minutes'] ?? 'Libre' ?> min
|
<strong>Durée :</strong> <?= $eval['duree_minutes'] ?? 'Libre' ?> min
|
||||||
|
| <strong>Note :</strong> /<?= $eval['note_totale'] ?? 20 ?>
|
||||||
</p>
|
</p>
|
||||||
<?php if (isset($eval['fin_acces'])): ?>
|
<?php if (isset($eval['fin_acces'])): ?>
|
||||||
<p style="color: #f57c00;">
|
<p style="color: #f57c00;">
|
||||||
@ -648,8 +644,11 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<?php if ($statut === 'terminee'): ?>
|
<?php if ($statut === 'terminee'): ?>
|
||||||
|
<?php
|
||||||
|
$note_affichee = ceil($eval['note_obtenue'] * 2) / 2;
|
||||||
|
?>
|
||||||
<span class="note-display">
|
<span class="note-display">
|
||||||
<?= number_format($eval['note_obtenue'], 2) ?>/20
|
<?= number_format($note_affichee, 1) ?>/20
|
||||||
</span>
|
</span>
|
||||||
<span class="status-badge status-termine">✅ Terminé</span>
|
<span class="status-badge status-termine">✅ Terminé</span>
|
||||||
<a href="../voir_resultat.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
<a href="../voir_resultat.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
||||||
@ -684,19 +683,24 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
// Données pour le graphique
|
// Données pour le graphique
|
||||||
const toutesEvaluations = <?= json_encode($toutesEvals) ?>;
|
const toutesEvaluations = <?= json_encode($toutesEvals) ?>;
|
||||||
|
|
||||||
// Préparer les données
|
// Préparer les données avec notes arrondies au demi-point supérieur
|
||||||
const labels = toutesEvaluations.map((e, index) => {
|
const labels = toutesEvaluations.map((e, index) => {
|
||||||
const date = new Date(e.date_fin);
|
const date = new Date(e.date_fin);
|
||||||
return `Eval ${index + 1}\n${date.getDate()}/${date.getMonth() + 1}`;
|
return `Eval ${index + 1}\n${date.getDate()}/${date.getMonth() + 1}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const notes = toutesEvaluations.map(e => parseFloat(e.note));
|
// Arrondir toutes les notes au demi-point supérieur
|
||||||
|
const notes = toutesEvaluations.map(e => {
|
||||||
|
const note = parseFloat(e.note);
|
||||||
|
return Math.ceil(note * 2) / 2;
|
||||||
|
});
|
||||||
|
|
||||||
// Calculer la moyenne mobile (sur 3 évaluations)
|
// Calculer la moyenne mobile (sur 3 évaluations)
|
||||||
const moyennesMobiles = notes.map((note, index, arr) => {
|
const moyennesMobiles = notes.map((note, index, arr) => {
|
||||||
if (index < 2) return null;
|
if (index < 2) return null;
|
||||||
const sum = arr[index - 2] + arr[index - 1] + arr[index];
|
const sum = arr[index - 2] + arr[index - 1] + arr[index];
|
||||||
return sum / 3;
|
const avg = sum / 3;
|
||||||
|
return Math.ceil(avg * 2) / 2; // Arrondir aussi la moyenne mobile
|
||||||
});
|
});
|
||||||
|
|
||||||
// Créer le graphique
|
// Créer le graphique
|
||||||
@ -771,9 +775,9 @@ $stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
|||||||
const index = context.dataIndex;
|
const index = context.dataIndex;
|
||||||
const eval = toutesEvaluations[index];
|
const eval = toutesEvaluations[index];
|
||||||
if (context.datasetIndex === 0) {
|
if (context.datasetIndex === 0) {
|
||||||
return `Note: ${context.parsed.y.toFixed(2)}/20 (${eval.pourcentage}%)`;
|
return `Note: ${context.parsed.y.toFixed(1)}/20 (${Math.round(eval.pourcentage)}%)`;
|
||||||
} else {
|
} else {
|
||||||
return context.parsed.y ? `Moyenne mobile: ${context.parsed.y.toFixed(2)}/20` : '';
|
return context.parsed.y ? `Moyenne mobile: ${context.parsed.y.toFixed(1)}/20` : '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
afterLabel: function(context) {
|
afterLabel: function(context) {
|
||||||
|
|||||||
Reference in New Issue
Block a user