Weltkueche Fundament: geschaffte Gerichte persistent (localStorage, Schueler-Reload) + Backend-Submit pro Gericht (Lehrer-Historie: score/correctClicks/wrongClicks/completed) + Fehler-Zaehler

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 12:38:03 +02:00
parent f6df2eb79f
commit 4bfb6539cb
+46 -3
View File
@@ -618,7 +618,7 @@ const BADGES = [
];
/* ====================== STATE ====================== */
let state={name:"",score:0,badges:[],completed:[],totalCorrect:0,cleanIngredients:0};
let state={name:"",score:0,badges:[],completed:[],totalCorrect:0,totalWrong:0,cleanIngredients:0,startedAt:0};
let map,markerLayer,current;
const store={get(k,d){try{const v=localStorage.getItem(k);return v?JSON.parse(v):d;}catch(e){return d;}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v));}catch(e){}}};
@@ -639,6 +639,7 @@ async function startGame(){
try { await loadWeltkuecheData(); }
catch (e) { alert('Daten konnten nicht geladen werden: ' + e.message); return; }
}
wkLoadProgress(); // bereits geschaffte Gerichte (dieser Browser) wiederherstellen
// Name aus Plattform-Session — kein Eingabefeld mehr
state.name = (window.WK_STUDENT_NAME && window.WK_STUDENT_NAME !== 'Gast') ? window.WK_STUDENT_NAME : 'Forscher:in';
document.getElementById('statName').textContent = state.name;
@@ -792,6 +793,8 @@ window.GGS_LIVE_STATE = function() {
ingCurrent: (current && current.dish && current.idx<current.dish.ings.length) ? current.dish.ings[current.idx] : null,
mistakesInDish: current ? (current.mistakesInDish||0) : 0,
score: state.score || 0,
correctClicks: state.totalCorrect || 0,
wrongClicks: state.totalWrong || 0,
completed: completedDish,
completedTotal: totalDish,
badgesEarned: (state.badges||[]).length,
@@ -800,6 +803,44 @@ window.GGS_LIVE_STATE = function() {
};
};
/* ===== Persistenz (Schüler-Reload) + Backend-Submit (Lehrer-Historie/Kennzahlen) ===== */
const WK_PKEY = 'wk_progress_' + (window.WK_SESSION_ID || 'local');
function wkSaveProgress(){
try { store.set(WK_PKEY, { completed: state.completed, score: state.score, badges: state.badges }); } catch(_){}
}
function wkLoadProgress(){
const p = store.get(WK_PKEY, null);
if (p && Array.isArray(p.completed)) {
state.completed = p.completed;
state.score = p.score || 0;
state.badges = Array.isArray(p.badges) ? p.badges : [];
}
}
function wkSubmitProgress(dish, perfect){
if (!window.WK_SESSION_ID) return; // Free-Mode → nichts senden
const api = (window.WK_API_BASE || '/geograsim/App/php/api') + '/progress';
const mis = current ? (current.mistakesInDish||0) : 0;
// grobe Sterne aus der Fehlerquote des Gerichts (für Benchmark/Übersicht)
const dishStars = perfect ? 5 : mis <= 1 ? 4 : mis <= 3 ? 3 : mis <= 6 ? 2 : 1;
try {
fetch(api, {
method:'POST', headers:{'Content-Type':'application/json'}, credentials:'same-origin',
body: JSON.stringify({
action:'complete', simId:'weltkueche', stars: dishStars,
durationMs: Math.max(0, Date.now() - ((current && current.startTs) || Date.now())),
data: {
event:'dish_complete',
dishId: dish.id, dishName: dish.name, dishOrigin: dish.origin || null,
completed: state.completed.length, total: DISHES.length,
score: state.score, dishScore: (current && current.dishScore) || 0,
correctClicks: state.totalCorrect || 0, wrongClicks: state.totalWrong || 0,
mistakesInDish: mis, perfect: !!perfect
}
})
}).catch(()=>{});
} catch(_){}
}
/* ====================== DISH GRID ====================== */
let _activeFilter = 'all';
function renderDishes(){
@@ -839,7 +880,7 @@ window.setDishFilter = setDishFilter;
/* ====================== GAME ====================== */
function openDish(id){
const dish=DISHES.find(d=>d.id===id);
current={dish,idx:0,solved:[],dishScore:0,mistakesInDish:0,found:[],wrongHere:0,wrongStreak:0};
current={dish,idx:0,solved:[],dishScore:0,mistakesInDish:0,found:[],wrongHere:0,wrongStreak:0,startTs:Date.now()};
// Aufgabe-Cache reset pro Gericht — neue Korrekt-Auswahl + neue Distraktoren
_taskCache = {};
showRecipeScreen(dish);
@@ -1243,7 +1284,7 @@ function guess(key){
updateHUD(); renderIngList();
} else {
b.classList.add('wrong'); b.disabled=true;
current.wrongStreak++; current.wrongHere++; current.mistakesInDish++;
current.wrongStreak++; current.wrongHere++; current.mistakesInDish++; state.totalWrong++;
showWrong(key, cls, ingKey);
setTimeout(()=>playSfx('ingredient-wrong'), 120);
}
@@ -1569,6 +1610,8 @@ function finishDish(){
if(!state.completed.includes(d.id)) state.completed.push(d.id);
playSfx('dish-complete');
const perfect=current.mistakesInDish===0;
wkSaveProgress(); // Schüler-Reload merkt sich geschaffte Gerichte
wkSubmitProgress(d, perfect); // Lehrer-Historie + Kennzahlen ans Backend
const newly=[];
if(perfect) newly.push(...awardLive(['perfect']));
newly.push(...awardLive(['dish']));