diff --git a/App/teacher.html b/App/teacher.html index 6ccbb35..9f9354f 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -1464,10 +1464,21 @@ function _compareGroupLabel(g) { async function renderLiveCompare() { var host = document.getElementById('tab-live'); if (!host) return; - var sessions = await api('live?class_id=' + currentClassId); + var res = await Promise.all([ + api('live?class_id=' + currentClassId), + api('assignments?class_id=' + currentClassId), + api('results?class_id=' + currentClassId + '&view=matrix'), + ]); + var sessions = res[0], assignments = res[1], matrix = res[2]; if (sessions.error) { host.innerHTML = _liveToggleHtml() + '

'+esc(sessions.error)+'

'; return; } + if (!Array.isArray(assignments)) assignments = []; + if (!matrix || matrix.error) matrix = { students:[], modules:[], cells:{} }; - // Sim-Filter-Chips: alle aktiven Sims zählen, gruppiert + // Aktive Klassenaufgabe (erste aktive) → Fokus-Modul für den Vergleich + var activeAssign = assignments.filter(function(a){ return a.active; })[0] || null; + var assignGroup = activeAssign ? _compareSimGroup(activeAssign.module_id) : null; + + // Online-Sessions nach Sim gruppieren var byGroup = {}; (sessions || []).forEach(function(ls){ var g = _compareSimGroup(ls.module_id); @@ -1477,38 +1488,75 @@ async function renderLiveCompare() { }); var groups = Object.keys(byGroup).sort(function(a,b){ return byGroup[b].count - byGroup[a].count; }); - if (!groups.length) { + // Chips = Online-Gruppen, Aufgabe immer vorne (auch wenn noch niemand aktiv) + var chipGroups = groups.slice(); + if (assignGroup) chipGroups = [assignGroup].concat(chipGroups.filter(function(g){ return g !== assignGroup; })); + + if (!chipGroups.length) { host.innerHTML = _liveToggleHtml() + '
Vergleich
' - + '

Gerade niemand online — sobald Schüler*innen eine Simulation öffnen, kannst du hier vergleichen.

' + + '

Gerade niemand online und keine aktive Klassenaufgabe — sobald Schüler*innen eine Simulation öffnen (oder du eine Aufgabe freigibst), kannst du hier vergleichen.

' + '
'; return; } - // Aktive Sim wählen — User-Wahl, sonst die mit den meisten Schüler*innen - var sim = _liveCompareSim && byGroup[_liveCompareSim] ? _liveCompareSim : groups[0]; + // Sim wählen: explizite User-Wahl > aktive Aufgabe > meiste Online + var sim; + if (_liveCompareSim && chipGroups.indexOf(_liveCompareSim) >= 0) sim = _liveCompareSim; + else if (assignGroup) sim = assignGroup; + else sim = groups[0]; _liveCompareSim = sim; - // Header mit Toggle + Sim-Filter-Chips var html = _liveToggleHtml(); + + // Aufgaben-Banner, wenn eine Klassenaufgabe aktiv ist + if (activeAssign) { + var modId = activeAssign.module_id; + var N = (matrix.students || []).length; + var begun = 0; + (matrix.students || []).forEach(function(s){ + var c = (matrix.cells && matrix.cells[s.id]) ? matrix.cells[s.id][modId] : null; + if (c && c.plays > 0) begun++; + }); + var onlineNow = byGroup[assignGroup] ? byGroup[assignGroup].sessions : []; + var progVals = onlineNow.map(function(ls){ return _liveProgressPct(ls.module_id, ls.state); }).filter(function(v){ return v != null; }); + var avgProg = progVals.length ? Math.round(progVals.reduce(function(a,b){return a+b;},0)/progVals.length) : null; + var due = activeAssign.ends_at ? ' · bis ' + new Date(activeAssign.ends_at).toLocaleDateString('de-AT',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : ''; + html += '
' + + '
📋 Aufgabe: '+esc(_compareGroupLabel(assignGroup))+' · Level '+esc(activeAssign.level)+due+'
' + + '
' + + 'begonnen '+begun+' / '+N+'' + + 'gerade aktiv '+onlineNow.length+'' + + 'Ø Fortschritt '+(avgProg!=null?avgProg+' %':'–')+'' + + '
'; + } + + // Sim-Filter-Chips html += '
'; - groups.forEach(function(g){ + chipGroups.forEach(function(g){ var active = g === sim; + var isAssign = (g === assignGroup); var bg = active ? '#1f4b37' : '#fff'; var col = active ? '#fff' : '#3d5165'; - var border = active ? '#1f4b37' : 'rgba(0,0,0,.12)'; + var border = active ? '#1f4b37' : (isAssign ? '#3a6a3e' : 'rgba(0,0,0,.12)'); + var cnt = byGroup[g] ? byGroup[g].count : 0; html += ''; }); html += '
'; - // Sim-spezifisch rendern - if (sim === 'klima') { - html += _renderKlimaCompareBody(byGroup.klima.sessions); + // Körper + var simSessions = byGroup[sim] ? byGroup[sim].sessions : []; + if (!simSessions.length) { + html += '
'+esc(_compareGroupLabel(sim))+' · Vergleich
' + + '

Noch niemand arbeitet gerade an dieser Simulation. Sobald Kinder starten, erscheinen sie hier im Vergleich.

'; + } else if (sim === 'klima') { + html += _renderKlimaCompareBody(simSessions); } else { - html += _renderGenericCompareBody(byGroup[sim].sessions, sim); + html += _renderGenericCompareBody(simSessions, sim); } host.innerHTML = html; }