Aufgaben-Python/assets/sidebar.js

181 lines
9.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 🧭 NEXT-GEN SIDEBAR COMPONENT 🧭
* =================================
* Rendert eine saubere, linksbündige Sidebar-Navigation
* für das Hauptportal und alle 27 Kapitel-Seiten.
*/
(function () {
const LEHRPFADE = [
{
id: "lehrpfad_1",
title: "🌱 1. Grundlagen",
badge: "G01–G10",
items: [
{ id: "01_erste_schritte_taschenrechner", num: "G01", icon: "🧮", title: "Taschenrechner", path: "lehrpfad_1_grundlagen/01_erste_schritte_taschenrechner/index.html" },
{ id: "02_variablen_und_datentypen", num: "G02", icon: "📦", title: "Variablen & Typen", path: "lehrpfad_1_grundlagen/02_variablen_und_datentypen/index.html" },
{ id: "03_ein_und_ausgabe", num: "G03", icon: "💬", title: "Ein- & Ausgabe", path: "lehrpfad_1_grundlagen/03_ein_und_ausgabe/index.html" },
{ id: "04_verzweigungen_und_bedingungen", num: "G04", icon: "🚦", title: "Bedingungen (if)", path: "lehrpfad_1_grundlagen/04_verzweigungen_und_bedingungen/index.html" },
{ id: "05_schleifen_und_wiederholungen", num: "G05", icon: "🎡", title: "Schleifen (for/while)", path: "lehrpfad_1_grundlagen/05_schleifen_und_wiederholungen/index.html" },
{ id: "06_funktionen_und_module", num: "G06", icon: "🪄", title: "Funktionen & Module", path: "lehrpfad_1_grundlagen/06_funktionen_und_module/index.html" },
{ id: "07_listen_und_sequenzen", num: "G07", icon: "📋", title: "Listen & Sequenzen", path: "lehrpfad_1_grundlagen/07_listen_und_sequenzen/index.html" },
{ id: "08_textverarbeitung_und_strings", num: "G08", icon: "🔤", title: "String-Methoden", path: "lehrpfad_1_grundlagen/08_textverarbeitung_und_strings/index.html" },
{ id: "09_dictionaries_und_sets", num: "G09", icon: "🗃️", title: "Dicts & Sets", path: "lehrpfad_1_grundlagen/09_dictionaries_und_sets/index.html" },
{ id: "10_comprehensions_datum_algorithmen", num: "G10", icon: "🚀", title: "Comprehensions", path: "lehrpfad_1_grundlagen/10_comprehensions_datum_algorithmen/index.html" },
]
},
{
id: "lehrpfad_2",
title: "🏗️ 2. OOP Einstieg",
badge: "00–06",
items: [
{ id: "00_fehlersuche_und_grundlagen", num: "00", icon: "🔍", title: "Fehlersuche & Debug", path: "lehrpfad_2_oop_einstieg/00_fehlersuche_und_grundlagen/index.html" },
{ id: "01_einstieg_klassen", num: "01", icon: "🏗️", title: "Einstieg in Klassen", path: "lehrpfad_2_oop_einstieg/01_einstieg_klassen/index.html" },
{ id: "02_init_und_self", num: "02", icon: "⚙️", title: "Konstruktor & self", path: "lehrpfad_2_oop_einstieg/02_init_und_self/index.html" },
{ id: "03_methoden_und_verhalten", num: "03", icon: "🏎️", title: "Methoden & Verhalten", path: "lehrpfad_2_oop_einstieg/03_methoden_und_verhalten/index.html" },
{ id: "04_str_und_darstellung", num: "04", icon: "🧾", title: "__str__ Darstellung", path: "lehrpfad_2_oop_einstieg/04_str_und_darstellung/index.html" },
{ id: "04b_umstieg_vscode", num: "04b", icon: "💻", title: "VS Code Setup", path: "lehrpfad_2_oop_einstieg/04b_umstieg_vscode/index.html" },
{ id: "04c_git_und_versionskontrolle", num: "04c", icon: "🌿", title: "Git-Versionskontrolle", path: "lehrpfad_2_oop_einstieg/04c_git_und_versionskontrolle/index.html" },
{ id: "05_objekte_kombinieren", num: "05", icon: "🎵", title: "Objekte kombinieren", path: "lehrpfad_2_oop_einstieg/05_objekte_kombinieren/index.html" },
{ id: "06_abschlussprojekt_tamagotchi", num: "06", icon: "🥚", title: "Projekt: Tamagotchi", path: "lehrpfad_2_oop_einstieg/06_abschlussprojekt_tamagotchi/index.html" },
]
},
{
id: "lehrpfad_3",
title: "🚀 3. Fortgeschritten",
badge: "07–16",
items: [
{ id: "07_referenzen_und_speicher", num: "07", icon: "🧠", title: "Referenzen & Speicher", path: "lehrpfad_3_fortgeschrittenes_oop/07_referenzen_und_speicher/index.html" },
{ id: "08_operator_overloading_dunder", num: "08", icon: "➕", title: "Operator Overloading", path: "lehrpfad_3_fortgeschrittenes_oop/08_operator_overloading_dunder/index.html" },
{ id: "09_eigene_unit_tests_schreiben", num: "09", icon: "🧪", title: "Unit Tests & TDD", path: "lehrpfad_3_fortgeschrittenes_oop/09_eigene_unit_tests_schreiben/index.html" },
{ id: "10_vererbung_und_super", num: "10", icon: "🧬", title: "Vererbung & super()", path: "lehrpfad_3_fortgeschrittenes_oop/10_vererbung_und_super/index.html" },
{ id: "11_polymorphie_und_interfaces", num: "11", icon: "🎭", title: "Polymorphie", path: "lehrpfad_3_fortgeschrittenes_oop/11_polymorphie_und_interfaces/index.html" },
{ id: "12_exceptions_und_fehlerbehandlung", num: "12", icon: "🛡️", title: "Exceptions & Fehler", path: "lehrpfad_3_fortgeschrittenes_oop/12_exceptions_und_fehlerbehandlung/index.html" },
{ id: "13_persistenz_json_und_csv", num: "13", icon: "💾", title: "Persistenz (JSON/CSV)", path: "lehrpfad_3_fortgeschrittenes_oop/13_persistenz_json_und_csv/index.html" },
{ id: "14_gui_mit_tkinter", num: "14", icon: "🖥️", title: "Desktop-GUIs (Tkinter)", path: "lehrpfad_3_fortgeschrittenes_oop/14_gui_mit_tkinter/index.html" },
{ id: "15_parameter_und_container", num: "15", icon: "🎒", title: "Container & *args", path: "lehrpfad_3_fortgeschrittenes_oop/15_parameter_und_container/index.html" },
{ id: "16_master_abschlussprojekt", num: "16", icon: "🏆", title: "Master-Abschlussprojekt", path: "lehrpfad_3_fortgeschrittenes_oop/16_master_abschlussprojekt/index.html" },
]
}
];
function detectRootPrefix() {
const p = window.location.pathname;
if (p.includes("/lehrpfad_1_grundlagen/") || p.includes("/lehrpfad_2_oop_einstieg/") || p.includes("/lehrpfad_3_fortgeschrittenes_oop/")) {
return "../../";
}
return "./";
}
function initSidebar() {
const prefix = detectRootPrefix();
const currentPath = window.location.pathname;
// Wrap existing body content in .app-main if not wrapped yet
if (!document.querySelector(".app-main")) {
const mainWrapper = document.createElement("div");
mainWrapper.className = "app-main";
while (document.body.firstChild) {
mainWrapper.appendChild(document.body.firstChild);
}
document.body.appendChild(mainWrapper);
}
// Check if sidebar already exists
if (document.querySelector(".app-sidebar")) return;
// Gamification Data
const gData = window.GAMIFICATION_DATA || { xp: 0, level: 1, titel: "Code-Küken 🐣", geloeste_kapitel: [] };
const solvedSet = new Set(gData.geloeste_kapitel || []);
// 1. Mobile Drawer Toggle Button
const toggleBtn = document.createElement("button");
toggleBtn.type = "button";
toggleBtn.className = "sidebar-mobile-toggle";
toggleBtn.innerHTML = "<span>☰ Menü</span>";
document.body.appendChild(toggleBtn);
// 2. Mobile Overlay
const overlay = document.createElement("div");
overlay.className = "sidebar-overlay";
document.body.appendChild(overlay);
// 3. Sidebar Element
const sidebar = document.createElement("aside");
sidebar.className = "app-sidebar";
let navSectionsHtml = "";
LEHRPFADE.forEach(track => {
let itemsHtml = "";
track.items.forEach(item => {
const fullLink = prefix + item.path;
const isActive = currentPath.includes(item.id);
const isSolved = solvedSet.has(item.path.replace("/index.html", ""));
itemsHtml += `
<a href="${fullLink}" class="sidebar-link ${isActive ? 'active' : ''}">
<span class="sidebar-link-icon">${item.icon}</span>
<span class="sidebar-link-text">${item.num}. ${item.title}</span>
${isSolved ? '<span style="font-size: 0.75rem;">✅</span>' : ''}
</a>
`;
});
navSectionsHtml += `
<div class="sidebar-group">
<div class="sidebar-group-title">
<span>${track.title}</span>
<span style="background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 99px; font-size: 0.7rem;">${track.badge}</span>
</div>
<div style="display: flex; flex-direction: column; gap: 2px;">
${itemsHtml}
</div>
</div>
`;
});
sidebar.innerHTML = `
<div class="sidebar-header">
<a href="${prefix}index.html" style="display: flex; align-items: center; gap: 10px; text-decoration: none; color: white;">
<div class="sidebar-logo">🐍</div>
<div>
<div class="sidebar-title">Python Portal</div>
<div class="sidebar-subtitle">Lernplattform</div>
</div>
</a>
</div>
<div style="padding: 10px 14px; border-bottom: 1px solid var(--border-dark); display: flex; flex-direction: column; gap: 2px; background: rgba(0,0,0,0.15);">
<a href="${prefix}index.html" class="sidebar-link">🏠 Startseite</a>
<a href="${prefix}index.html#tutorial" class="sidebar-link">📖 Tutorial & Workflow</a>
<a href="${prefix}index.html#zertifikate" class="sidebar-link">🏆 Zertifikate</a>
</div>
<div class="sidebar-nav">
${navSectionsHtml}
</div>
<div class="sidebar-footer">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="font-size: 0.85rem; font-weight: 700; color: white;">⭐ Level ${gData.level || 1}</div>
<div style="font-size: 0.82rem; font-weight: 700; color: #38bdf8;">${gData.xp || 0} XP</div>
</div>
</div>
`;
document.body.prepend(sidebar);
// Toggle Handler
toggleBtn.addEventListener("click", () => {
sidebar.classList.toggle("open");
overlay.classList.toggle("active");
});
overlay.addEventListener("click", () => {
sidebar.classList.remove("open");
overlay.classList.remove("active");
});
}
document.addEventListener("DOMContentLoaded", initSidebar);
})();