Klassenaufgabe: Modal mit Frist-Schnellwahl + Live-Bestaetigung; Start/Tempo auf aktiver Card
- Modal "Aufgabe erteilen": Frist-Buttons (Heute/Morgen/+1 Woche/Kein Limit), Default +1 Woche, Tempo-Checkbox "Vorbereiten", Live-Zusammenfassung als Bestaetigung, Button "Auftrag erteilen" - Aktive Klassen-Aufgabe-Card: Sim-Bild + Status (Vorbereitet/Laeuft) + Steuerung "Start freigeben" / "Pause" / "Beenden" direkt auf der Card (Tempo-Start nicht mehr in der individuellen Freigabe) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+74
-26
@@ -373,26 +373,33 @@ schueler01,Max M.,,,,,</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: Klassen-Simulation starten -->
|
||||
<!-- Modal: Klassen-Aufgabe erteilen -->
|
||||
<div class="modal hidden" id="modal-startsim">
|
||||
<div class="modal-card">
|
||||
<h3>🚀 Klassen-Simulation starten</h3>
|
||||
<p style="font-size:.7rem;color:#8a8a8a;margin-bottom:.5rem">Wählen Sie ein Modul und Level. Die Aufgabe erscheint bei allen Schüler*innen an oberster Stelle.</p>
|
||||
<h3>🚀 Klassen-Aufgabe erteilen</h3>
|
||||
<p style="font-size:.7rem;color:#8a8a8a;margin-bottom:.5rem">Modul und Stufe wählen, Frist setzen. Die Aufgabe erscheint bei allen Schüler*innen ganz oben.</p>
|
||||
<label>Modul</label>
|
||||
<select id="ss-module" style="width:100%;padding:.4rem .6rem;border:1.5px solid rgba(0,0,0,.1);border-radius:6px;font-size:.78rem;font-family:inherit"></select>
|
||||
<label>Level</label>
|
||||
<select id="ss-level" style="width:100%;padding:.4rem .6rem;border:1.5px solid rgba(0,0,0,.1);border-radius:6px;font-size:.78rem;font-family:inherit">
|
||||
<option value="1">Level 1 — Einsteiger</option>
|
||||
<option value="2">Level 2 — Fortgeschritten</option>
|
||||
<option value="3">Level 3 — Profi</option>
|
||||
<select id="ss-module" onchange="ssUpdateSummary()" style="width:100%;padding:.4rem .6rem;border:1.5px solid rgba(0,0,0,.1);border-radius:6px;font-size:.78rem;font-family:inherit"></select>
|
||||
<label>Stufe</label>
|
||||
<select id="ss-level" onchange="ssUpdateSummary()" style="width:100%;padding:.4rem .6rem;border:1.5px solid rgba(0,0,0,.1);border-radius:6px;font-size:.78rem;font-family:inherit">
|
||||
<option value="1">Stufe 1 — Einsteiger</option>
|
||||
<option value="2">Stufe 2 — Fortgeschritten</option>
|
||||
<option value="3">Stufe 3 — Profi</option>
|
||||
</select>
|
||||
<label>Endet am (optional, leer = ohne Zeitlimit)</label>
|
||||
<input type="datetime-local" id="ss-ends">
|
||||
<label style="display:flex;align-items:center;gap:.4rem;margin-top:.5rem;cursor:pointer">
|
||||
<input type="checkbox" id="ss-paused"> <span style="font-size:.74rem">⏸ Tempo-Sperre — Schüler*in startet pausiert, bis Lehrperson freigibt</span>
|
||||
<label>Fällig bis</label>
|
||||
<div style="display:flex;gap:.3rem;flex-wrap:wrap;margin-bottom:.35rem">
|
||||
<button type="button" class="btn btn-outline" style="font-size:.66rem;padding:.25rem .55rem" onclick="ssSetDue('heute')">Heute 13:00</button>
|
||||
<button type="button" class="btn btn-outline" style="font-size:.66rem;padding:.25rem .55rem" onclick="ssSetDue('morgen')">Morgen</button>
|
||||
<button type="button" class="btn btn-outline" style="font-size:.66rem;padding:.25rem .55rem" onclick="ssSetDue('woche')">+1 Woche</button>
|
||||
<button type="button" class="btn btn-outline" style="font-size:.66rem;padding:.25rem .55rem" onclick="ssSetDue('')">Kein Limit</button>
|
||||
</div>
|
||||
<input type="datetime-local" id="ss-ends" onchange="ssUpdateSummary()">
|
||||
<label style="display:flex;align-items:flex-start;gap:.4rem;margin-top:.6rem;cursor:pointer">
|
||||
<input type="checkbox" id="ss-paused" onchange="ssUpdateSummary()" style="margin-top:.15rem"> <span style="font-size:.74rem">⏸ Vorbereiten — die Klasse startet erst, wenn du auf der Aufgaben-Card „▶ Start freigeben" drückst (gemeinsamer Start)</span>
|
||||
</label>
|
||||
<div style="display:flex;gap:.4rem;margin-top:.8rem">
|
||||
<button class="btn" onclick="startSimulation()">🚀 Starten</button>
|
||||
<div id="ss-summary" style="margin-top:.7rem;padding:.5rem .7rem;background:#f5f3eb;border:1px solid rgba(0,0,0,.06);border-radius:8px;font-size:.72rem;color:#3a3a3a"></div>
|
||||
<div style="display:flex;gap:.4rem;margin-top:.7rem">
|
||||
<button class="btn" onclick="startSimulation()">✓ Auftrag erteilen</button>
|
||||
<button class="btn btn-outline" onclick="hideModal('modal-startsim')">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2878,23 +2885,41 @@ async function loadModuleMatrix() {
|
||||
// Aktive Aufgaben anzeigen
|
||||
var html = '';
|
||||
if (activeAssign.length > 0) {
|
||||
html += '<div class="card" style="border-color:#e8833a;border-width:2px"><div class="card-h" style="color:#e8833a">Aktive Klassen-Simulation</div>';
|
||||
html += '<div class="card" style="border-color:#e8833a;border-width:2px"><div class="card-h" style="color:#e8833a">📋 Aktive Klassen-Aufgabe</div>';
|
||||
var anyPrepared = false;
|
||||
activeAssign.forEach(function(a) {
|
||||
var mod = mods.find(function(m){return m.id===a.module_id;});
|
||||
var name = mod ? mod.icon + ' ' + mod.name : a.module_id;
|
||||
var end = a.ends_at ? ' · bis ' + new Date(a.ends_at).toLocaleDateString('de-AT',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : ' · ohne Zeitlimit';
|
||||
html += '<div style="display:flex;align-items:center;gap:.6rem;padding:.3rem 0">';
|
||||
html += '<span style="font-size:1.2rem">' + (mod?.icon||'📋') + '</span>';
|
||||
html += '<div style="flex:1"><strong style="font-size:.78rem">' + esc(mod?.name||a.module_id) + '</strong>';
|
||||
html += '<span style="font-size:.65rem;color:#8a8a8a"> · Level ' + a.level + end + '</span></div>';
|
||||
html += '<button class="btn" style="background:#c07a6b;font-size:.6rem;padding:.2rem .5rem" onclick="stopAssignment('+a.id+')">Beenden</button>';
|
||||
html += '</div>';
|
||||
var paused = mod ? !!mod.paused : false;
|
||||
if (paused) anyPrepared = true;
|
||||
var img = (mod && mod.card_image) ? 'assets/img/'+mod.card_image : null;
|
||||
var thumb = img
|
||||
? '<img src="'+img+'" alt="" style="width:50px;height:50px;border-radius:9px;object-fit:cover;flex:none">'
|
||||
: '<span style="font-size:1.6rem;width:50px;text-align:center">'+(mod?mod.icon:'📋')+'</span>';
|
||||
var end = a.ends_at ? 'fällig ' + new Date(a.ends_at).toLocaleDateString('de-AT',{weekday:'short',day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : 'ohne Zeitlimit';
|
||||
var stateBadge = paused
|
||||
? '<span style="background:#fdf1e6;color:#c25e1e;border:1px solid #e8c3a0;padding:.08rem .5rem;border-radius:99px;font-size:.62rem;font-weight:700">⏸ Vorbereitet</span>'
|
||||
: '<span style="background:#e5f2e7;color:#2a7a3a;border:1px solid #b9dcc0;padding:.08rem .5rem;border-radius:99px;font-size:.62rem;font-weight:700">▶ Läuft</span>';
|
||||
html += '<div style="display:flex;align-items:center;gap:.7rem;padding:.5rem 0;border-bottom:1px solid rgba(0,0,0,.05)">';
|
||||
html += thumb;
|
||||
html += '<div style="flex:1;min-width:0"><div style="font-size:.86rem;font-weight:800;color:#3a3a3a">'+esc(mod?mod.name:a.module_id)+' <span style="font-weight:500;color:#8a8a8a;font-size:.72rem">· Stufe '+a.level+'</span></div>';
|
||||
html += '<div style="font-size:.66rem;color:#8a8a8a;margin-top:.2rem">'+stateBadge+' <span style="margin-left:.35rem">'+end+'</span></div></div>';
|
||||
html += '<div style="display:flex;gap:.4rem;align-items:center;flex:none">';
|
||||
if (paused) {
|
||||
html += '<button class="btn" style="background:#3a6a3e;font-size:.74rem;padding:.42rem .85rem;font-weight:700" onclick="toggleAssignmentPause(\''+a.module_id+'\',true)" title="Die Klasse darf jetzt loslegen">▶ Start freigeben</button>';
|
||||
} else {
|
||||
html += '<button class="btn" style="background:#c9913a;font-size:.66rem;padding:.35rem .6rem" onclick="toggleAssignmentPause(\''+a.module_id+'\',false)" title="Pausieren — die Klasse wartet">⏸ Pause</button>';
|
||||
}
|
||||
html += '<button class="btn" style="background:#c07a6b;font-size:.66rem;padding:.35rem .6rem" onclick="stopAssignment('+a.id+')">■ Beenden</button>';
|
||||
html += '</div></div>';
|
||||
});
|
||||
if (anyPrepared) {
|
||||
html += '<p style="font-size:.66rem;color:#8a8a8a;margin-top:.55rem;line-height:1.45">⏸ <b>Vorbereitet:</b> Die Klasse sieht den Auftrag bereits, kann aber erst loslegen, wenn du <b>„▶ Start freigeben"</b> drückst — so starten alle gemeinsam.</p>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// Start-Button
|
||||
html += '<div style="margin-bottom:.6rem"><button class="btn" onclick="showStartSim()" style="font-size:.75rem">🚀 Klassen-Simulation starten</button></div>';
|
||||
html += '<div style="margin-bottom:.6rem"><button class="btn" onclick="showStartSim()" style="font-size:.75rem">🚀 Klassen-Aufgabe erteilen</button></div>';
|
||||
|
||||
// Vorbereitung: spielbare vs. geplante Module trennen (vor Matrix nutzen)
|
||||
var modsActive = mods.filter(function(m){ return m.status !== 'geplant' && m.status !== 'archiv'; });
|
||||
@@ -3021,11 +3046,34 @@ async function showStartSim(preselectedModuleId) {
|
||||
sel.innerHTML = '';
|
||||
ALL_MODS.forEach(function(m) { var o=document.createElement('option'); o.value=m.id; o.textContent=(m.icon||'')+' '+m.name; sel.appendChild(o); });
|
||||
if (preselectedModuleId) sel.value = preselectedModuleId;
|
||||
document.getElementById('ss-ends').value = '';
|
||||
document.getElementById('ss-paused').checked = false;
|
||||
document.getElementById('ss-level').value = '1';
|
||||
ssSetDue('woche'); // Default-Frist: +1 Woche (Hausübung); setzt Feld + Bestätigung
|
||||
showModal('modal-startsim');
|
||||
}
|
||||
function _ssPad(n){ return String(n).padStart(2,'0'); }
|
||||
function _ssDtLocal(d){ return d.getFullYear()+'-'+_ssPad(d.getMonth()+1)+'-'+_ssPad(d.getDate())+'T'+_ssPad(d.getHours())+':'+_ssPad(d.getMinutes()); }
|
||||
function ssSetDue(kind){
|
||||
var el = document.getElementById('ss-ends');
|
||||
if (kind === '') { el.value = ''; ssUpdateSummary(); return; }
|
||||
var d = new Date();
|
||||
if (kind === 'morgen') d.setDate(d.getDate()+1);
|
||||
else if (kind === 'woche') d.setDate(d.getDate()+7);
|
||||
d.setHours(13, 0, 0, 0);
|
||||
el.value = _ssDtLocal(d);
|
||||
ssUpdateSummary();
|
||||
}
|
||||
function ssUpdateSummary(){
|
||||
var el = document.getElementById('ss-summary'); if (!el) return;
|
||||
var modSel = document.getElementById('ss-module');
|
||||
var modTxt = (modSel && modSel.options[modSel.selectedIndex]) ? modSel.options[modSel.selectedIndex].text : '—';
|
||||
var lvl = document.getElementById('ss-level').value;
|
||||
var ends = document.getElementById('ss-ends').value;
|
||||
var paused = document.getElementById('ss-paused').checked;
|
||||
var endTxt = ends ? new Date(ends).toLocaleDateString('de-AT',{weekday:'short',day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : 'ohne Zeitlimit';
|
||||
var startTxt = paused ? '⏸ startet auf dein Signal' : '▶ startet sofort';
|
||||
el.innerHTML = '<b>'+esc(modTxt)+'</b> · Stufe '+lvl+' · fällig <b>'+esc(endTxt)+'</b> · '+startTxt;
|
||||
}
|
||||
async function startSimulation() {
|
||||
var moduleId = document.getElementById('ss-module').value;
|
||||
var level = parseInt(document.getElementById('ss-level').value);
|
||||
|
||||
Reference in New Issue
Block a user