// public/assets/js/lang.js (function () { const supportedLangs = ["de", "en", "it", "fr"]; let currentLang = "en"; let translations = {}; const langMeta = { de: { flag: "🇩🇪", label: "DE" }, en: { flag: "🇬🇧", label: "EN" }, it: { flag: "🇮🇹", label: "IT" }, fr: { flag: "🇫🇷", label: "FR" } }; // 🔹 WICHTIG: // Diese Funktion nimmt eine verschachtelte JSON-Struktur // und schreibt ALLE "Blatt-Keys" in ein flaches Objekt, // OHNE den Pfad in den Keynamen einzubauen. // D.h. { "hero": { "hero_kicker": "..." } } -> { "hero_kicker": "..." } function flattenTranslations(obj, target = {}) { Object.keys(obj || {}).forEach((key) => { const val = obj[key]; if (val && typeof val === "object" && !Array.isArray(val)) { flattenTranslations(val, target); } else { target[key] = val; } }); return target; } function applyDomainPlaceholders(text) { if (typeof text !== "string") return text; const domains = window.appDomains || {}; const replacements = { "{{primary_domain}}": domains.primaryDomain || "usbcheck.it", "{{primary_url}}": domains.primaryUrl || ("https://" + (domains.primaryDomain || "usbcheck.it")), "{{fakecheck_domain}}": domains.fakecheckDomain || "ismyusbfake.com", "{{fakecheck_url}}": domains.fakecheckUrl || ("https://" + (domains.fakecheckDomain || "ismyusbfake.com")), }; return Object.keys(replacements).reduce((acc, token) => { const value = replacements[token]; return acc.split(token).join(value); }, text); } function getInitialLang() { const urlParams = new URLSearchParams(window.location.search); const paramLang = urlParams.get("lang"); if (paramLang && supportedLangs.includes(paramLang)) return paramLang; const stored = localStorage.getItem("usbcheck_lang"); if (stored && supportedLangs.includes(stored)) return stored; const navLang = (navigator.language || navigator.userLanguage || "en") .slice(0, 2) .toLowerCase(); if (supportedLangs.includes(navLang)) return navLang; return "en"; } async function loadLangFile(lang) { try { const res = await fetch(`/assets/i18n/${lang}.json`, { cache: "no-store" }); if (!res.ok) throw new Error(`Failed to load /assets/i18n/${lang}.json`); const raw = await res.json(); translations = flattenTranslations(raw); // 👈 hier wird strukturiert -> flach gemacht } catch (err) { console.error("i18n load error:", err); translations = {}; } } function applyTranslations() { document.documentElement.setAttribute("lang", currentLang); document.querySelectorAll("[data-i18n]").forEach((node) => { const key = node.getAttribute("data-i18n"); if (!key) return; let value = translations[key]; if (typeof value !== "string") return; // {year}-Platzhalter ersetzen (z. B. footer_copy) if (value.includes("{year}")) { const year = new Date().getFullYear(); value = value.replace("{year}", year); } value = applyDomainPlaceholders(value); node.innerHTML = value; }); } function updateLangCurrentLabel(lang) { const meta = langMeta[lang] || { flag: "", label: lang.toUpperCase() }; const node = document.getElementById("langCurrentLabel") || document.getElementById("langCurrent"); if (!node) return; if (meta.flag) { node.innerHTML = `${meta.flag}${meta.label}`; } else { node.textContent = meta.label; } } async function setLang(lang) { if (!supportedLangs.includes(lang)) return; currentLang = lang; localStorage.setItem("usbcheck_lang", lang); const url = new URL(window.location.href); url.searchParams.set("lang", lang); window.history.replaceState({}, "", url.toString()); await loadLangFile(lang); applyTranslations(); updateLangCurrentLabel(lang); } document.addEventListener("DOMContentLoaded", async function () { currentLang = getInitialLang(); updateLangCurrentLabel(currentLang); await loadLangFile(currentLang); applyTranslations(); const langCurrent = document.getElementById("langCurrent"); const langMenu = document.getElementById("langMenu"); if (langCurrent && langMenu) { langCurrent.addEventListener("click", function (e) { e.stopPropagation(); langMenu.classList.toggle("hidden"); }); document.addEventListener("click", function (e) { if (!langMenu.classList.contains("hidden")) { if (!langMenu.contains(e.target) && !langCurrent.contains(e.target)) { langMenu.classList.add("hidden"); } } }); langMenu.addEventListener("click", function (e) { const pill = e.target.closest(".lang-pill"); if (pill) { langMenu.classList.add("hidden"); } }); } // Sprachumschaltung über .lang-pill document.addEventListener("click", function (e) { const btn = e.target.closest(".lang-pill"); if (btn) { const lang = btn.getAttribute("data-lang"); setLang(lang); } }); // Login / Avatar – Dummy const loginButton = document.getElementById("loginButton"); const userAvatar = document.getElementById("userAvatar"); const avatarInitials = document.getElementById("avatarInitials"); if (loginButton && userAvatar) { loginButton.addEventListener("click", function () { loginButton.classList.add("hidden"); userAvatar.classList.remove("hidden"); if (avatarInitials && !avatarInitials.textContent.trim()) { avatarInitials.textContent = "UC"; } }); userAvatar.addEventListener("click", function () { alert("Account-Menü Platzhalter – hier später Profil/Logout etc. einbauen."); }); } }); })();