feat(admin): replace checkbox with toggle-switch slider, add i18n multilanguage

This commit is contained in:
Lago
2026-04-18 00:01:03 +02:00
parent c5fa51ce63
commit 1820f7d766
4 changed files with 212 additions and 56 deletions
+27 -10
View File
@@ -1,4 +1,5 @@
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.4";
import { getLang, setLang, t, applyI18n } from "./i18n.js";
const SUPA_URL = window.MCCARS_CONFIG?.SUPABASE_URL ?? "";
const SUPA_KEY = window.MCCARS_CONFIG?.SUPABASE_ANON_KEY || "";
@@ -12,6 +13,7 @@ const supabase = createClient(SUPA_URL, SUPA_KEY, {
// ----- DOM -----
const loginView = document.querySelector("#loginView");
const adminView = document.querySelector("#adminView");
const langToggle = document.querySelector(".lang-toggle");
const rotateView = document.querySelector("#rotateView");
const loginForm = document.querySelector("#loginForm");
const loginError = document.querySelector("#loginError");
@@ -59,6 +61,7 @@ const state = {
// AUTH FLOW
// =========================================================================
async function bootstrap() {
applyI18n();
const { data: { session } } = await supabase.auth.getSession();
if (session) {
// Always fetch fresh user from server so metadata (must_change_password) is current.
@@ -204,8 +207,8 @@ function renderVehicles() {
<td>€ ${v.daily_price_eur}</td>
<td>${v.is_active ? "✅" : "—"}</td>
<td style="white-space:nowrap;">
<button class="btn small ghost" data-edit="${v.id}">Edit</button>
<button class="btn small danger" data-del="${v.id}">Del</button>
<button class="btn small ghost" data-edit="${v.id}">${t("editVehicle")}</button>
<button class="btn small danger" data-del="${v.id}">${t("adminDel")}</button>
</td>`;
tableBody.appendChild(tr);
}
@@ -352,12 +355,12 @@ function renderLeads() {
<td>${esc(l.date_from || "—")}${esc(l.date_to || "—")}</td>
<td><span class="pill pill-${esc(l.status)}">${esc(l.status)}</span></td>
<td style="white-space:nowrap;">
<button class="btn small ghost" data-open="${l.id}">Details</button>
<button class="btn small ghost" data-open="${l.id}">${t("adminDetails")}</button>
${wantActive ? `
<button class="btn small" data-qual="${l.id}">Qualifizieren</button>
<button class="btn small danger" data-disq="${l.id}">Ablehnen</button>
<button class="btn small" data-qual="${l.id}">${t("adminQualify")}</button>
<button class="btn small danger" data-disq="${l.id}">${t("adminReject")}</button>
` : `
<button class="btn small ghost" data-reopen="${l.id}">Wieder oeffnen</button>
<button class="btn small ghost" data-reopen="${l.id}">${t("adminReopen")}</button>
`}
</td>`;
leadsTableBody.appendChild(tr);
@@ -385,9 +388,9 @@ function openLead(id) {
</dl>
<div style="display:flex;gap:0.5rem;justify-content:flex-end;margin-top:0.8rem;">
${l.is_active ? `
<button class="btn danger" id="dlgDisq">Ablehnen</button>
<button class="btn" id="dlgQual">Qualifizieren</button>
` : `<button class="btn ghost" id="dlgReopen">Wieder oeffnen</button>`}
<button class="btn danger" id="dlgDisq">${t("adminReject")}</button>
<button class="btn" id="dlgQual">${t("adminQualify")}</button>
` : `<button class="btn ghost" id="dlgReopen">${t("adminReopen")}</button>`}
</div>`;
leadDialog.showModal();
const note = () => document.querySelector("#leadNote").value;
@@ -448,7 +451,7 @@ function renderCustomers() {
<td><span class="pill pill-${esc(c.status)}">${esc(c.status)}</span></td>
<td style="white-space:nowrap;">
<button class="btn small ghost" data-toggle="${c.id}" data-status="${c.status}">
${c.status === "active" ? "Inaktiv setzen" : "Aktiv setzen"}
${c.status === "active" ? t("adminSetInactive") : t("adminSetActive")}
</button>
</td>`;
customersTableBody.appendChild(tr);
@@ -493,4 +496,18 @@ function fmtDate(iso) {
return d.toLocaleString("de-AT", { dateStyle: "short", timeStyle: "short" });
}
if (langToggle) {
langToggle.addEventListener("click", () => {
const current = getLang();
setLang(current === "de" ? "en" : "de");
langToggle.textContent = getLang() === "de" ? "EN" : "DE";
applyI18n();
// Re-render JS injected text correctly
if (state.vehicles) renderVehicles();
if (state.leads) renderLeads();
if (state.customers) renderCustomers();
});
langToggle.textContent = getLang() === "de" ? "EN" : "DE";
}
bootstrap();