diff --git a/App/teacher.html b/App/teacher.html index 4e6497f..6ccbb35 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -729,16 +729,12 @@ var LIVE_PRIMARY_FIELDS = { var done = v||0; var pct = done/t; var c = pct>=1 ? '#5a8a5e' : pct>=.5 ? '#c9913a' : '#8a7a4a'; return ''+done+' / '+t+''; }}, - {k:'completed', label:'Gerichte', fmt:function(v, row){ - var s = row.state||{}; var t = s.completedTotal||0; - if (!t) return '—'; - var done = v||0; var pct = done/t; var c = pct>=1 ? '#5a8a5e' : pct>=.5 ? '#c9913a' : '#8a8a8a'; - return ''+done+' / '+t+''; - }}, {k:'mistakesInDish', label:'Fehlklicks', align:'center', fmt:function(v){ var n = v||0; var c = n>=12 ? '#c07a6b' : n>=5 ? '#c9913a' : '#5a8a5e'; return ''+n+''; }}, + {k:'__prog', label:'Fortschritt', align:'left', fmt:function(v, row){ return _liveProgressBar(row.module_id, row.state); }}, + {k:'__lage', label:'Lage', align:'center', fmt:function(v, row){ return _liveMoodBadge(row.module_id, row.state); }}, ], 'busfahrt': [ {k:'levelId', label:'Stufe', align:'center'}, @@ -1159,6 +1155,59 @@ function _liveNeedsHelp(simId, s) { } return false; } +// Allgemeiner „aktueller Erfolg": Fortschritt (% durch die Sim) + Lage (Ampel). +// Aus dem Live-State jeder Sim ableitbar → über alle Module vergleichbar. +function _liveProgressPct(simId, s) { + if (!s) return null; + var f = function(n, d) { return d > 0 ? Math.max(0, Math.min(100, Math.round((n||0)/d*100))) : null; }; + switch (simId) { + case 'weltkueche': return f(s.completed, s.completedTotal); + case 'sonnensystem': return s.taskTotal ? f(s.completed, s.taskTotal) : (s.progressPct!=null?s.progressPct:null); + case 'kofferdetektiv': return s.cases_total ? f(s.cases_solved, s.cases_total) : (s.progressPct!=null?s.progressPct:null); + case 'eu-werkstatt': return f(s.step, s.stepsTotal); + case 'energiemanager': return f(s.day, s.dayTotal); + case 'busfahrt': case 'fluggesellschaft': return f(s.orderIndex, s.totalOrders); + case 'heli': return f(s.planIndex, s.planTotal); + case 'tourismusregion': return f(s.wave, s.waveTotal); + case 'tourismustal': return f(s.goalsDone, s.goalsTotal); + case 'fluss': return s.progressPct!=null ? s.progressPct : null; + } + return s.progressPct!=null ? s.progressPct : null; +} +function _liveMood(simId, s) { + if (!s) return null; + if (s.health) return ({good:'good',ok:'good',warning:'mid',bad:'bad',critical:'bad'})[s.health] || 'mid'; + if (_liveNeedsHelp(simId, s)) return 'bad'; + switch (simId) { + case 'weltkueche': return (s.mistakesInDish||0) <= 2 ? 'good' : (s.mistakesInDish >= 8 ? 'bad' : 'mid'); + case 'klima': case 'klima-3d': return ((s.floodedPct==null?100:s.floodedPct) < 20 && (s.budget||0) >= 0) ? 'good' : 'mid'; + case 'busfahrt': case 'fluggesellschaft': return (s.budget==null?0:s.budget) >= 5000 ? 'good' : (s.budget < 0 ? 'bad' : 'mid'); + case 'tourismustal': return (s.money==null?0:s.money) >= 4000 ? 'good' : (s.money < 0 ? 'bad' : 'mid'); + case 'heli': return (s.totalStars||0) >= 4 ? 'good' : 'mid'; + case 'fluss': case 'kofferdetektiv': case 'sonnensystem': + return s.score!=null ? (s.score>=70?'good':s.score>=40?'mid':'bad') : 'mid'; + } + return 'mid'; +} +function _liveProgressBar(simId, s) { + var p = _liveProgressPct(simId, s); + if (p == null) return ''; + var c = p >= 75 ? '#5a8a5e' : p >= 40 ? '#c9913a' : '#c07a6b'; + return '' + + '' + + '' + + ''+p+'%'; +} +function _liveMoodBadge(simId, s) { + var m = _liveMood(simId, s); + if (!m) return ''; + var map = { good:['#5a8a5e','Gut'], mid:['#c9913a','OK'], bad:['#c07a6b','Kritisch'] }; + var x = map[m] || map.mid; + return '' + + '' + + ''+x[1]+''; +} + var _liveReflCache = '', _liveReflAt = 0; // Aktiv = Lebenszeichen in den letzten 90 s. Ältere Sessions bleiben sichtbar, // aber als „pausiert" (Lernende:r macht Pause, kann später weitermachen).