diff --git a/public/js/components/language-selector.js b/public/js/components/language-selector.js
index 7fda9f1e..33474c80 100644
--- a/public/js/components/language-selector.js
+++ b/public/js/components/language-selector.js
@@ -1,6 +1,7 @@
/**
* Language Selector Component
- * Creates a dropdown for switching between supported languages
+ * Mobile: Icon-only buttons (flags)
+ * Desktop: Dropdown with full language names
*/
(function() {
@@ -10,24 +11,22 @@
{ code: 'fr', name: 'Français', flag: '🇫🇷' },
{ code: 'mi', name: 'Te Reo Māori', flag: '🇳🇿', disabled: true, tooltip: 'Coming when system is complete' }
];
-
- function createLanguageSelector() {
- const container = document.getElementById('language-selector-container');
- if (!container) return;
-
- const currentLang = (window.I18n && window.I18n.currentLang) || 'en';
-
- const selectorHTML = `
-
-
-
`;
-
+ }
+
+ /**
+ * Create mobile icon-only selector
+ */
+ function createMobileSelector(currentLang) {
+ return `
+
+ ${supportedLanguages.filter(lang => !lang.disabled).map(lang => `
+
+ `).join('')}
+
+ `;
+ }
+
+ /**
+ * Create mobile menu language selector (inside drawer)
+ */
+ function createMobileMenuSelector(currentLang) {
+ const container = document.getElementById('mobile-menu-language-selector');
+ if (!container) return;
+
+ const selectorHTML = `
+
+
Language
+
+ ${supportedLanguages.map(lang => `
+
+ `).join('')}
+
+
+ `;
+
container.innerHTML = selectorHTML;
-
- // Add change event listener
- const selector = document.getElementById('language-selector');
- if (selector && window.I18n) {
- selector.addEventListener('change', function(e) {
+
+ // Attach event listeners for mobile menu buttons
+ document.querySelectorAll('.mobile-menu-lang-btn').forEach(btn => {
+ if (!btn.disabled) {
+ btn.addEventListener('click', function(e) {
+ const selectedLang = this.getAttribute('data-lang');
+ if (window.I18n && selectedLang) {
+ window.I18n.setLanguage(selectedLang);
+ // Close mobile menu after selection
+ const mobileMenu = document.getElementById('mobile-menu');
+ if (mobileMenu) {
+ mobileMenu.classList.add('hidden');
+ document.body.style.overflow = '';
+ }
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Initialize language selector
+ */
+ function createLanguageSelector() {
+ const container = document.getElementById('language-selector-container');
+ if (!container) return;
+
+ const currentLang = (window.I18n && window.I18n.currentLang) || 'en';
+
+ // Create both mobile and desktop versions
+ const combinedHTML = createMobileSelector(currentLang) + createDesktopSelector(currentLang);
+ container.innerHTML = combinedHTML;
+
+ // Attach event listener for desktop dropdown
+ const desktopDropdown = document.getElementById('language-selector-dropdown');
+ if (desktopDropdown && window.I18n) {
+ desktopDropdown.addEventListener('change', function(e) {
const selectedLang = e.target.value;
window.I18n.setLanguage(selectedLang);
});
}
+
+ // Attach event listeners for mobile icon buttons
+ document.querySelectorAll('.language-btn').forEach(btn => {
+ btn.addEventListener('click', function(e) {
+ const selectedLang = this.getAttribute('data-lang');
+ if (window.I18n && selectedLang) {
+ window.I18n.setLanguage(selectedLang);
+ }
+ });
+ });
+
+ // Initialize mobile menu language selector (if container exists)
+ createMobileMenuSelector(currentLang);
}
-
+
+ /**
+ * Update UI when language changes
+ */
+ function updateLanguageUI(newLang) {
+ // Update mobile icon buttons
+ document.querySelectorAll('.language-btn').forEach(btn => {
+ const lang = btn.getAttribute('data-lang');
+ if (lang === newLang) {
+ btn.classList.add('bg-blue-100', 'ring-2', 'ring-blue-500');
+ btn.classList.remove('bg-white', 'border', 'border-gray-300');
+ btn.setAttribute('aria-pressed', 'true');
+ } else {
+ btn.classList.remove('bg-blue-100', 'ring-2', 'ring-blue-500');
+ btn.classList.add('bg-white', 'border', 'border-gray-300');
+ btn.setAttribute('aria-pressed', 'false');
+ }
+ });
+
+ // Update desktop dropdown
+ const dropdown = document.getElementById('language-selector-dropdown');
+ if (dropdown) {
+ dropdown.value = newLang;
+ }
+
+ // Update mobile menu buttons
+ document.querySelectorAll('.mobile-menu-lang-btn').forEach(btn => {
+ const lang = btn.getAttribute('data-lang');
+ if (lang === newLang) {
+ btn.classList.add('bg-blue-50', 'text-blue-700');
+ btn.classList.remove('text-gray-700', 'hover:bg-gray-50');
+ } else {
+ btn.classList.remove('bg-blue-50', 'text-blue-700');
+ btn.classList.add('text-gray-700', 'hover:bg-gray-50');
+ }
+ });
+ }
+
+ // Listen for language change events
+ window.addEventListener('languageChanged', function(e) {
+ if (e.detail && e.detail.language) {
+ updateLanguageUI(e.detail.language);
+ }
+ });
+
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', createLanguageSelector);
} else {
createLanguageSelector();
}
+
+ // Re-initialize when mobile menu is rendered (if needed)
+ window.addEventListener('mobileMenuRendered', createLanguageSelector);
+
})();
diff --git a/public/js/components/navbar.js b/public/js/components/navbar.js
index b00e700f..2db5d175 100644
--- a/public/js/components/navbar.js
+++ b/public/js/components/navbar.js
@@ -71,6 +71,9 @@ class TractatusNavbar {