feat(dashboard): Kosten-Kachel zeigt den aktuellen Monat

Die Kachel heißt jetzt API-Kosten aktueller Monat (Läufe des Monats und
Lebenszeit-Summe klein in der Unterzeile) statt der nackten
Gesamtsumme. Datenquelle ist der Statistik-Endpoint in einem Aufruf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-07-25 16:54:40 +00:00
Ursprung 9d76fb994a
Commit 7336ba8ad0
2 geänderte Dateien mit 21 neuen und 12 gelöschten Zeilen

Datei anzeigen

@@ -1249,15 +1249,24 @@ function onNewOrgLicPeriodChange() {
async function loadDashboardTokenStats() {
try {
const data = await API.get('/api/token-usage/overview');
// Aktueller Monat im Vordergrund, Lebenszeit-Summe klein darunter.
// months=0 liefert beides in einem Aufruf (kpi = gesamt, Serien je Monat).
const data = await API.get('/api/statistik?months=0');
const grid = document.getElementById('statsGrid');
if (grid && data.length > 0) {
const totals = data.reduce(function(acc, org) {
return {
cost: acc.cost + (org.total_cost_usd || 0),
refreshes: acc.refreshes + (org.total_refreshes || 0),
};
}, { cost: 0, refreshes: 0 });
if (grid && data && data.kpi) {
const jetzt = new Date();
const monat = jetzt.getFullYear() + '-' + String(jetzt.getMonth() + 1).padStart(2, '0');
let monatKosten = 0;
(data.monat_quelle || []).forEach(function(r) {
if (r.monat === monat) monatKosten += r.kosten || 0;
});
let monatLaeufe = 0;
(data.monat_betrieb || []).forEach(function(r) {
if (r.monat === monat) monatLaeufe = r.completed || 0;
});
const fmtUsd = function(n) {
return '$' + Number(n || 0).toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
};
// Sprung-Kachel zum Statistik-Tab. Handler direkt anhaengen, denn die
// Kachel entsteht NACH wireStatCardLinks() (ein erneuter Aufruf dort
@@ -1267,9 +1276,9 @@ async function loadDashboardTokenStats() {
card.setAttribute('role', 'link');
card.setAttribute('tabindex', '0');
card.title = 'Zur Statistik';
card.innerHTML = '<div class="stat-label">API-Kosten gesamt</div>' +
'<div class="stat-value">$' + totals.cost.toFixed(2) + '</div>' +
'<div class="stat-sub">' + totals.refreshes + ' Refreshes</div>';
card.innerHTML = '<div class="stat-label">API-Kosten aktueller Monat</div>' +
'<div class="stat-value">' + fmtUsd(monatKosten) + '</div>' +
'<div class="stat-sub">' + monatLaeufe.toLocaleString('de-DE') + ' Läufe · gesamt ' + fmtUsd(data.kpi.kosten_usd) + '</div>';
const springe = () => gotoSection('statistik');
card.addEventListener('click', springe);
card.addEventListener('keydown', (e) => {