feat: implement milestone-based progress system and activate new lessons

Progress System:
- Replace percentage-based progress with milestone markers (1, 5, 10, 20, 30, 50, 75, 100)
- Add visual milestone indicators with reached/current/next states
- Add celebration animation when milestones are reached
- Update progress bar to show progress toward next milestone
- Add progressTextMilestone i18n key for all 6 languages

New Lessons Activated:
- HTML Dialog (native modal dialogs)
- HTML Progress & Meter (indicator elements)
- HTML Fieldset (form grouping)
- HTML Datalist (autocomplete inputs)

This adds 10 new lessons across all 6 languages, bringing total from ~66 to ~76.
This commit is contained in:
2026-01-16 13:56:29 +01:00
parent 9844d9ed15
commit b693013743
7 changed files with 209 additions and 13 deletions

View File

@@ -165,6 +165,7 @@ const elements = {
sectionFooterLessonLinks: document.getElementById("section-footer-lesson-links"),
progressFill: document.getElementById("progress-fill"),
progressText: document.getElementById("progress-text"),
milestonesContainer: document.getElementById("milestones"),
resetBtn: document.getElementById("reset-btn"),
disableFeedbackToggle: document.getElementById("disable-feedback-toggle"),
@@ -310,14 +311,48 @@ function showSuccessHint(message) {
// ================= PROGRESS DISPLAY =================
// Track last milestone to detect new achievements
let lastMilestoneReached = 0;
function updateProgressDisplay() {
const stats = lessonEngine.getProgressStats();
elements.progressFill.style.width = `${stats.percentComplete}%`;
elements.progressText.textContent = t("progressText", {
percent: stats.percentComplete,
// Update progress bar (now shows progress to next milestone)
elements.progressFill.style.width = `${stats.progressToNext}%`;
// Update progress text
elements.progressText.textContent = t("progressTextMilestone", {
completed: stats.totalCompleted,
total: stats.totalLessons
next: stats.nextMilestone
});
// Update milestone indicators
if (elements.milestonesContainer) {
const milestoneEls = elements.milestonesContainer.querySelectorAll(".milestone");
milestoneEls.forEach((el) => {
const value = parseInt(el.dataset.value, 10);
el.classList.remove("reached", "current", "next", "just-reached");
if (stats.milestonesReached.includes(value)) {
el.classList.add("reached");
// Check if this milestone was just reached
if (value > lastMilestoneReached && value === stats.currentMilestone) {
el.classList.add("just-reached");
}
} else if (value === stats.nextMilestone) {
el.classList.add("next");
}
if (value === stats.currentMilestone) {
el.classList.add("current");
}
});
}
// Update last milestone for celebration detection
if (stats.currentMilestone > lastMilestoneReached) {
lastMilestoneReached = stats.currentMilestone;
}
}
// ================= USER SETTINGS =================