fix: add languageSelector function and translate icon for admin context
- Add languageSelector() function to admin init-alpine.js for use in language selector macros on admin components page - Add 'translate' icon to icons.js for language selector display 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -163,4 +163,57 @@ function data() {
|
|||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
currentPage: ''
|
currentPage: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
@@ -152,6 +152,7 @@ const Icons = {
|
|||||||
'view-grid-add': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 14v6m-3-3h6M6 10h2a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2zm10 0h2a2 2 0 002-2V6a2 2 0 00-2-2h-2a2 2 0 00-2 2v2a2 2 0 002 2zM6 20h2a2 2 0 002-2v-2a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2z"/></svg>`,
|
'view-grid-add': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 14v6m-3-3h6M6 10h2a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2zm10 0h2a2 2 0 002-2V6a2 2 0 00-2-2h-2a2 2 0 00-2 2v2a2 2 0 002 2zM6 20h2a2 2 0 002-2v-2a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2z"/></svg>`,
|
||||||
'code': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/></svg>`,
|
'code': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/></svg>`,
|
||||||
'template': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/></svg>`,
|
'template': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/></svg>`,
|
||||||
|
'translate': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/></svg>`,
|
||||||
'view-boards': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"/></svg>`,
|
'view-boards': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"/></svg>`,
|
||||||
'menu-alt-2': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"/></svg>`,
|
'menu-alt-2': `<svg class="{{classes}}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"/></svg>`,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user