feat(i18n): add dynamic lesson loading by language

- Import both EN and DE lesson files in lessons.js
- loadModules() now accepts language parameter
- toggleLanguage() reloads lessons in new language
- initializeModules() uses current language from i18n
- Preserves user position when switching languages
This commit is contained in:
2025-12-30 15:43:00 +01:00
parent a621adada9
commit 5e0f2c9936
2 changed files with 128 additions and 62 deletions

View File

@@ -1,63 +1,112 @@
/**
* Lesson Config - Functions for loading lesson configurations
* Supports English and German lesson content
*/
// Import lesson configs
import basicSelectorsConfig from "../../lessons/00-basic-selectors.json";
import advancedSelectorsConfig from "../../lessons/01-advanced-selectors.json";
import tailwindConfig from "../../lessons/10-tailwind-basics.json";
// CSS lessons
import boxModelConfig from "../../lessons/01-box-model.json";
import flexboxConfig from "../../lessons/flexbox.json";
import responsiveConfig from "../../lessons/08-responsive.json";
import unitsVariablesConfig from "../../lessons/05-units-variables.json";
import transitionsAnimationsConfig from "../../lessons/06-transitions-animations.json";
// HTML lessons
import htmlElementsConfig from "../../lessons/20-html-elements.json";
import htmlFormsBasicConfig from "../../lessons/21-html-forms-basic.json";
import htmlFormsValidationConfig from "../../lessons/22-html-forms-validation.json";
import htmlDetailsSummaryConfig from "../../lessons/23-html-details-summary.json";
import htmlProgressMeterConfig from "../../lessons/24-html-progress-meter.json";
import htmlDatalistConfig from "../../lessons/25-html-datalist.json";
import htmlDataAttributesConfig from "../../lessons/26-html-data-attributes.json";
import htmlDialogConfig from "../../lessons/27-html-dialog.json";
import htmlFormsFieldsetConfig from "../../lessons/28-html-forms-fieldset.json";
import htmlFigureConfig from "../../lessons/29-html-figure.json";
import htmlTablesConfig from "../../lessons/30-html-tables.json";
import htmlMarqueeConfig from "../../lessons/31-html-marquee.json";
import htmlSvgConfig from "../../lessons/32-html-svg.json";
// English lesson imports
import basicSelectorsEN from "../../lessons/00-basic-selectors.json";
import advancedSelectorsEN from "../../lessons/01-advanced-selectors.json";
import boxModelEN from "../../lessons/01-box-model.json";
import unitsVariablesEN from "../../lessons/05-units-variables.json";
import transitionsAnimationsEN from "../../lessons/06-transitions-animations.json";
import responsiveEN from "../../lessons/08-responsive.json";
import tailwindEN from "../../lessons/10-tailwind-basics.json";
import htmlElementsEN from "../../lessons/20-html-elements.json";
import htmlFormsBasicEN from "../../lessons/21-html-forms-basic.json";
import htmlFormsValidationEN from "../../lessons/22-html-forms-validation.json";
import htmlDetailsSummaryEN from "../../lessons/23-html-details-summary.json";
import htmlProgressMeterEN from "../../lessons/24-html-progress-meter.json";
import htmlDatalistEN from "../../lessons/25-html-datalist.json";
import htmlDataAttributesEN from "../../lessons/26-html-data-attributes.json";
import htmlDialogEN from "../../lessons/27-html-dialog.json";
import htmlFormsFieldsetEN from "../../lessons/28-html-forms-fieldset.json";
import htmlFigureEN from "../../lessons/29-html-figure.json";
import htmlTablesEN from "../../lessons/30-html-tables.json";
import htmlMarqueeEN from "../../lessons/31-html-marquee.json";
import htmlSvgEN from "../../lessons/32-html-svg.json";
import flexboxEN from "../../lessons/flexbox.json";
// Module store
const moduleStore = [
htmlElementsConfig,
htmlFormsBasicConfig,
htmlFormsValidationConfig,
htmlDetailsSummaryConfig,
htmlProgressMeterConfig,
htmlDatalistConfig,
htmlDataAttributesConfig,
htmlDialogConfig,
htmlFormsFieldsetConfig,
htmlFigureConfig,
htmlTablesConfig,
htmlMarqueeConfig,
htmlSvgConfig,
boxModelConfig,
flexboxConfig,
responsiveConfig,
unitsVariablesConfig,
transitionsAnimationsConfig,
basicSelectorsConfig,
advancedSelectorsConfig,
tailwindConfig
// German lesson imports
import basicSelectorsDE from "../../lessons/de/00-basic-selectors.json";
import advancedSelectorsDE from "../../lessons/de/01-advanced-selectors.json";
import boxModelDE from "../../lessons/de/01-box-model.json";
import unitsVariablesDE from "../../lessons/de/05-units-variables.json";
import transitionsAnimationsDE from "../../lessons/de/06-transitions-animations.json";
import responsiveDE from "../../lessons/de/08-responsive.json";
import tailwindDE from "../../lessons/de/10-tailwind-basics.json";
import htmlElementsDE from "../../lessons/de/20-html-elements.json";
import htmlFormsBasicDE from "../../lessons/de/21-html-forms-basic.json";
import htmlFormsValidationDE from "../../lessons/de/22-html-forms-validation.json";
import htmlDetailsSummaryDE from "../../lessons/de/23-html-details-summary.json";
import htmlProgressMeterDE from "../../lessons/de/24-html-progress-meter.json";
import htmlDatalistDE from "../../lessons/de/25-html-datalist.json";
import htmlDataAttributesDE from "../../lessons/de/26-html-data-attributes.json";
import htmlDialogDE from "../../lessons/de/27-html-dialog.json";
import htmlFormsFieldsetDE from "../../lessons/de/28-html-forms-fieldset.json";
import htmlFigureDE from "../../lessons/de/29-html-figure.json";
import htmlTablesDE from "../../lessons/de/30-html-tables.json";
import htmlMarqueeDE from "../../lessons/de/31-html-marquee.json";
import htmlSvgDE from "../../lessons/de/32-html-svg.json";
import flexboxDE from "../../lessons/de/flexbox.json";
// English module store
const moduleStoreEN = [
htmlElementsEN,
htmlFormsBasicEN,
htmlFormsValidationEN,
htmlDetailsSummaryEN,
htmlProgressMeterEN,
htmlDatalistEN,
htmlDataAttributesEN,
htmlDialogEN,
htmlFormsFieldsetEN,
htmlFigureEN,
htmlTablesEN,
htmlMarqueeEN,
htmlSvgEN,
boxModelEN,
flexboxEN,
responsiveEN,
unitsVariablesEN,
transitionsAnimationsEN,
basicSelectorsEN,
advancedSelectorsEN,
tailwindEN
];
// German module store
const moduleStoreDE = [
htmlElementsDE,
htmlFormsBasicDE,
htmlFormsValidationDE,
htmlDetailsSummaryDE,
htmlProgressMeterDE,
htmlDatalistDE,
htmlDataAttributesDE,
htmlDialogDE,
htmlFormsFieldsetDE,
htmlFigureDE,
htmlTablesDE,
htmlMarqueeDE,
htmlSvgDE,
boxModelDE,
flexboxDE,
responsiveDE,
unitsVariablesDE,
transitionsAnimationsDE,
basicSelectorsDE,
advancedSelectorsDE,
tailwindDE
];
/**
* Load all available modules
* Load all available modules for a given language
* @param {string} language - Language code ('en' or 'de')
* @returns {Promise<Array>} Promise resolving to array of modules
*/
export async function loadModules() {
return moduleStore.map((module) => ({
export async function loadModules(language = "en") {
const store = language === "de" ? moduleStoreDE : moduleStoreEN;
return store.map((module) => ({
...module,
lessons: module.lessons.map((lesson) => ({
...lesson,
@@ -69,10 +118,12 @@ export async function loadModules() {
/**
* Get a module by its ID
* @param {string} moduleId - The module ID to find
* @param {string} language - Language code ('en' or 'de')
* @returns {Object|null} The module object or null if not found
*/
export function getModuleById(moduleId) {
return moduleStore.find((module) => module.id === moduleId) || null;
export function getModuleById(moduleId, language = "en") {
const store = language === "de" ? moduleStoreDE : moduleStoreEN;
return store.find((module) => module.id === moduleId) || null;
}
/**
@@ -118,20 +169,23 @@ function validateModuleConfig(config) {
/**
* Add a custom module to the store
* @param {Object} moduleConfig - The module configuration to add
* @param {string} language - Language code ('en' or 'de')
* @returns {boolean} Success status
*/
export function addCustomModule(moduleConfig) {
export function addCustomModule(moduleConfig, language = "en") {
try {
validateModuleConfig(moduleConfig);
const store = language === "de" ? moduleStoreDE : moduleStoreEN;
// Check if module with same ID already exists
const existingIndex = moduleStore.findIndex((m) => m.id === moduleConfig.id);
const existingIndex = store.findIndex((m) => m.id === moduleConfig.id);
if (existingIndex >= 0) {
// Replace existing module
moduleStore[existingIndex] = moduleConfig;
store[existingIndex] = moduleConfig;
} else {
// Add new module
moduleStore.push(moduleConfig);
store.push(moduleConfig);
}
return true;