feat(01-05): forest screen with level map and complete app flow
- Add forest overview screen with 6-level map showing locked/current/completed states - Create src/forest/scene.ts with getLevelStatus, renderLevelMap, initForestScreen - Wire complete flow: welcome -> forest -> lesson -> forest with progress updates - Add forest CSS with level card styles and continue button Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Continue button starts the current level
|
||||
continueBtn.onclick = () => onStartLesson(progress.currentLevel);
|
||||
}
|
||||
Reference in New Issue
Block a user