/** Foodlinkk i18n — edit /static/i18n/nl.json and en.json to translate. */ window.I18n = (function () { var locale = 'nl'; var strings = {}; function t(key, fallback) { if (!key) return fallback || ''; var parts = String(key).split('.'); var o = strings; for (var i = 0; i < parts.length; i++) { if (o == null || typeof o !== 'object') return fallback != null ? fallback : key; o = o[parts[i]]; } return typeof o === 'string' ? o : (fallback != null ? fallback : key); } function applyDom() { document.querySelectorAll('[data-i18n]').forEach(function (el) { var k = el.getAttribute('data-i18n'); if (k) el.textContent = t(k); }); document.querySelectorAll('[data-i18n-placeholder]').forEach(function (el) { var k = el.getAttribute('data-i18n-placeholder'); if (k) el.placeholder = t(k); }); document.querySelectorAll('[data-i18n-title]').forEach(function (el) { var k = el.getAttribute('data-i18n-title'); if (k) el.title = t(k); }); document.documentElement.lang = locale; } async function loadBundle(loc) { var r = await fetch('/static/i18n/' + loc + '.json?v=2'); if (!r.ok) throw new Error('Locale ' + loc + ' not found'); strings = await r.json(); } async function setLocale(loc, persist) { if (persist == null) persist = true; locale = loc === 'en' ? 'en' : 'nl'; try { await loadBundle(locale); } catch (e) { if (locale !== 'nl') { locale = 'nl'; await loadBundle('nl'); } } localStorage.setItem('foodlinkk_locale', locale); applyDom(); window.dispatchEvent(new CustomEvent('foodlinkk:locale', { detail: { locale: locale } })); if (persist) { fetch('/api/preferences/ui', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ locale: locale }), }).catch(function () {}); } return locale; } async function init() { var loc = localStorage.getItem('foodlinkk_locale') || 'nl'; try { var prefs = await fetch('/api/preferences/ui').then(function (r) { return r.json(); }); if (prefs.locale) loc = prefs.locale; } catch (e) { /* ignore */ } await setLocale(loc, false); } return { t: t, init: init, setLocale: setLocale, locale: function () { return locale; }, applyDom: applyDom }; })(); document.addEventListener('alpine:init', function () { if (!window.Alpine) return; Alpine.magic('t', function () { return function (key, fallback) { return window.I18n.t(key, fallback); }; }); });