diff --git a/public/components/oikos-locale-picker.js b/public/components/oikos-locale-picker.js new file mode 100644 index 0000000..bc9d411 --- /dev/null +++ b/public/components/oikos-locale-picker.js @@ -0,0 +1,80 @@ +/** + * oikos-locale-picker — Sprachauswahl-Web-Component + * Zeigt Radio-Buttons für System/Deutsch/English. + * Bei Auswahl: setLocale() oder localStorage-Eintrag löschen (System). + * Dependencies: i18n.js + */ + +import { t, setLocale, getLocale, getSupportedLocales } from '/i18n.js'; + +const LOCALE_LABELS = { + de: 'Deutsch', + en: 'English', +}; + +class OikosLocalePicker extends HTMLElement { + connectedCallback() { + this._render(); + this._onLocaleChanged = () => this._render(); + window.addEventListener('locale-changed', this._onLocaleChanged); + } + + disconnectedCallback() { + window.removeEventListener('locale-changed', this._onLocaleChanged); + } + + _render() { + this.textContent = ''; + + const stored = localStorage.getItem('oikos-locale'); + + const wrapper = document.createElement('div'); + wrapper.className = 'locale-picker'; + + // System-Option + const systemOption = this._createOption( + 'system', + t('settings.localeSystem'), + !stored, + () => { + localStorage.removeItem('oikos-locale'); + location.reload(); + } + ); + wrapper.appendChild(systemOption); + + // Sprach-Optionen + for (const locale of getSupportedLocales()) { + const option = this._createOption( + locale, + LOCALE_LABELS[locale] || locale, + stored === locale, + () => setLocale(locale) + ); + wrapper.appendChild(option); + } + + this.appendChild(wrapper); + } + + _createOption(value, label, checked, onChange) { + const item = document.createElement('label'); + item.className = 'locale-picker__option'; + + const radio = document.createElement('input'); + radio.type = 'radio'; + radio.name = 'locale'; + radio.value = value; + radio.checked = checked; + radio.addEventListener('change', onChange); + + const span = document.createElement('span'); + span.textContent = label; + + item.appendChild(radio); + item.appendChild(span); + return item; + } +} + +customElements.define('oikos-locale-picker', OikosLocalePicker); diff --git a/public/locales/de.json b/public/locales/de.json index 28ef092..c80f640 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -508,7 +508,9 @@ "logout": "Abmelden", "synchronizing": "Synchronisiere…", "googleDisconnectConfirm": "Google Calendar-Verbindung trennen?", - "appleDisconnectConfirm": "Apple Calendar-Verbindung trennen?" + "appleDisconnectConfirm": "Apple Calendar-Verbindung trennen?", + "localeSystem": "System", + "languageTitle": "Sprache" }, "login": { diff --git a/public/locales/en.json b/public/locales/en.json index c33f4a4..d2f94a0 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -508,7 +508,9 @@ "logout": "Log out", "synchronizing": "Syncing…", "googleDisconnectConfirm": "Disconnect Google Calendar?", - "appleDisconnectConfirm": "Disconnect Apple Calendar?" + "appleDisconnectConfirm": "Disconnect Apple Calendar?", + "localeSystem": "System", + "languageTitle": "Language" }, "login": { diff --git a/public/pages/settings.js b/public/pages/settings.js index 03a15d5..e47f380 100644 --- a/public/pages/settings.js +++ b/public/pages/settings.js @@ -6,6 +6,7 @@ import { api, auth } from '/api.js'; import { t, formatDate, formatTime } from '/i18n.js'; +import '/components/oikos-locale-picker.js'; /** * @param {HTMLElement} container @@ -74,6 +75,14 @@ export async function render(container, { user }) { + +
+

${t('settings.languageTitle')}

+
+ +
+
+

${t('settings.sectionAccount')}