diff --git a/lxc-frontend/app/static/app.js b/lxc-frontend/app/static/app.js index e7696c3..de71d24 100644 --- a/lxc-frontend/app/static/app.js +++ b/lxc-frontend/app/static/app.js @@ -34,10 +34,8 @@ const usersBody = document.getElementById("users-body"); const profileLabel = document.getElementById("profile-label"); const profileSelect = document.getElementById("profile-select"); const defaultProfileName = document.getElementById("default-profile-name"); -const settingsCard = document.getElementById("settings-card"); -const settingsForm = document.getElementById("settings-form"); -const settingsProfile = document.getElementById("settings-profile"); -const settingsMsg = document.getElementById("settings-msg"); +const headerProfileWrap = document.getElementById("header-profile-wrap"); +const headerProfile = document.getElementById("header-profile"); let currentUser = null; // { id, username, is_admin, default_profile } let mode = "login"; // "login" | "setup" @@ -146,12 +144,12 @@ function profileLabelOf(name) { } function applyProfileUI() { - // Upload-Dropdown nur sichtbar wenn ≥2 Profile zur Auswahl stehen. + // Upload-Dropdown und Header-Selector nur sichtbar wenn ≥2 Profile. const showDropdown = availableProfiles.length > 1; profileLabel.classList.toggle("hidden", !showDropdown); + headerProfileWrap.classList.toggle("hidden", !showDropdown); - // Beide Selects befüllen - for (const sel of [profileSelect, settingsProfile]) { + for (const sel of [profileSelect, headerProfile]) { sel.innerHTML = ""; availableProfiles.forEach((p) => { const o = document.createElement("option"); @@ -162,13 +160,32 @@ function applyProfileUI() { } const def = currentUser.default_profile || "meeting"; profileSelect.value = def; - settingsProfile.value = def; + headerProfile.value = def; defaultProfileName.textContent = profileLabelOf(def); - - // Settings-Karte nur, wenn es überhaupt was auszuwählen gibt. - settingsCard.classList.toggle("hidden", !showDropdown); } +// Sofort-Speichern, sobald der User im Header das Standard-Profil ändert. +headerProfile.addEventListener("change", async () => { + const newDefault = headerProfile.value; + headerProfile.disabled = true; + try { + const r = await api("/api/auth/me", { + method: "PATCH", + body: JSON.stringify({ default_profile: newDefault }), + }); + if (!r.ok) throw new Error("save failed"); + currentUser = await r.json(); + // Upload-Dropdown synchron mitziehen + profileSelect.value = currentUser.default_profile; + defaultProfileName.textContent = profileLabelOf(currentUser.default_profile); + } catch (e) { + alert("Konnte Standard-Profil nicht speichern."); + headerProfile.value = currentUser.default_profile || "meeting"; + } finally { + headerProfile.disabled = false; + } +}); + authForm.addEventListener("submit", async (ev) => { ev.preventDefault(); authSubmit.disabled = true; @@ -417,26 +434,6 @@ usersBody.addEventListener("click", async (ev) => { } }); -settingsForm.addEventListener("submit", async (ev) => { - ev.preventDefault(); - settingsMsg.textContent = ""; - settingsMsg.className = "msg"; - const r = await api("/api/auth/me", { - method: "PATCH", - body: JSON.stringify({ default_profile: settingsProfile.value }), - }); - const data = await r.json(); - if (!r.ok) { - settingsMsg.textContent = data.detail || "Speichern fehlgeschlagen"; - settingsMsg.className = "msg err"; - return; - } - currentUser = data; - applyProfileUI(); - settingsMsg.textContent = "Gespeichert."; - settingsMsg.className = "msg ok"; -}); - // ─── Init ────────────────────────────────────────────────────────────────── bootstrap(); checkMac(); diff --git a/lxc-frontend/app/static/index.html b/lxc-frontend/app/static/index.html index bf4fe5c..5a7cc6b 100644 --- a/lxc-frontend/app/static/index.html +++ b/lxc-frontend/app/static/index.html @@ -19,6 +19,11 @@ Angemeldet als + @@ -71,18 +76,6 @@

-
-

Meine Einstellungen

-
- - -
-

-
-

Jobs

diff --git a/lxc-frontend/app/static/style.css b/lxc-frontend/app/static/style.css index c727058..648115b 100644 --- a/lxc-frontend/app/static/style.css +++ b/lxc-frontend/app/static/style.css @@ -253,15 +253,6 @@ footer { text-align: center; padding: 24px 16px 32px; } .user-form { grid-template-columns: 1fr; } } -/* Settings-Form */ -.settings-form { - display: grid; - grid-template-columns: 1fr auto; - gap: 12px; - align-items: end; - max-width: 480px; -} - /* Select-Felder im selben Stil wie Inputs */ select { background: #0f1219; @@ -273,6 +264,23 @@ select { font-family: inherit; } +/* Kompakter Profil-Selector im Header */ +.header-profile-wrap { + display: inline-flex; + align-items: center; + gap: 6px; +} +.header-profile { + padding: 3px 6px; + font-size: 12px; + border-radius: 5px; + background: #0f1219; + border: 1px solid var(--border); + color: var(--text); + max-width: 180px; +} +.header-profile:disabled { opacity: .5; } + /* Profile-Tag in der Job-Zeile */ .tag-profile { display: inline-block;