v7
This commit is contained in:
parent
02dd93db80
commit
6d09b07dec
1 changed files with 91 additions and 55 deletions
|
|
@ -144,6 +144,13 @@
|
|||
details.det>summary::before{content:"▸ ";color:var(--muted)}
|
||||
details.det[open]>summary::before{content:"▾ "}
|
||||
details.det>div,details.det>p,details.det>ul{margin-top:10px}
|
||||
/* Schrittweise Aktivitaet: Aufloesung */
|
||||
.aufBox{background:#f1faf4;border:1px solid #cde6d6;border-left:3px solid var(--ok);border-radius:10px;padding:14px 16px;margin:14px 0 4px}
|
||||
.aufBox .aufH{margin:0 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted)}
|
||||
.aufBox ul{margin:6px 0 0;padding-left:20px}
|
||||
.aufBox ul li{margin:3px 0}
|
||||
.roleChips{display:flex;flex-wrap:wrap;gap:6px}
|
||||
.roleChip{background:#eef0f3;border-radius:999px;padding:3px 11px;font-size:13px}
|
||||
|
||||
.actions { display:flex; gap:10px; align-items:center; margin-top:24px; flex-wrap:wrap; }
|
||||
.actions .spacer { flex:1; }
|
||||
|
|
@ -196,6 +203,7 @@
|
|||
.classifyTop{display:grid;grid-template-columns:minmax(220px,320px) 1fr;gap:26px;align-items:start;margin:18px 0 6px}
|
||||
.classifyCard{display:block;width:100%;border-radius:12px;box-shadow:0 3px 16px rgba(0,0,0,.16)}
|
||||
.classifyMain{min-width:0}
|
||||
.classifyMain .phaseRow{grid-template-columns:repeat(2,1fr);margin-top:12px}
|
||||
@media(max-width:680px){.classifyTop{grid-template-columns:1fr}.classifyCard{max-width:300px;margin:0 auto}.classifyMain{margin-top:6px}}
|
||||
.choice{text-align:left;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:#fff;cursor:pointer;font-size:15px;font-weight:600}
|
||||
.choice:hover{border-color:var(--ink)}
|
||||
|
|
@ -863,6 +871,7 @@ function defaultState(){
|
|||
classifyDone:false, classifyWrong:null,
|
||||
entryDone:false, entryWrong:null,
|
||||
index:0, stage:"discuss", quizIndex:0,
|
||||
actStep:0, actReveal:false,
|
||||
picks:{}, done:{}, unclear:{},
|
||||
loopback:null, revisit:{}, endReason:null, endGate:null };
|
||||
}
|
||||
|
|
@ -961,7 +970,7 @@ function renderDeck(){
|
|||
function renderClassify(){
|
||||
const correct = S.change;
|
||||
const card = acard(S.service,S.change);
|
||||
const thumb = `<img class="cardThumb" src="cards/s${S.service}-c${S.change}.png" alt="${card.titel}">`;
|
||||
const cardBig = `<img class="classifyCard" src="cards/s${S.service}-c${S.change}.png" alt="${card.titel}">`;
|
||||
if(!S.classifyDone){
|
||||
const choices = CHANGE_TYPES.map((t,i)=>
|
||||
`<button class="choice ${S.classifyWrong===i?'bad':''}" data-i="${i}">${t}</button>`).join("");
|
||||
|
|
@ -972,7 +981,7 @@ function renderClassify(){
|
|||
$("#panel").innerHTML = `
|
||||
<div class="setupHead">Schritt 2 · Change-Art bestimmen</div>
|
||||
<div class="classifyTop">
|
||||
<img class="classifyCard" src="cards/s${S.service}-c${S.change}.png" alt="${card.titel}">
|
||||
${cardBig}
|
||||
<div class="classifyMain">
|
||||
<h2 class="setupTitle" style="margin-top:0">Welche Art von Change ist das?</h2>
|
||||
<p class="muted">Überlegt gemeinsam und wählt die passende Change-Art. Die Legende hilft beim Einordnen.</p>
|
||||
|
|
@ -991,10 +1000,14 @@ function renderClassify(){
|
|||
} else {
|
||||
$("#panel").innerHTML = `
|
||||
<div class="setupHead">Schritt 3 · Erfolgreiche Kategorisierung</div>
|
||||
${thumb}
|
||||
<div class="hint ok">✓ Richtig: ${CHANGE_TYPES[correct]}</div>
|
||||
<div class="recBox"><h4>Warum?</h4>
|
||||
<p style="margin:0;color:var(--muted)">${CHANGE_LEGEND[correct]}</p></div>
|
||||
<div class="classifyTop">
|
||||
${cardBig}
|
||||
<div class="classifyMain">
|
||||
<div class="hint ok">✓ Richtig: ${CHANGE_TYPES[correct]}</div>
|
||||
<div class="recBox"><h4>Warum?</h4>
|
||||
<p style="margin:0;color:var(--muted)">${CHANGE_LEGEND[correct]}</p></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ghost" id="backDeck">← Andere Karte</button>
|
||||
<div class="spacer"></div>
|
||||
|
|
@ -1011,6 +1024,7 @@ function renderEntry(){
|
|||
const recIndex = STATIONEN.findIndex(s=>s.id===rec.id);
|
||||
const correctPhase = STATIONEN[recIndex].phase;
|
||||
const order = ["design","transition","operation","support","review"];
|
||||
const cardBig = `<img class="classifyCard" src="cards/s${S.service}-c${S.change}.png" alt="${acard(S.service,S.change).titel}">`;
|
||||
if(!S.entryDone){
|
||||
const zones = order.map(ph=>
|
||||
`<button class="phaseZone ${S.entryWrong===ph?'bad':''}" data-ph="${ph}"
|
||||
|
|
@ -1019,11 +1033,16 @@ function renderEntry(){
|
|||
? `<div class="hint bad">Diese Phase passt nicht zur Change-Art — denkt an die Definition und probiert es erneut.</div>` : ``;
|
||||
$("#panel").innerHTML = `
|
||||
<div class="setupHead">Schritt 4 · Einstieg finden</div>
|
||||
<div class="hint ok">Change-Art: ${CHANGE_TYPES[S.change]}</div>
|
||||
<h2 class="setupTitle">In welcher Phase startet dieser Change?</h2>
|
||||
<p class="muted">Klickt auf die Lebenszyklus-Phase, in der dieser Change einsteigt.</p>
|
||||
${hint}
|
||||
<div class="phaseRow">${zones}</div>
|
||||
<div class="classifyTop">
|
||||
${cardBig}
|
||||
<div class="classifyMain">
|
||||
<div class="hint ok">Change-Art: ${CHANGE_TYPES[S.change]}</div>
|
||||
<h2 class="setupTitle" style="margin-top:8px">In welcher Phase startet dieser Change?</h2>
|
||||
<p class="muted">Klickt auf die Lebenszyklus-Phase, in der dieser Change einsteigt.</p>
|
||||
${hint}
|
||||
<div class="phaseRow">${zones}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions"><button class="ghost" id="backClassify">← zurück</button></div>`;
|
||||
$("#panel").querySelectorAll(".phaseZone").forEach(el=>{
|
||||
el.onclick=()=>{ const ph=el.dataset.ph;
|
||||
|
|
@ -1034,10 +1053,15 @@ function renderEntry(){
|
|||
} else {
|
||||
$("#panel").innerHTML = `
|
||||
<div class="setupHead">Schritt 5 · Los geht's</div>
|
||||
<div class="hint ok">✓ Einstieg: ${PHASEN[correctPhase].label}</div>
|
||||
<div class="recBox"><h4>Start-Station</h4>
|
||||
<p style="margin:0 0 6px"><b>${rec.id} — ${STATIONEN[recIndex].name}</b></p>
|
||||
<p style="margin:0;color:var(--muted)">${rec.grund}</p></div>
|
||||
<div class="classifyTop">
|
||||
${cardBig}
|
||||
<div class="classifyMain">
|
||||
<div class="hint ok">✓ Einstieg: ${PHASEN[correctPhase].label}</div>
|
||||
<div class="recBox"><h4>Start-Station</h4>
|
||||
<p style="margin:0 0 6px"><b>${rec.id} — ${STATIONEN[recIndex].name}</b></p>
|
||||
<p style="margin:0;color:var(--muted)">${rec.grund}</p></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ghost" id="backClassify">← zurück</button>
|
||||
<div class="spacer"></div>
|
||||
|
|
@ -1064,6 +1088,7 @@ function enterStation(idx){
|
|||
S.index = idx;
|
||||
S.stage = STATIONEN[idx].typ==="gate" ? "gate" : "act";
|
||||
S.gatePick = null; S.quizIndex = 0;
|
||||
S.actStep = 0; S.actReveal = false;
|
||||
}
|
||||
function gateGoto(st, i){
|
||||
S.done[st.id] = true;
|
||||
|
|
@ -1095,53 +1120,62 @@ function renderRun(){
|
|||
const loopBanner = (S.loopback && S.index < S.loopback.untilIdx)
|
||||
? `<div class="tourBanner">↩ <b>Nacharbeit nach Gate ${S.loopback.gateNr}</b> — überarbeitet die folgenden Stationen; danach wird das Gate erneut vorgelegt und entscheidet neu.</div>`
|
||||
: ``;
|
||||
const cardBig = `<img class="classifyCard" src="cards/s${S.service}-c${S.change}.png" alt="${acard(S.service,S.change).titel}">`;
|
||||
const stepBody = st.typ==="gate"
|
||||
? (S.stage==="gateDone" ? renderGateDone(st) : renderGate(st))
|
||||
: renderActivity(st);
|
||||
let body = `
|
||||
${loopBanner}
|
||||
<div class="sHead">${chip}<span class="sId">${st.id}</span></div>
|
||||
<h2 class="sTitle">${st.name}</h2>
|
||||
<div class="caseLine">Fall: «${acard(S.service,S.change).titel}»</div>`;
|
||||
if(st.typ==="gate") body += (S.stage==="gateDone") ? renderGateDone(st) : renderGate(st);
|
||||
else body += (S.stage==="reveal") ? renderReveal(st) : renderAct(st);
|
||||
<div class="classifyTop">
|
||||
${cardBig}
|
||||
<div class="classifyMain">
|
||||
<div class="sHead">${chip}<span class="sId">${st.id}</span></div>
|
||||
<h2 class="sTitle" style="margin-top:8px">${st.name}</h2>
|
||||
${stepBody}
|
||||
</div>
|
||||
</div>`;
|
||||
$("#panel").innerHTML = body;
|
||||
wire(st);
|
||||
}
|
||||
|
||||
/* Aktivitaet — Takt 1: Handeln am Brett (mit "Zeig mir") */
|
||||
function renderAct(st){
|
||||
return `
|
||||
<p class="lead">Handeln am Brett — besprecht und legt ab:</p>
|
||||
<ol class="todo">
|
||||
<li>Beteiligte Rollen → Figuren auf die <b>Mulden des Station-Pucks</b></li>
|
||||
<li>RACI klären → dieselben Figuren ins <b>Aktiv-Feld (R·A·C·I)</b></li>
|
||||
<li>Artefaktkarte → in die <b>Service-Akte</b></li>
|
||||
</ol>
|
||||
<details class="det">
|
||||
<summary>Zeig mir</summary>
|
||||
<div>${raciTable(st)}<p class="muted" style="margin:8px 0 0"><b>Artefakt:</b> ${st.artefakt}</p></div>
|
||||
</details>
|
||||
<div class="actions">
|
||||
<div class="spacer"></div>
|
||||
<button class="primary" id="toReveal">Auflösen →</button>
|
||||
</div>`;
|
||||
/* Aktivitaet — schrittweiser Mikro-Ablauf: 4 Fragen, je einzeln + Aufloesung.
|
||||
1) Was steckt hinter der Ueberschrift? 2) Beteiligte Rollen 3) RACI 4) Artefakt */
|
||||
function activitySteps(st){
|
||||
return [
|
||||
{ label:"Diskussion",
|
||||
frage:`<p class="lead">Diskutiert gemeinsam: Was fällt alles unter <b>„${st.name}"</b>? Was stellt ihr euch darunter vor? Nennt Beispiele.</p>`,
|
||||
auf:`<p style="margin:0 0 8px">${st.beschreibung}</p><h4 class="aufH">Das fällt darunter</h4><ul>${st.umfasst.map(u=>`<li>${u}</li>`).join("")}</ul>` },
|
||||
{ label:"Beteiligte Rollen",
|
||||
frage:`<p class="lead">Welche Rollen sind an dieser Aktivität beteiligt? Stellt ihre Figuren auf die <b>Mulden des Station-Pucks</b>.</p>`,
|
||||
auf:`<h4 class="aufH">Beteiligte Rollen</h4><div class="roleChips">${st.raci.map(([r])=>`<span class="roleChip">${roleLabel(r)}</span>`).join("")}</div>` },
|
||||
{ label:"RACI",
|
||||
frage:`<p class="lead">Klärt die <b>RACI</b>: Wer ist R, A, C, I? Sortiert die Figuren ins <b>Aktiv-Feld (R·A·C·I)</b>.</p>`,
|
||||
auf:`<h4 class="aufH">RACI</h4>${raciTable(st)}` },
|
||||
{ label:"Artefakt",
|
||||
frage:`<p class="lead">Welche <b>Artefaktkarte</b> entsteht hier und gehört in die <b>Service-Akte</b>?</p>`,
|
||||
auf:`<h4 class="aufH">Artefakt</h4><p style="margin:0"><b>${st.artefakt}</b></p>` }
|
||||
];
|
||||
}
|
||||
function renderActivity(st){
|
||||
const steps = activitySteps(st);
|
||||
const i = Math.min(S.actStep||0, steps.length-1);
|
||||
const step = steps[i];
|
||||
const isLast = i === steps.length-1;
|
||||
let html = `<div class="tourProg">Schritt ${i+1}/${steps.length} · ${step.label}</div>${step.frage}`;
|
||||
if(S.actReveal) html += `<div class="aufBox">${step.auf}</div>`;
|
||||
|
||||
/* Aktivitaet — Takt 2: Aufloesung & Abgleich */
|
||||
function renderReveal(st){
|
||||
return `
|
||||
<p class="lead">Auflösung — gleicht euer Brett ab:</p>
|
||||
${raciTable(st)}
|
||||
<p class="muted" style="margin-top:10px"><b>Artefakt:</b> ${st.artefakt}</p>
|
||||
<details class="det">
|
||||
<summary>Worum geht's & was umfasst die Station</summary>
|
||||
<div><p>${st.beschreibung}</p><ul>${st.umfasst.map(u=>`<li>${u}</li>`).join("")}</ul></div>
|
||||
</details>
|
||||
<div class="actions">
|
||||
<label class="unclear"><input type="checkbox" id="unclear" ${S.unclear[st.id]?'checked':''}/> War unklar</label>
|
||||
<div class="spacer"></div>
|
||||
${S.index < STATIONEN.length-1
|
||||
? `<button class="primary" id="nextStation">Nächste Station →</button>`
|
||||
: `<button class="primary" id="finish">Durchlauf abschließen</button>`}
|
||||
</div>`;
|
||||
let actions = `<div class="actions">`;
|
||||
if(S.actReveal || i>0) actions += `<button class="ghost" id="actBack">← zurück</button>`;
|
||||
if(S.actReveal && isLast)
|
||||
actions += `<label class="unclear"><input type="checkbox" id="unclear" ${S.unclear[st.id]?'checked':''}/> War unklar</label>`;
|
||||
actions += `<div class="spacer"></div>`;
|
||||
if(!S.actReveal) actions += `<button class="primary" id="actReveal">Auflösen →</button>`;
|
||||
else if(!isLast) actions += `<button class="primary" id="actNext">Weiter →</button>`;
|
||||
else actions += S.index < STATIONEN.length-1
|
||||
? `<button class="primary" id="nextStation">Nächste Station →</button>`
|
||||
: `<button class="primary" id="finish">Durchlauf abschließen</button>`;
|
||||
actions += `</div>`;
|
||||
return html + actions;
|
||||
}
|
||||
|
||||
/* Gate — Entscheidung nach Kriterien */
|
||||
|
|
@ -1190,7 +1224,9 @@ function renderGateDone(st){
|
|||
/* ====================== WIRING ====================== */
|
||||
function wire(st){
|
||||
const b = id => $("#"+id);
|
||||
if(b("toReveal")) b("toReveal").onclick = ()=>{ S.stage="reveal"; save(); draw(); };
|
||||
if(b("actReveal")) b("actReveal").onclick = ()=>{ S.actReveal=true; save(); draw(); };
|
||||
if(b("actNext")) b("actNext").onclick = ()=>{ S.actStep=(S.actStep||0)+1; S.actReveal=false; save(); draw(); };
|
||||
if(b("actBack")) b("actBack").onclick = ()=>{ if(S.actReveal){ S.actReveal=false; } else if((S.actStep||0)>0){ S.actStep--; S.actReveal=true; } save(); draw(); };
|
||||
if(b("unclear")) b("unclear").onchange = e=>{ if(e.target.checked) S.unclear[st.id]=true; else delete S.unclear[st.id]; save(); renderList(); };
|
||||
if(b("nextStation")) b("nextStation").onclick = ()=>{ S.done[st.id]=true; enterStation(S.index+1); save(); draw(); };
|
||||
if(b("finish")) b("finish").onclick = ()=>{ S.done[st.id]=true; S.view="end"; S.endReason="done"; save(); draw(); };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue