feat(design): AegisSight-Design, Lucide-Icons und aufgeräumter Verbrauchs-Bereich

Drei Pakete auf Nutzerwunsch.

1. Design-Angleichung an das AegisSight-Design-System. Navy/Gold-Token
   statt Slate/Amber, Light- UND Dark-Theme mit goldenem Schiebeschalter
   oben rechts (Dark = Standard, Wahl persistiert), Barrierefreiheits-
   Panel über js/a11y.js (identische Datei wie im Monitor), echtes Logo
   mit heller Plakette in Kopfzeile und Login, Poppins/Inter-Typografie,
   Radius 6/8 nach Styleguide. Automatisch erzeugte Light-Theme-
   Überschreibungen für alle Badge-Pastelltöne.
2. Lucide-Icons (Inline-SVG, keine externen Quellen) für alle
   Navigations-Tabs inkl. nachgeladenem Verbrauchsrechner, die
   Anlege-Knöpfe, Abmelden und Speichern.
3. Verbrauchs-Bereich aufgeräumt. Reiter heißt jetzt Verbrauch,
   Statistik in Kundensicht (Credits) und Interne Kosten (Einkauf, USD)
   getrennt, Leiste heißt Kontingent-Auslastung, Sätze-Infozeile mit
   Sprung zum Verbrauchsrechner, Altmodus-Felder (USD) und die
   Verbrauchs-Korrektur liegen in einem eingeklappten Bereich
   Erweitert mit Erklärtext. Der Rechner trägt einen deutlichen
   Simulations-Hinweis. Lizenz verlängern nutzt ein eigenes Modal
   statt des Browser-prompt().

Cache-Buster auf 20260725 gebumpt, alle Restfarben tokenisiert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-07-25 13:57:59 +00:00
Ursprung eeb74c74c1
Commit 8fd087ea0c
7 geänderte Dateien mit 654 neuen und 80 gelöschten Zeilen

Datei anzeigen

@@ -45,6 +45,36 @@ const API = {
},
};
// --- Theme (Dark = Standard, Wahl bleibt in localStorage erhalten) ---
const ThemeManager = {
_key: "portal_theme",
init() {
const theme = localStorage.getItem(this._key) === "light" ? "light" : "dark";
this._apply(theme);
},
toggle() {
const next = document.documentElement.getAttribute("data-theme") === "light" ? "dark" : "light";
localStorage.setItem(this._key, next);
this._apply(next);
},
_apply(theme) {
if (theme === "light") document.documentElement.setAttribute("data-theme", "light");
else document.documentElement.removeAttribute("data-theme");
const el = document.getElementById("theme-toggle");
if (el) {
el.classList.remove("dark", "light");
el.classList.add(theme);
el.setAttribute("aria-checked", theme === "dark" ? "true" : "false");
}
},
};
// Sprung zum (nachgeladenen) Verbrauchsrechner-Tab
function openRechnerTab() {
const tab = document.querySelector('.nav-tab[data-section="rechner"]');
if (tab) tab.click();
}
// --- State ---
let currentOrgId = null;
let orgsCache = [];
@@ -53,6 +83,10 @@ let orgsCache = [];
document.addEventListener("DOMContentLoaded", () => {
if (!API.token) { window.location.href = "/"; return; }
ThemeManager.init();
// Barrierefreiheits-Panel (a11y.js, identische Datei wie im Monitor)
if (typeof A11yManager !== "undefined") A11yManager.init();
document.getElementById("headerUser").textContent = localStorage.getItem("username") || "";
document.getElementById("logoutBtn").addEventListener("click", logout);
@@ -368,17 +402,37 @@ async function loadOrgLicenses(orgId) {
}
}
async function extendLicense(licId) {
const days = prompt("Um wie viele Tage verlängern?", "365");
if (!days) return;
try {
await API.put(`/api/licenses/${licId}/extend?days=${parseInt(days)}`);
if (currentOrgId) loadOrgLicenses(currentOrgId);
} catch (err) {
showToast(err.message, "error");
}
// Lizenz verlängern über ein eigenes Modal statt des rohen Browser-prompt()
let _extendLicenseId = null;
function extendLicense(licId) {
_extendLicenseId = licId;
const errEl = document.getElementById("extendLicenseError");
if (errEl) errEl.style.display = "none";
openModal("modalExtendLicense");
const input = document.getElementById("extendDays");
if (input) { input.value = "365"; input.focus(); }
}
document.addEventListener("DOMContentLoaded", function () {
const form = document.getElementById("extendLicenseForm");
if (!form) return;
form.addEventListener("submit", async function (e) {
e.preventDefault();
const errEl = document.getElementById("extendLicenseError");
if (errEl) errEl.style.display = "none";
const days = parseInt(document.getElementById("extendDays").value);
if (!days || days < 1) return;
try {
await API.put(`/api/licenses/${_extendLicenseId}/extend?days=${days}`);
closeModal("modalExtendLicense");
if (currentOrgId) loadOrgLicenses(currentOrgId);
loadExpiringLicenses();
} catch (err) {
if (errEl) { errEl.textContent = err.message; errEl.style.display = "block"; }
}
});
});
function confirmRevokeLicense(licId) {
showConfirm(
"Lizenz widerrufen",
@@ -1169,6 +1223,6 @@ document.addEventListener("DOMContentLoaded", () => {
// --- Verbrauchsrechner nachladen (eigenstaendiges Modul, siehe rechner.js) ---
(function () {
var s = document.createElement("script");
s.src = "/static/js/rechner.js?v=20260724d";
s.src = "/static/js/rechner.js?v=20260725a";
document.head.appendChild(s);
})();