Aufgabe: Freigabe/Tempo entfernt (sofort startbar); Beenden als Dialog
- keine Vorbereiten/paused/Start-freigeben/Pause mehr — Aufgabe ist ab Vergabe sofort startbar (paused:false), Card zeigt nur "Laeuft" + Beenden - Schueler-Card immer "Jetzt starten" (kein Warte-Zustand) - "Aufgabe beenden" jetzt ordentlicher Dialog (#modal-stopassign) statt confirm() Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+1
-5
@@ -247,11 +247,7 @@ async function renderModules() {
|
||||
s += '<h3 style="color:#c25e1e">'+(m.icon||'📚')+' '+m.name+(m.forcedLevel ? ' <span style="font-weight:600;color:#9a9a9a;font-size:.82rem">· Stufe '+m.forcedLevel+'</span>' : '')+'</h3>';
|
||||
s += '<p>Auftrag von deiner Lehrperson'+(meta.length ? '<br><span style="color:#8a8a8a">'+meta.join(' · ')+'</span>' : '')+'</p>';
|
||||
s += '<div class="mod-actions">';
|
||||
if (m.paused) {
|
||||
s += '<span class="mod-btn" style="flex:1;justify-content:center;background:#fdf1e6;color:#c25e1e;border-color:#e8c3a0;cursor:default" title="Deine Lehrperson gibt den Start noch frei">⏳ Wartet auf Freigabe</span>';
|
||||
} else {
|
||||
s += '<a href="'+url+'" class="mod-btn primary" style="background:#e8833a;border-color:#e8833a">▶ Jetzt starten</a>';
|
||||
}
|
||||
s += '<a href="'+url+'" class="mod-btn primary" style="background:#e8833a;border-color:#e8833a">▶ Jetzt starten</a>';
|
||||
s += '</div></div></div>';
|
||||
return s;
|
||||
}
|
||||
|
||||
+33
-37
@@ -406,9 +406,6 @@ schueler01,Max M.,,,,,</pre>
|
||||
<input type="date" id="ss-end-date" onchange="ssUpdateSummary()" style="padding:.35rem .5rem;border:1.5px solid rgba(0,0,0,.12);border-radius:6px;font-size:.78rem;font-family:inherit">
|
||||
<input type="time" id="ss-end-time" value="13:00" onchange="ssUpdateSummary()" style="padding:.35rem .5rem;border:1.5px solid rgba(0,0,0,.12);border-radius:6px;font-size:.78rem;font-family:inherit">
|
||||
</div>
|
||||
<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 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>
|
||||
@@ -417,6 +414,19 @@ schueler01,Max M.,,,,,</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: Aufgabe beenden -->
|
||||
<div class="modal hidden" id="modal-stopassign">
|
||||
<div class="modal-card">
|
||||
<h3>■ Aufgabe beenden</h3>
|
||||
<p style="font-size:.82rem;color:#3a3a3a;line-height:1.5">Möchtest du die Aufgabe <b id="stopassign-name">…</b> wirklich beenden?</p>
|
||||
<p style="font-size:.72rem;color:#8a8a8a;line-height:1.5;margin-top:.4rem">Die Schüler:innen sehen sie danach nicht mehr als Auftrag. Bereits erledigte Durchgänge und Ergebnisse bleiben erhalten — das Modul bleibt zum freien Üben verfügbar (sofern freigegeben).</p>
|
||||
<div style="display:flex;gap:.4rem;margin-top:1rem">
|
||||
<button class="btn" style="background:#c07a6b" onclick="doStopAssignment()">■ Aufgabe beenden</button>
|
||||
<button class="btn btn-outline" onclick="hideModal('modal-stopassign')">Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: Lizenzen einlösen -->
|
||||
<div class="modal hidden" id="modal-license">
|
||||
<div class="modal-card">
|
||||
@@ -2898,11 +2908,8 @@ async function loadModuleMatrix() {
|
||||
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-Aufgabe</div>';
|
||||
var anyPrepared = false;
|
||||
activeAssign.forEach(function(a) {
|
||||
var mod = mods.find(function(m){return m.id===a.module_id;});
|
||||
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">'
|
||||
@@ -2910,25 +2917,14 @@ async function loadModuleMatrix() {
|
||||
var end = a.ends_at ? 'fällig ' + new Date(a.ends_at.replace(' ','T')).toLocaleDateString('de-AT',{weekday:'short',day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) : 'ohne Zeitlimit';
|
||||
var startMs = a.starts_at ? new Date(a.starts_at.replace(' ','T')).getTime() : 0;
|
||||
if (startMs && startMs > Date.now()) end = 'ab ' + new Date(startMs).toLocaleDateString('de-AT',{weekday:'short',day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) + ' · ' + end;
|
||||
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>';
|
||||
var modName = mod ? mod.name : a.module_id;
|
||||
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>';
|
||||
html += '<div style="flex:1;min-width:0"><div style="font-size:.86rem;font-weight:800;color:#3a3a3a">'+esc(modName)+' <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"><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> <span style="margin-left:.35rem">'+end+'</span></div></div>';
|
||||
html += '<button class="btn" style="background:#c07a6b;font-size:.66rem;padding:.4rem .7rem;flex:none" onclick="stopAssignment('+a.id+',\''+esc(modName).replace(/\x27/g,"\\x27")+'\')">■ Beenden</button>';
|
||||
html += '</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>';
|
||||
}
|
||||
|
||||
@@ -3062,7 +3058,6 @@ 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-paused').checked = false;
|
||||
document.getElementById('ss-level').value = '1';
|
||||
var now = new Date();
|
||||
document.getElementById('ss-start-date').value = _ssDate(now);
|
||||
@@ -3109,34 +3104,35 @@ function ssUpdateSummary(){
|
||||
var lvl = document.getElementById('ss-level').value;
|
||||
var startsAt = ssStartValue();
|
||||
var endsAt = ssEndValue();
|
||||
var paused = document.getElementById('ss-paused').checked;
|
||||
var future = startsAt && new Date(startsAt) > new Date();
|
||||
var startTxt = startsAt ? ('ab <b>'+esc(_ssFmt(startsAt))+'</b>') : (paused ? '⏸ auf dein Signal' : '▶ sofort');
|
||||
var startTxt = startsAt ? ('ab <b>'+esc(_ssFmt(startsAt))+'</b>') : '▶ sofort';
|
||||
var endTxt = endsAt ? ('fällig <b>'+esc(_ssFmt(endsAt))+'</b>') : 'ohne Frist';
|
||||
var note = (paused || future) ? ' <span style="color:#c25e1e">· Klasse wartet auf „Start freigeben"</span>' : '';
|
||||
el.innerHTML = '<b>'+esc(modTxt)+'</b> · Stufe '+lvl+' · '+startTxt+' · '+endTxt+note;
|
||||
el.innerHTML = '<b>'+esc(modTxt)+'</b> · Stufe '+lvl+' · '+startTxt+' · '+endTxt;
|
||||
}
|
||||
async function startSimulation() {
|
||||
var moduleId = document.getElementById('ss-module').value;
|
||||
var level = parseInt(document.getElementById('ss-level').value);
|
||||
var startsAt = ssStartValue();
|
||||
var endsAt = ssEndValue();
|
||||
var future = startsAt && new Date(startsAt) > new Date();
|
||||
// Zukünftiger Start ⇒ automatisch „vorbereitet" (Klasse wartet), sonst Checkbox.
|
||||
var paused = document.getElementById('ss-paused').checked || !!future;
|
||||
|
||||
// Sowohl class_modules (Modus + Level + Pause) als auch class_assignments
|
||||
// (Auftragshistorie inkl. Zeitfenster) setzen.
|
||||
var rm = await api('modules', {action:'set_mode', classId:currentClassId, moduleId:moduleId, mode:'teacher_started', currentLevel:level, dueDate:endsAt, paused:paused});
|
||||
// Aufgabe ist ab Vergabe sofort startbar (keine Tempo-/Freigabe-Sperre mehr).
|
||||
var rm = await api('modules', {action:'set_mode', classId:currentClassId, moduleId:moduleId, mode:'teacher_started', currentLevel:level, dueDate:endsAt, paused:false});
|
||||
if (rm && rm.error) { alert(rm.error); return; }
|
||||
var r = await api('assignments', {action:'create', classId:currentClassId, moduleId:moduleId, level:level, startsAt:startsAt, endsAt:endsAt});
|
||||
if (r.error) { alert(r.error); return; }
|
||||
hideModal('modal-startsim');
|
||||
loadModuleMatrix();
|
||||
}
|
||||
async function stopAssignment(id) {
|
||||
if (!confirm('Simulation beenden?')) return;
|
||||
await api('assignments', {action:'stop', assignmentId:id});
|
||||
var _stopAssignId = null;
|
||||
function stopAssignment(id, name) {
|
||||
_stopAssignId = id;
|
||||
document.getElementById('stopassign-name').textContent = name || 'diese Aufgabe';
|
||||
showModal('modal-stopassign');
|
||||
}
|
||||
async function doStopAssignment() {
|
||||
if (!_stopAssignId) return;
|
||||
await api('assignments', {action:'stop', assignmentId:_stopAssignId});
|
||||
_stopAssignId = null;
|
||||
hideModal('modal-stopassign');
|
||||
loadModuleMatrix();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user