refactor: move language picker to sidebar as dropdown

- Remove language button from header
- Add language select dropdown in sidebar settings
- Add translations for "Language" label in all languages
- Remove unused .lang-switch CSS
This commit is contained in:
2025-12-31 10:26:51 +01:00
parent b7a34b02d8
commit af5a5a2045
4 changed files with 58 additions and 31 deletions

View File

@@ -2,7 +2,7 @@ import { LessonEngine } from "./impl/LessonEngine.js";
import { CodeEditor } from "./impl/CodeEditor.js";
import { renderLesson, renderModuleList, renderLevelIndicator, updateActiveLessonInSidebar } from "./helpers/renderer.js";
import { loadModules } from "./config/lessons.js";
import { initI18n, t, getLanguage, setLanguage, getNextLanguage, applyTranslations } from "./i18n.js";
import { initI18n, t, getLanguage, setLanguage, applyTranslations } from "./i18n.js";
// Simplified state - LessonEngine now manages lesson state and progress
const state = {
@@ -17,7 +17,7 @@ const elements = {
// Header
menuBtn: document.getElementById("menu-btn"),
logoLink: document.getElementById("logo-link"),
langBtn: document.getElementById("lang-btn"),
langSelect: document.getElementById("lang-select"),
helpBtn: document.getElementById("help-btn"),
// Left panel
@@ -117,10 +117,7 @@ function toggleExpectedResult() {
// ================= LANGUAGE TOGGLE =================
function toggleLanguage() {
const currentLang = getLanguage();
const newLang = getNextLanguage(currentLang);
function changeLanguage(newLang) {
// Add transition class before any updates
elements.editorSection?.classList.add("transitioning");
@@ -730,8 +727,9 @@ function init() {
loadCurrentLesson();
});
// Language toggle
elements.langBtn.addEventListener("click", toggleLanguage);
// Language select
elements.langSelect.value = getLanguage();
elements.langSelect.addEventListener("change", (e) => changeLanguage(e.target.value));
// Expected result toggle
elements.showExpectedBtn.addEventListener("click", toggleExpectedResult);

View File

@@ -36,6 +36,7 @@ const translations = {
// Sidebar
menu: "Menu",
closeMenu: "Close menu",
language: "Language",
progress: "Progress",
progressText: "{percent}% Complete ({completed}/{total})",
lessons: "Lessons",
@@ -135,6 +136,7 @@ const translations = {
// Sidebar
menu: "Menü",
closeMenu: "Menü schließen",
language: "Sprache",
progress: "Fortschritt",
progressText: "{percent}% abgeschlossen ({completed}/{total})",
lessons: "Lektionen",
@@ -235,6 +237,7 @@ const translations = {
// Sidebar
menu: "Menu",
closeMenu: "Zamknij menu",
language: "Język",
progress: "Postęp",
progressText: "{percent}% ukończone ({completed}/{total})",
lessons: "Lekcje",
@@ -335,6 +338,7 @@ const translations = {
// Sidebar
menu: "Menú",
closeMenu: "Cerrar menú",
language: "Idioma",
progress: "Progreso",
progressText: "{percent}% completado ({completed}/{total})",
lessons: "Lecciones",
@@ -435,6 +439,7 @@ const translations = {
// Sidebar
menu: "القائمة",
closeMenu: "إغلاق القائمة",
language: "اللغة",
progress: "التقدم",
progressText: "{percent}% مكتمل ({completed}/{total})",
lessons: "الدروس",
@@ -535,6 +540,7 @@ const translations = {
// Sidebar
menu: "Меню",
closeMenu: "Закрити меню",
language: "Мова",
progress: "Прогрес",
progressText: "{percent}% завершено ({completed}/{total})",
lessons: "Уроки",

View File

@@ -20,7 +20,6 @@
<h1><span class="code-text">CODE</span><span>CRISPIES</span></h1>
</a>
<div class="header-actions">
<button id="lang-btn" class="lang-switch" data-i18n-aria-label="langSwitchLabel" data-i18n="langSwitch" aria-label="Sprache wechseln: Deutsch">DE</button>
<button id="help-btn" class="help-toggle" data-i18n-aria-label="help" aria-label="Help">?</button>
</div>
</header>
@@ -109,6 +108,17 @@
<div class="sidebar-section">
<h4 data-i18n="settings">Settings</h4>
<label class="setting-row">
<span class="setting-label" data-i18n="language">Language</span>
<select id="lang-select" class="lang-select">
<option value="en">English</option>
<option value="de">Deutsch</option>
<option value="pl">Polski</option>
<option value="es">Español</option>
<option value="ar">العربية</option>
<option value="uk">Українська</option>
</select>
</label>
<label class="toggle-switch">
<input type="checkbox" id="disable-feedback-toggle" checked />
<span class="toggle-slider"></span>

View File

@@ -220,28 +220,6 @@ code, kbd {
gap: var(--spacing-sm);
}
.lang-switch {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid var(--border-color);
background: none;
font-size: 0.7rem;
font-weight: 700;
text-decoration: none;
color: var(--light-text);
transition: all 0.2s;
}
.lang-switch:hover {
border-color: var(--primary-color);
color: var(--primary-color);
background: var(--primary-bg-light);
}
/* ================= GAME LAYOUT ================= */
.game-layout {
display: flex;
@@ -991,6 +969,41 @@ button.lesson-list-item {
}
/* ================= TOGGLE SWITCH ================= */
/* Setting row (for label + control) */
.setting-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--spacing-sm);
}
.setting-label {
font-size: 0.9rem;
color: var(--text-color);
}
/* Language select */
.lang-select {
padding: 6px 10px;
border: 1px solid var(--border-color);
border-radius: var(--radius-sm);
background: var(--panel-bg);
color: var(--text-color);
font-size: 0.85rem;
cursor: pointer;
min-width: 120px;
}
.lang-select:hover {
border-color: var(--primary-color);
}
.lang-select:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
}
.toggle-switch {
display: flex;
align-items: center;