diff --git a/static/admin/js/init-alpine.js b/static/admin/js/init-alpine.js index 5c75e35b..80af7f4d 100644 --- a/static/admin/js/init-alpine.js +++ b/static/admin/js/init-alpine.js @@ -163,4 +163,57 @@ function data() { // ───────────────────────────────────────────────────────────────── currentPage: '' } -} \ No newline at end of file +} + +/** + * Language selector component for i18n support + * Used by language_selector macros in templates + * + * @param {string} currentLang - Current language code (e.g., 'fr') + * @param {Array} enabledLanguages - Array of enabled language codes + * @returns {Object} Alpine.js component data + */ +function languageSelector(currentLang, enabledLanguages) { + return { + isLangOpen: false, + currentLang: currentLang || 'fr', + languages: enabledLanguages || ['fr', 'de', 'en'], + languageNames: { + 'en': 'English', + 'fr': 'Français', + 'de': 'Deutsch', + 'lb': 'Lëtzebuergesch' + }, + languageFlags: { + 'en': 'gb', + 'fr': 'fr', + 'de': 'de', + 'lb': 'lu' + }, + async setLanguage(lang) { + if (lang === this.currentLang) { + this.isLangOpen = false; + return; + } + try { + const response = await fetch('/api/v1/language/set', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ language: lang }) + }); + if (response.ok) { + this.currentLang = lang; + window.location.reload(); + } + } catch (error) { + console.error('Failed to set language:', error); + } + this.isLangOpen = false; + } + }; +} + +// Export to window for use in templates +window.languageSelector = languageSelector; \ No newline at end of file diff --git a/static/shared/js/icons.js b/static/shared/js/icons.js index 076e585a..c8094100 100644 --- a/static/shared/js/icons.js +++ b/static/shared/js/icons.js @@ -152,6 +152,7 @@ const Icons = { 'view-grid-add': ``, 'code': ``, 'template': ``, + 'translate': ``, 'view-boards': ``, 'menu-alt-2': ``,