2026-03-29 11:15:18 +02:00
|
|
|
import type { Progress, LevelStatus } from "../types";
|
|
|
|
|
import { levels } from "../game/levels";
|
|
|
|
|
import { getProgress } from "../storage/db";
|
|
|
|
|
|
|
|
|
|
export function getLevelStatus(
|
|
|
|
|
levelNum: number,
|
|
|
|
|
progress: Progress,
|
|
|
|
|
): LevelStatus {
|
|
|
|
|
if (progress.completedLevels.includes(levelNum)) return "completed";
|
|
|
|
|
if (levelNum === progress.currentLevel) return "current";
|
|
|
|
|
return "locked";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function renderLevelMap(
|
|
|
|
|
container: HTMLElement,
|
|
|
|
|
progress: Progress,
|
|
|
|
|
onLevelClick: (level: number) => void,
|
|
|
|
|
): void {
|
|
|
|
|
container.innerHTML = "";
|
|
|
|
|
|
|
|
|
|
levels.forEach((level) => {
|
|
|
|
|
const status = getLevelStatus(level.level, progress);
|
|
|
|
|
const card = document.createElement("button");
|
|
|
|
|
card.className = `level-card level-card--${status}`;
|
|
|
|
|
card.dataset.level = String(level.level);
|
|
|
|
|
|
|
|
|
|
const statusIcon =
|
|
|
|
|
status === "completed" ? "\u2713" : status === "current" ? "\u2192" : "\uD83D\uDD12";
|
|
|
|
|
const keysDisplay = level.newKeys
|
|
|
|
|
.filter((k) => k !== " ")
|
|
|
|
|
.map((k) => k.toUpperCase())
|
|
|
|
|
.join(" ");
|
|
|
|
|
|
|
|
|
|
card.innerHTML = `
|
|
|
|
|
<span class="level-card__number">Stufe ${level.level}</span>
|
|
|
|
|
<span class="level-card__keys">${keysDisplay}${level.newKeys.includes(" ") ? " + Leertaste" : ""}</span>
|
|
|
|
|
<span class="level-card__status">${statusIcon}</span>
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
// Only current and completed levels are clickable
|
|
|
|
|
if (status !== "locked") {
|
|
|
|
|
card.addEventListener("click", () => onLevelClick(level.level));
|
|
|
|
|
} else {
|
|
|
|
|
card.disabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
container.appendChild(card);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-29 11:30:55 +02:00
|
|
|
const MAX_LEVEL = 6;
|
|
|
|
|
|
2026-03-29 11:15:18 +02:00
|
|
|
export async function initForestScreen(
|
|
|
|
|
db: IDBDatabase,
|
|
|
|
|
onStartLesson: (level: number) => void,
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const mapContainer = document.getElementById("level-map")!;
|
|
|
|
|
const continueBtn = document.getElementById(
|
|
|
|
|
"continue-btn",
|
|
|
|
|
) as HTMLButtonElement;
|
|
|
|
|
const progress = await getProgress(db);
|
|
|
|
|
if (!progress) return;
|
|
|
|
|
|
|
|
|
|
renderLevelMap(mapContainer, progress, onStartLesson);
|
|
|
|
|
|
2026-03-29 11:30:55 +02:00
|
|
|
const allComplete = levels.every((l) =>
|
|
|
|
|
progress.completedLevels.includes(l.level),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (allComplete) {
|
|
|
|
|
continueBtn.textContent = "Alle Stufen geschafft!";
|
|
|
|
|
continueBtn.disabled = true;
|
|
|
|
|
continueBtn.classList.add("forest__continue-btn--done");
|
|
|
|
|
} else {
|
|
|
|
|
continueBtn.textContent = "Weiter ueben";
|
|
|
|
|
continueBtn.disabled = false;
|
|
|
|
|
continueBtn.classList.remove("forest__continue-btn--done");
|
|
|
|
|
continueBtn.onclick = () =>
|
|
|
|
|
onStartLesson(Math.min(progress.currentLevel, MAX_LEVEL));
|
|
|
|
|
}
|
2026-03-29 11:15:18 +02:00
|
|
|
}
|