com
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
// public/assets/js/lang-usbcheck.js
|
// public/assets/js/lang.js
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
const translations = {
|
const translations = {
|
||||||
de: {
|
de: {
|
||||||
|
|
||||||
header_slogan: "USB-Sticks testen",
|
header_slogan: "USB-Sticks testen",
|
||||||
btn_login: "Login",
|
btn_login: "Login",
|
||||||
|
|
||||||
@@ -15,9 +14,11 @@
|
|||||||
|
|
||||||
footer_imprint: "Impressum",
|
footer_imprint: "Impressum",
|
||||||
footer_privacy: "Datenschutz",
|
footer_privacy: "Datenschutz",
|
||||||
|
|
||||||
brand_wordmark: "usbcheck.it",
|
brand_wordmark: "usbcheck.it",
|
||||||
brand_subtitle: "USB-Sticks auf Fakes testen",
|
brand_subtitle: "USB-Sticks auf Fakes testen",
|
||||||
btn_login: "Login",
|
// btn_login oben bereits definiert, diese Zeile könnte theoretisch entfallen
|
||||||
|
// btn_login: "Login",
|
||||||
|
|
||||||
nav_how: "Wie es funktioniert",
|
nav_how: "Wie es funktioniert",
|
||||||
nav_problem: "Warum es wichtig ist",
|
nav_problem: "Warum es wichtig ist",
|
||||||
@@ -141,9 +142,10 @@
|
|||||||
|
|
||||||
footer_imprint: "Imprint",
|
footer_imprint: "Imprint",
|
||||||
footer_privacy: "Privacy policy",
|
footer_privacy: "Privacy policy",
|
||||||
|
|
||||||
brand_wordmark: "usbcheck.it",
|
brand_wordmark: "usbcheck.it",
|
||||||
brand_subtitle: "Test USB drives for fakes",
|
brand_subtitle: "Test USB drives for fakes",
|
||||||
btn_login: "Login",
|
// btn_login oben bereits gesetzt
|
||||||
|
|
||||||
nav_how: "How it works",
|
nav_how: "How it works",
|
||||||
nav_problem: "Why it matters",
|
nav_problem: "Why it matters",
|
||||||
@@ -231,6 +233,7 @@
|
|||||||
security_kicker: "Security & privacy",
|
security_kicker: "Security & privacy",
|
||||||
security_title: "Privacy-first design: your test data is yours.",
|
security_title: "Privacy-first design: your test data is yours.",
|
||||||
security_intro: "USBCheck was designed from day one to protect your data. The browser quick test only works with test files. Your own documents, photos and backups are never read or uploaded. In Pro mode you decide if and which reports are synced to your account.",
|
security_intro: "USBCheck was designed from day one to protect your data. The browser quick test only works with test files. Your own documents, photos and backups are never read or uploaded. In Pro mode you decide if and which reports are synced to your account.",
|
||||||
|
|
||||||
security_card1_title: "Local-only tests",
|
security_card1_title: "Local-only tests",
|
||||||
security_card1_text: "All write and read tests run locally on your USB drive. The browser only accesses test files – not your private content.",
|
security_card1_text: "All write and read tests run locally on your USB drive. The browser only accesses test files – not your private content.",
|
||||||
security_card2_title: "Transparent reports",
|
security_card2_title: "Transparent reports",
|
||||||
@@ -268,9 +271,10 @@
|
|||||||
|
|
||||||
footer_imprint: "Imprint",
|
footer_imprint: "Imprint",
|
||||||
footer_privacy: "Privacy",
|
footer_privacy: "Privacy",
|
||||||
|
|
||||||
brand_wordmark: "usbcheck.it",
|
brand_wordmark: "usbcheck.it",
|
||||||
brand_subtitle: "Controlla le chiavette USB contraffatte",
|
brand_subtitle: "Controlla le chiavette USB contraffatte",
|
||||||
btn_login: "Login",
|
// btn_login: "Login",
|
||||||
|
|
||||||
nav_how: "Come funziona",
|
nav_how: "Come funziona",
|
||||||
nav_problem: "Perché è importante",
|
nav_problem: "Perché è importante",
|
||||||
@@ -396,9 +400,10 @@
|
|||||||
|
|
||||||
footer_imprint: "Mentions légales",
|
footer_imprint: "Mentions légales",
|
||||||
footer_privacy: "Confidentialité",
|
footer_privacy: "Confidentialité",
|
||||||
|
|
||||||
brand_wordmark: "usbcheck.it",
|
brand_wordmark: "usbcheck.it",
|
||||||
brand_subtitle: "Tester les clés USB contrefaites",
|
brand_subtitle: "Tester les clés USB contrefaites",
|
||||||
btn_login: "Connexion",
|
// btn_login: "Connexion",
|
||||||
|
|
||||||
nav_how: "Fonctionnement",
|
nav_how: "Fonctionnement",
|
||||||
nav_problem: "Pourquoi c’est important",
|
nav_problem: "Pourquoi c’est important",
|
||||||
@@ -558,6 +563,12 @@
|
|||||||
localStorage.setItem('usbcheck_lang', lang);
|
localStorage.setItem('usbcheck_lang', lang);
|
||||||
applyTranslations(lang);
|
applyTranslations(lang);
|
||||||
|
|
||||||
|
// Button-Label im Header aktualisieren
|
||||||
|
const currentLabel = document.getElementById('langCurrentLabel') || document.getElementById('langCurrent');
|
||||||
|
if (currentLabel) {
|
||||||
|
currentLabel.textContent = lang.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
// Optional: URL-Parameter aktualisieren (ohne Reload)
|
// Optional: URL-Parameter aktualisieren (ohne Reload)
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
url.searchParams.set('lang', lang);
|
url.searchParams.set('lang', lang);
|
||||||
@@ -568,7 +579,49 @@
|
|||||||
const initialLang = getInitialLang();
|
const initialLang = getInitialLang();
|
||||||
applyTranslations(initialLang);
|
applyTranslations(initialLang);
|
||||||
|
|
||||||
// Sprachumschaltung
|
// --- Dropdown-Elemente im Header holen ---
|
||||||
|
const langCurrent = document.getElementById('langCurrent');
|
||||||
|
const langCurrentLabel = document.getElementById('langCurrentLabel');
|
||||||
|
const langMenu = document.getElementById('langMenu');
|
||||||
|
|
||||||
|
// aktuelles Label für den Header-Button setzen
|
||||||
|
if (langCurrentLabel) {
|
||||||
|
langCurrentLabel.textContent = initialLang.toUpperCase();
|
||||||
|
} else if (langCurrent) {
|
||||||
|
langCurrent.textContent = initialLang.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dropdown-Logik für Sprachauswahl
|
||||||
|
if (langCurrent && langMenu) {
|
||||||
|
// Toggle Menü bei Klick auf den Button
|
||||||
|
langCurrent.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
langMenu.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Menü schließen bei Klick außerhalb
|
||||||
|
document.addEventListener('click', function (e) {
|
||||||
|
if (!langMenu.classList.contains('hidden')) {
|
||||||
|
if (
|
||||||
|
!langMenu.contains(e.target) &&
|
||||||
|
e.target !== langCurrent &&
|
||||||
|
!langCurrent.contains(e.target)
|
||||||
|
) {
|
||||||
|
langMenu.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Menü schließen, wenn eine Sprache gewählt wurde
|
||||||
|
langMenu.addEventListener('click', function (e) {
|
||||||
|
const pill = e.target.closest('.lang-pill');
|
||||||
|
if (pill) {
|
||||||
|
langMenu.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprachumschaltung (Click auf .lang-pill → Sprache setzen)
|
||||||
document.addEventListener('click', function (e) {
|
document.addEventListener('click', function (e) {
|
||||||
const btn = e.target.closest('.lang-pill');
|
const btn = e.target.closest('.lang-pill');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
|
|||||||
@@ -30,34 +30,44 @@
|
|||||||
<a href="#faq" class="hover:text-brand-primary transition-colors" data-i18n="nav_faq"></a>
|
<a href="#faq" class="hover:text-brand-primary transition-colors" data-i18n="nav_faq"></a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Language Switch: inline pills -->
|
<!-- Language Switch: Button + Dropdown mit Kürzeln -->
|
||||||
<div class="flex items-center gap-1 sm:gap-1.5 text-[11px] sm:text-xs font-medium uppercase tracking-[0.18em]">
|
<div class="relative">
|
||||||
|
<button id="langCurrent"
|
||||||
|
type="button"
|
||||||
|
class="flex items-center gap-1 text-xs uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary transition">
|
||||||
|
<span id="langCurrentLabel"><?= strtoupper($lang) ?></span>
|
||||||
|
<svg class="w-3 h-3 opacity-70" viewBox="0 0 20 20" aria-hidden="true">
|
||||||
|
<path d="M5 7l5 6 5-6" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div id="langMenu"
|
||||||
|
class="hidden absolute right-0 mt-2 w-20 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="lang-pill px-1.5 py-0.5 rounded-full border border-transparent text-brand-muted hover:text-brand-primary hover:border-brand-border transition"
|
class="lang-pill block w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||||
data-lang="de">
|
data-lang="de">
|
||||||
DE
|
DE
|
||||||
</button>
|
</button>
|
||||||
<span class="text-brand-border/60">·</span>
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="lang-pill px-1.5 py-0.5 rounded-full border border-transparent text-brand-muted hover:text-brand-primary hover:border-brand-border transition"
|
class="lang-pill block w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||||
data-lang="en">
|
data-lang="en">
|
||||||
EN2
|
EN
|
||||||
</button>
|
</button>
|
||||||
<span class="text-brand-border/60">·</span>
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="lang-pill px-1.5 py-0.5 rounded-full border border-transparent text-brand-muted hover:text-brand-primary hover:border-brand-border transition"
|
class="lang-pill block w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||||
data-lang="it">
|
data-lang="it">
|
||||||
IT
|
IT
|
||||||
</button>
|
</button>
|
||||||
<span class="text-brand-border/60">·</span>
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="lang-pill px-1.5 py-0.5 rounded-full border border-transparent text-brand-muted hover:text-brand-primary hover:border-brand-border transition"
|
class="lang-pill block w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||||
data-lang="fr">
|
data-lang="fr">
|
||||||
FR
|
FR
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Login Button / Avatar -->
|
<!-- Login Button / Avatar -->
|
||||||
<button id="loginButton"
|
<button id="loginButton"
|
||||||
class="relative inline-flex items-center justify-center rounded-full bg-brand-primary px-4 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-brand-bg shadow-soft hover:bg-cyan-400 transition-colors"
|
class="relative inline-flex items-center justify-center rounded-full bg-brand-primary px-4 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-brand-bg shadow-soft hover:bg-cyan-400 transition-colors"
|
||||||
|
|||||||
Reference in New Issue
Block a user