Uebersicht: Top Performers heute + neue Abzeichen heute; Wochengrafik-Labels; Spielzeit sortierbar
- results.php view=today: heutige finale Laeufe (topToday) + vorher/nachher-Progress je Schueler:in x Sim (aus student_results rekonstruiert) fuer Badge-Erkennung - teacher.html: Sektion "Top Performers heute" (heutige Wertung, Sterne + Erfolg) ersetzt Allzeit-Top; darunter "Neue Abzeichen heute" (badges.js, jetzt erfuellt aber vor heute nicht) - Wochen-Saeulengrafik: Sim-Titel klein in die Balkenabschnitte, hoehere Grafik - Modul-Tabelle: Spielzeit-Spalte sortierbar (Quoten-Spalten schon sortierbar) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -246,6 +246,72 @@ if ($view === 'matrix') {
|
||||
]);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// VIEW: TODAY → Top-Leistungen von HEUTE + heute neu vergebene Abzeichen
|
||||
// =============================================================================
|
||||
// Liefert die heutigen finalen Läufe (topToday) sowie pro Schüler:in×Sim, die
|
||||
// heute aktiv war, den Progress-Stand VOR heute und JETZT (aus student_results
|
||||
// rekonstruiert). Die Badge-Auswertung passiert clientseitig mit badges.js,
|
||||
// damit die Abzeichen-Definition eine einzige Quelle bleibt.
|
||||
if ($view === 'today') {
|
||||
$rows = $db->fetchAll(
|
||||
"SELECT sr.student_id, sr.module_id, sr.score, sr.detail_json, sr.completed_at,
|
||||
s.display_name, s.username, s.emoji_avatar
|
||||
FROM student_results sr
|
||||
JOIN students s ON s.id = sr.student_id
|
||||
WHERE sr.class_id = ? AND s.deleted_at IS NULL
|
||||
ORDER BY sr.completed_at",
|
||||
[$classId]
|
||||
);
|
||||
$starsOf = function ($score, $dj) {
|
||||
$d = json_decode($dj, true);
|
||||
if (is_array($d)) {
|
||||
if (isset($d['stars'])) return (int)$d['stars'];
|
||||
if (isset($d['sterneGesamt'])) return (int)$d['sterneGesamt'];
|
||||
}
|
||||
return (int)round(((float)$score) / 20);
|
||||
};
|
||||
$levelFromXp = function ($xp) { return $xp < 50 ? 1 : ($xp < 150 ? 2 : ($xp < 300 ? 3 : 4)); };
|
||||
$today = date('Y-m-d');
|
||||
|
||||
$agg = []; // "sid|sim" => Aggregat vorher/jetzt
|
||||
$todayRuns = [];
|
||||
foreach ($rows as $r) {
|
||||
$sid = (int)$r['student_id'];
|
||||
$sim = $r['module_id'];
|
||||
$st = $starsOf($r['score'], $r['detail_json']);
|
||||
$xp = $st * 10 + ($st >= 5 ? 5 : 0);
|
||||
$isToday = substr($r['completed_at'], 0, 10) === $today;
|
||||
$k = "$sid|$sim";
|
||||
if (!isset($agg[$k])) $agg[$k] = [
|
||||
'sid'=>$sid, 'sim'=>$sim, 'name'=>$r['display_name'] ?: $r['username'], 'emoji'=>$r['emoji_avatar'],
|
||||
'pB'=>0,'bB'=>0,'xB'=>0, 'pN'=>0,'bN'=>0,'xN'=>0, 'today'=>false,
|
||||
];
|
||||
$agg[$k]['pN']++; $agg[$k]['bN'] = max($agg[$k]['bN'], $st); $agg[$k]['xN'] += $xp;
|
||||
if ($isToday) {
|
||||
$agg[$k]['today'] = true;
|
||||
$todayRuns[] = ['studentId'=>$sid, 'displayName'=>$r['display_name'] ?: $r['username'],
|
||||
'emoji'=>$r['emoji_avatar'] ?: '🧑🎓', 'moduleId'=>$sim,
|
||||
'score'=>round((float)$r['score']), 'stars'=>$st, 'at'=>$r['completed_at']];
|
||||
} else {
|
||||
$agg[$k]['pB']++; $agg[$k]['bB'] = max($agg[$k]['bB'], $st); $agg[$k]['xB'] += $xp;
|
||||
}
|
||||
}
|
||||
usort($todayRuns, function ($a, $b) { return $b['score'] <=> $a['score']; });
|
||||
|
||||
$progress = [];
|
||||
foreach ($agg as $a) {
|
||||
if (!$a['today']) continue;
|
||||
$progress[] = [
|
||||
'studentId'=>$a['sid'], 'displayName'=>$a['name'], 'emoji'=>$a['emoji'] ?: '🧑🎓', 'simId'=>$a['sim'],
|
||||
'before'=>['plays'=>$a['pB'], 'best_stars'=>$a['bB'], 'level'=>$levelFromXp($a['xB'])],
|
||||
'now' =>['plays'=>$a['pN'], 'best_stars'=>$a['bN'], 'level'=>$levelFromXp($a['xN'])],
|
||||
];
|
||||
}
|
||||
|
||||
Response::ok(['date'=>$today, 'topToday'=>array_slice($todayRuns, 0, 6), 'progress'=>$progress]);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// VIEW: FLEISS (Lernzeit pro Schüler*in, optional Modul-Filter)
|
||||
// =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user