feat: Credits-System mit Verbrauchsanzeige im User-Dropdown
- DB-Migration: credits_total/credits_used/cost_per_credit auf licenses, token_usage_monthly Tabelle - Orchestrator: Monatliche Token-Aggregation + Credits-Abzug nach Refresh - Auth: Credits-Daten im /me Endpoint + Bugfix fehlende Klammer in get() - Frontend: Credits-Balken im User-Dropdown mit Farbwechsel Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -5335,3 +5335,61 @@ body.tutorial-active .tutorial-cursor {
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 0 0 2px rgba(150, 121, 26, 0.25);
|
||||
}
|
||||
|
||||
/* ===== Credits-Anzeige im User-Dropdown ===== */
|
||||
.credits-section {
|
||||
padding: 8px 16px 12px;
|
||||
}
|
||||
|
||||
.credits-divider {
|
||||
height: 1px;
|
||||
background: var(--border);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.credits-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.credits-bar-container {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.credits-bar {
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
background: var(--accent);
|
||||
transition: width 0.6s ease, background-color 0.3s ease;
|
||||
min-width: 2px;
|
||||
}
|
||||
|
||||
.credits-bar.warning {
|
||||
background: #e67e22;
|
||||
}
|
||||
|
||||
.credits-bar.critical {
|
||||
background: #e74c3c;
|
||||
}
|
||||
|
||||
.credits-info {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.credits-info span {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,16 @@
|
||||
<span class="header-dropdown-label">Lizenz</span>
|
||||
<span class="header-dropdown-value" id="header-license-info">-</span>
|
||||
</div>
|
||||
<div id="credits-section" class="credits-section" style="display: none;">
|
||||
<div class="credits-divider"></div>
|
||||
<div class="credits-label">Credits</div>
|
||||
<div class="credits-bar-container">
|
||||
<div id="credits-bar" class="credits-bar"></div>
|
||||
</div>
|
||||
<div class="credits-info">
|
||||
<span id="credits-remaining">0</span> von <span id="credits-total">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-license-warning" id="header-license-warning"></div>
|
||||
|
||||
@@ -466,6 +466,32 @@ const App = {
|
||||
licInfoEl.textContent = label;
|
||||
}
|
||||
|
||||
// Credits-Anzeige im Dropdown
|
||||
const creditsSection = document.getElementById('credits-section');
|
||||
if (creditsSection && user.credits_total) {
|
||||
creditsSection.style.display = 'block';
|
||||
const bar = document.getElementById('credits-bar');
|
||||
const remainingEl = document.getElementById('credits-remaining');
|
||||
const totalEl = document.getElementById('credits-total');
|
||||
|
||||
const remaining = user.credits_remaining || 0;
|
||||
const total = user.credits_total || 1;
|
||||
const percentUsed = user.credits_percent_used || 0;
|
||||
const percentRemaining = Math.max(0, 100 - percentUsed);
|
||||
|
||||
remainingEl.textContent = remaining.toLocaleString('de-DE');
|
||||
totalEl.textContent = total.toLocaleString('de-DE');
|
||||
bar.style.width = percentRemaining + '%';
|
||||
|
||||
// Farbwechsel je nach Verbrauch
|
||||
bar.classList.remove('warning', 'critical');
|
||||
if (percentUsed > 80) {
|
||||
bar.classList.add('critical');
|
||||
} else if (percentUsed > 50) {
|
||||
bar.classList.add('warning');
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown Toggle
|
||||
const userBtn = document.getElementById('header-user-btn');
|
||||
const userDropdown = document.getElementById('header-user-dropdown');
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren