diff --git a/App/teacher.html b/App/teacher.html index 89266dc..a8355a4 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -492,16 +492,15 @@ var _liveDate = new Date().toISOString().slice(0,10); // YYYY-MM-DD, default h async function loadLive() { await _renderLiveTab(); if (_liveTimer) clearInterval(_liveTimer); - // Auto-Refresh: cockpit + aktuell alle 4s, übersicht/vergleich nur wenn heute - var refreshMs = (_liveMode === 'cockpit' || _liveMode === 'aktuell') ? 4000 + // Auto-Refresh: aktuell alle 4s, übersicht/vergleich nur wenn heute + var refreshMs = (_liveMode === 'aktuell') ? 4000 : (_liveDate === new Date().toISOString().slice(0,10)) ? 60000 : 0; if (refreshMs) _liveTimer = setInterval(_renderLiveTab, refreshMs); } async function _renderLiveTab() { - if (_liveMode === 'cockpit') return renderLiveCockpit(); if (_liveMode === 'uebersicht') return renderLiveSummary(); if (_liveMode === 'vergleich') return renderLiveCompare(); - return renderLive(); + return renderLive(); // 'aktuell' } window.setCompareSim = function(simId){ _liveCompareSim = simId; loadLive(); }; function setLiveMode(mode) { @@ -533,7 +532,6 @@ function _liveToggleHtml() { return '
' + '
' + ' ' - + ' ' + ' ' + ' ' + '
' @@ -1090,7 +1088,8 @@ async function _loadCockpitReflections() { var host = document.getElementById('cockpit-reflections-list'); if (!host) return; if (!items.length) { - host.innerHTML = '

Noch keine Reflexionen aus dieser Klasse. Sobald Lernende einen Durchgang abschließen und die Reflexionsfrage beantworten, erscheint die Antwort hier.

'; + _liveReflCache = '

Noch keine Reflexionen aus dieser Klasse. Sobald Lernende einen Durchgang abschließen und die Reflexionsfrage beantworten, erscheint die Antwort hier.

'; + host.innerHTML = _liveReflCache; return; } var simIcons = {}; @@ -1113,6 +1112,7 @@ async function _loadCockpitReflections() { if (data.total > items.length) { html += '

Zeige ' + items.length + ' von ' + data.total + ' Reflexionen.

'; } + _liveReflCache = html; host.innerHTML = html; } catch (e) { var host = document.getElementById('cockpit-reflections-list'); @@ -1120,6 +1120,23 @@ async function _loadCockpitReflections() { } } +// „Braucht Hilfe" live aus dem Sim-State (spiegelt die Heuristik in live.php) +function _liveNeedsHelp(simId, s) { + if (!s || typeof s !== 'object') return false; + switch (simId) { + case 'heli': return (s.planAttempts||0) >= 10; + case 'klima': case 'klima-3d': return (s.budget||0) < 0; + case 'weltkueche': return (s.mistakesInDish||0) >= 12; + case 'farmer': return (s.cash==null?1000:s.cash) < 0; + case 'logistik': return (s.balance==null?1000:s.balance) < 0; + case 'eu-werkstatt': return (s.attemptsThisStep||0) >= 6; + case 'tourismustal': return (s.money==null?1:s.money) < 0 || (s.lossStreak||0) >= 8; + case 'tourismusregion': return (s.budget==null?1:s.budget) < -400 || (s.env==null?100:s.env) < 30; + } + return false; +} +var _liveReflCache = '', _liveReflAt = 0; + async function renderLive() { var sessions = await api('live?class_id=' + currentClassId); if (sessions.error) { document.getElementById('tab-live').innerHTML = '

'+esc(sessions.error)+'

'; return; } @@ -1132,6 +1149,15 @@ async function renderLive() { return; } + // „Braucht Hilfe"-Banner (live) + var helpList = sessions.filter(function(ls){ return _liveNeedsHelp(ls.module_id, ls.state); }); + if (helpList.length) { + html += '
' + + '🆘 '+helpList.length+' brauchen evtl. Hilfe — ' + + helpList.map(function(ls){ return esc(ls.displayName); }).join(' · ') + + '
'; + } + // Nach Modul gruppieren var byModule = {}; sessions.forEach(function(ls) { @@ -1197,9 +1223,12 @@ async function renderLive() { var lastSeen = ls.last_seen_ms ? Math.max(0, Math.round((Date.now() - ls.last_seen_ms)/1000)) : 0; var dotColor = lastSeen < 8 ? '#5a8a5e' : lastSeen < 20 ? '#e8833a' : '#c07a6b'; var s = ls.state || {}; + var help = _liveNeedsHelp(ls.module_id, s); + var restBg = help ? '#fdf3ee' : ''; + var hoverBg = help ? '#f9e7e0' : '#f7f6f3'; - html += ''; - html += ''+avatarHtml+''+esc(ls.displayName)+''; + html += ''; + html += ''+(help?'🆘':'')+avatarHtml+''+esc(ls.displayName)+''; html += '
'+missionStr+'
'+simStr+' ges.
'; fields.forEach(function(f) { var align = f.align || 'right'; @@ -1212,7 +1241,20 @@ async function renderLive() { }); html += '
'; + + // Reflexionen (letzte Antworten der Klasse) — gecacht, damit der 4s-Refresh nicht flackert + html += '
' + + '
💭 Reflexionen — letzte Antworten der Klasse
' + + '

Was die Bearbeiter:innen am Ende eines Durchgangs als wichtigsten Eindruck festgehalten haben.

' + + '
' + (_liveReflCache || 'Lade …') + '
' + + '
'; + host.innerHTML = html; + + if (!_liveReflCache || Date.now() - _liveReflAt > 30000) { + _liveReflAt = Date.now(); + _loadCockpitReflections(); + } } // === LIVE-ÜBERSICHT (Tages-Balkenchart pro Schüler*in) ===