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:
@@ -6,32 +6,63 @@
|
||||
<title>AegisSight Monitor-Verwaltung</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
|
||||
<link rel="apple-touch-icon" href="/static/favicon.svg">
|
||||
<link rel="stylesheet" href="/static/css/style.css?v=20260509d">
|
||||
<link rel="stylesheet" href="/static/css/style.css?v=20260725a">
|
||||
<script>(function(){var t=localStorage.getItem('portal_theme');if(t==='light')document.documentElement.setAttribute('data-theme','light');try{var a=JSON.parse(localStorage.getItem('osint_a11y')||'{}');Object.keys(a).forEach(function(k){if(a[k])document.documentElement.setAttribute('data-a11y-'+k,'true');});}catch(e){}})()</script>
|
||||
|
||||
<style>
|
||||
.source-badge { display:inline-block; padding:2px 8px; border-radius:4px; font-size:12px; font-weight:600; }
|
||||
.badge-monitor { background:#e3f2fd; color:#1565c0; }
|
||||
.badge-globe { background:#e8f5e9; color:#2e7d32; }
|
||||
.badge-monitor { background:rgba(59,130,246,0.15); color:#93c5fd; }
|
||||
.badge-globe { background:rgba(16,185,129,0.15); color:#86efac; }
|
||||
[data-theme="light"] .badge-monitor { background:#e3f2fd; color:#1565c0; }
|
||||
[data-theme="light"] .badge-globe { background:#e8f5e9; color:#2e7d32; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<header class="app-header">
|
||||
<div class="logo">AegisSight <span>Monitor-Verwaltung</span></div>
|
||||
<div class="logo">
|
||||
<span class="logo-plaque"><img src="/static/favicon.svg" alt="AegisSight Logo"></span>
|
||||
AegisSight <span>Monitor-Verwaltung</span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-switch dark" id="theme-toggle" onclick="ThemeManager.toggle()" role="switch" aria-checked="true" aria-label="Dark Mode" title="Theme wechseln">
|
||||
<span class="theme-switch-icon theme-switch-sun">☀︎</span>
|
||||
<div class="theme-switch-track">
|
||||
<div class="theme-switch-knob"></div>
|
||||
</div>
|
||||
<span class="theme-switch-icon theme-switch-moon">☽</span>
|
||||
</div>
|
||||
<span class="header-user" id="headerUser"></span>
|
||||
<button class="btn btn-secondary btn-small" id="logoutBtn">Abmelden</button>
|
||||
<button class="btn btn-secondary btn-small" id="logoutBtn">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
|
||||
Abmelden
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="app-content">
|
||||
<!-- Navigation -->
|
||||
<!-- Navigation (Lucide-Icons, Strichstaerke 2 bei 15px) -->
|
||||
<nav class="nav-tabs">
|
||||
<button class="nav-tab active" data-section="dashboard">Dashboard</button>
|
||||
<button class="nav-tab" data-section="orgs">Organisationen</button>
|
||||
<button class="nav-tab" data-section="licenses">Lizenzen</button>
|
||||
<button class="nav-tab" data-section="sources">Quellen</button>
|
||||
<button class="nav-tab" data-section="audit">Audit-Log</button>
|
||||
<button class="nav-tab active" data-section="dashboard">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></svg>
|
||||
Dashboard
|
||||
</button>
|
||||
<button class="nav-tab" data-section="orgs">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/><path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/><path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/><path d="M10 6h4"/><path d="M10 10h4"/><path d="M10 14h4"/><path d="M10 18h4"/></svg>
|
||||
Organisationen
|
||||
</button>
|
||||
<button class="nav-tab" data-section="licenses">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 18v3c0 .6.4 1 1 1h4v-3h3v-3h2l1.4-1.4a6.5 6.5 0 1 0-4-4Z"/><circle cx="16.5" cy="7.5" r=".5"/></svg>
|
||||
Lizenzen
|
||||
</button>
|
||||
<button class="nav-tab" data-section="sources">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></svg>
|
||||
Quellen
|
||||
</button>
|
||||
<button class="nav-tab" data-section="audit">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>
|
||||
Audit-Log
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<!-- Dashboard Section -->
|
||||
@@ -93,7 +124,7 @@
|
||||
<div id="orgListView">
|
||||
<div class="action-bar">
|
||||
<input type="text" class="search-input" id="orgSearch" placeholder="Organisation suchen...">
|
||||
<button class="btn btn-primary" id="newOrgBtn">+ Neue Organisation</button>
|
||||
<button class="btn btn-primary" id="newOrgBtn"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>Neue Organisation</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="table-wrap">
|
||||
@@ -123,14 +154,14 @@
|
||||
<button class="nav-tab active" data-subtab="users">Nutzer</button>
|
||||
<button class="nav-tab" data-subtab="org-licenses">Lizenzen</button>
|
||||
<button class="nav-tab" data-subtab="settings">Einstellungen</button>
|
||||
<button class="nav-tab" data-subtab="tokens">Token-Nutzung</button>
|
||||
<button class="nav-tab" data-subtab="tokens">Verbrauch</button>
|
||||
</div>
|
||||
|
||||
<!-- Users Sub-Tab -->
|
||||
<div class="section active" id="sub-users">
|
||||
<div class="action-bar">
|
||||
<span class="text-secondary" id="userLimitInfo"></span>
|
||||
<button class="btn btn-primary" id="newUserBtn">+ Nutzer anlegen</button>
|
||||
<button class="btn btn-primary" id="newUserBtn"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>Nutzer anlegen</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="table-wrap">
|
||||
@@ -155,7 +186,7 @@
|
||||
<div class="section" id="sub-org-licenses">
|
||||
<div class="action-bar">
|
||||
<span></span>
|
||||
<button class="btn btn-primary" id="newLicenseBtn">+ Neue Lizenz</button>
|
||||
<button class="btn btn-primary" id="newLicenseBtn"><svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>Neue Lizenz</button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="table-wrap">
|
||||
@@ -211,34 +242,46 @@
|
||||
</div>
|
||||
<div class="section" id="sub-tokens">
|
||||
<div class="token-overview">
|
||||
<!-- Kundensicht: das, was der Kunde im Monitor auch sieht -->
|
||||
<h3 style="margin-bottom:8px;">Kundensicht (Credits)</h3>
|
||||
<div class="token-stats-row" id="tokenStatsRow">
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">Verbrauchte Credits</div>
|
||||
<div class="token-stat-label">Verbrauchte Credits (Periode)</div>
|
||||
<div class="token-stat-value" id="tokenCreditsUsed">-</div>
|
||||
</div>
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">Verbleibend</div>
|
||||
<div class="token-stat-value" id="tokenCreditsRemaining">-</div>
|
||||
</div>
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">Budget (USD)</div>
|
||||
<div class="token-stat-value" id="tokenBudgetUsd">-</div>
|
||||
</div>
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">Kosten (USD)</div>
|
||||
<div class="token-stat-value" id="tokenCostUsd">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tokenSourceSplit" style="margin-top:12px;font-size:14px;"></div>
|
||||
<div class="token-budget-bar-section">
|
||||
<div class="token-budget-label">
|
||||
<span>Budget-Auslastung</span>
|
||||
<span>Kontingent-Auslastung (laufende Periode)</span>
|
||||
<span id="tokenBudgetPercent">0%</span>
|
||||
</div>
|
||||
<div class="token-budget-bar-container">
|
||||
<div class="token-budget-bar" id="tokenBudgetBar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin-top:10px; font-size:12px; color:var(--text-muted); display:flex; align-items:center; gap:6px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="flex-shrink:0;"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
|
||||
<span>Zur Einordnung. Ein Live-Lauf kostet 45 Credits, das Anlegen einer Recherche 120 (drei Durchläufe), jede Vertiefung 40, Chat und Beschreibungs-Assistent je 1 Credit.
|
||||
<a href="#" onclick="openRechnerTab(); return false;" style="color:var(--accent);">Verbrauchsrechner öffnen</a></span>
|
||||
</p>
|
||||
|
||||
<!-- Interne Sicht: was uns der Betrieb im Einkauf kostet -->
|
||||
<h3 style="margin-top:24px; margin-bottom:8px;">Interne Kosten (Einkauf, USD)</h3>
|
||||
<div class="token-stats-row">
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">API-Kosten aktueller Monat</div>
|
||||
<div class="token-stat-value" id="tokenCostUsd">-</div>
|
||||
</div>
|
||||
<div class="token-stat-card">
|
||||
<div class="token-stat-label">Budget-Limit (USD, Altmodus)</div>
|
||||
<div class="token-stat-value" id="tokenBudgetUsd">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tokenSourceSplit" style="margin-top:12px;font-size:14px;"></div>
|
||||
<h3 style="margin-top:24px;">Monatlicher Verlauf</h3>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
@@ -255,11 +298,11 @@
|
||||
<tbody id="tokenMonthlyTable"></tbody>
|
||||
</table>
|
||||
|
||||
<h3 style="margin-top:24px;">Budget bearbeiten</h3>
|
||||
<h3 style="margin-top:24px;">Credits-Kontingent bearbeiten</h3>
|
||||
<div class="card" style="margin-top:12px;">
|
||||
<div class="card-body">
|
||||
<form id="tokenBudgetForm" style="display:grid; grid-template-columns:1fr 1fr; gap:12px;">
|
||||
<div style="grid-column:1/-1; padding:8px 12px; background:var(--bg-tertiary,#0f172a); border-radius:6px; border:1px solid var(--border);">
|
||||
<div style="grid-column:1/-1; padding:8px 12px; background:var(--bg-tertiary); border-radius:6px; border:1px solid var(--border);">
|
||||
<label style="display:flex; align-items:center; gap:8px; cursor:pointer; margin:0;">
|
||||
<input type="checkbox" id="editUnlimitedBudget" onchange="onUnlimitedToggle()">
|
||||
<span><strong>Unbegrenztes Budget</strong> — Verbrauch wird trotzdem getrackt, aber kein Limit/Hard-Stop</span>
|
||||
@@ -286,20 +329,37 @@
|
||||
<label for="editWarnPercent">Warnschwelle (%)</label>
|
||||
<input type="number" id="editWarnPercent" min="1" max="100" placeholder="80">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editCostPerCredit">Kosten pro Credit (USD)</label>
|
||||
<input type="number" id="editCostPerCredit" step="0.01" placeholder="0.20">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editBudgetUsd">Budget-Limit (USD)</label>
|
||||
<input type="number" id="editBudgetUsd" step="0.01" placeholder="z.B. 2000">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editCreditsUsed">Verbrauchte Credits (laufende Periode)</label>
|
||||
<input type="number" id="editCreditsUsed" step="0.01" placeholder="Aktueller Verbrauch">
|
||||
</div>
|
||||
<details class="adv-section">
|
||||
<summary>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
Erweitert (Altmodus und Korrektur)
|
||||
</summary>
|
||||
<p class="adv-hint">
|
||||
Die beiden USD-Felder gehören zum alten Abrechnungsmodus (BILLING_MODE=actual)
|
||||
und haben im heutigen Pauschalmodus keine Wirkung auf den Kunden. Das
|
||||
Korrektur-Feld überschreibt den Verbrauch der laufenden Periode direkt,
|
||||
nur für bewusste Eingriffe gedacht.
|
||||
</p>
|
||||
<div class="adv-grid" style="margin-top:10px;">
|
||||
<div class="form-group">
|
||||
<label for="editCostPerCredit">Kosten pro Credit (USD, nur Altmodus)</label>
|
||||
<input type="number" id="editCostPerCredit" step="0.01" placeholder="0.20">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editBudgetUsd">Budget-Limit (USD, nur Altmodus)</label>
|
||||
<input type="number" id="editBudgetUsd" step="0.01" placeholder="z.B. 2000">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="editCreditsUsed">Verbrauch korrigieren (Credits, laufende Periode)</label>
|
||||
<input type="number" id="editCreditsUsed" step="0.01" placeholder="Aktueller Verbrauch">
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
<div style="grid-column:1/-1; display:flex; gap:8px; align-items:center;">
|
||||
<button type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
||||
Speichern
|
||||
</button>
|
||||
<span id="tokenBudgetMsg" style="font-size:13px; color:var(--text-secondary);"></span>
|
||||
</div>
|
||||
</form>
|
||||
@@ -786,6 +846,30 @@
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Modal: Lizenz verlängern (ersetzt das alte Browser-prompt) -->
|
||||
<div class="modal-overlay" id="modalExtendLicense">
|
||||
<div class="modal">
|
||||
<div class="modal-header">
|
||||
<h3>Lizenz verlängern</h3>
|
||||
<button class="modal-close" onclick="closeModal('modalExtendLicense')">×</button>
|
||||
</div>
|
||||
<form id="extendLicenseForm">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="extendDays">Um wie viele Tage verlängern?</label>
|
||||
<input type="number" id="extendDays" value="365" min="1" max="3650" required>
|
||||
<div class="text-muted mt-8" style="font-size:12px;">Die Verlängerung setzt am aktuellen Ablaufdatum an und aktiviert die Lizenz, falls sie abgelaufen war.</div>
|
||||
</div>
|
||||
<div id="extendLicenseError" class="error-msg" style="display:none"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('modalExtendLicense')">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-primary">Verlängern</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: Source (Create/Edit) -->
|
||||
<div class="modal-overlay" id="modalSource">
|
||||
<div class="modal">
|
||||
@@ -1154,7 +1238,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/app.js?v=20260725a"></script>
|
||||
<script src="/static/js/a11y.js?v=20260725a"></script>
|
||||
<script src="/static/js/app.js?v=20260725b"></script>
|
||||
<script src="/static/js/sources.js?v=20260522x2"></script>
|
||||
<script src="/static/js/x-scraper.js?v=20260522a"></script>
|
||||
<script src="/static/js/source-health.js?v=20260509l"></script>
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren