diff --git a/wwwroot/app.js b/wwwroot/app.js index e249091..fb63ac1 100644 --- a/wwwroot/app.js +++ b/wwwroot/app.js @@ -8,6 +8,7 @@ const ZOOM_LEVELS = [ { name: '1 Tag', days: 1 }, { name: '12 Stunden', days: 0.5 }, ]; +const WEEKLY_BUDGET = 800; // $ pro Woche const BAR_COUNT = 30; const CHAIN_COLORS = [ '#4ade80','#60a5fa','#f97316','#c084fc','#f472b6', @@ -97,7 +98,7 @@ async function loadView() { function renderSummary(s) { $('summary').innerHTML = ` - Zeitraum: $${s.totalCost.toFixed(2)} + Zeitraum: ${pct(s.totalCost)} Einträge: ${s.totalEntries} `; } @@ -118,7 +119,7 @@ function renderBucketChart(buckets, bucketMinutes) { const b = bucketMap[i]; const cost = b ? b.cost : 0; const count = b ? b.count : 0; - const pct = (cost / maxCost) * 100; + const barPct = (cost / maxCost) * 100; const bucketStart = new Date(viewFrom.getTime() + i * bucketMinutes * 60000); const bucketEnd = new Date(viewFrom.getTime() + (i + 1) * bucketMinutes * 60000); @@ -126,8 +127,8 @@ function renderBucketChart(buckets, bucketMinutes) { const wrapper = document.createElement('div'); wrapper.className = 'bar-wrapper'; wrapper.innerHTML = ` -
- + + `; if (isMaxZoom) { @@ -184,15 +185,15 @@ function renderEntryChart(entries) { chain.forEach((e, ei) => { const cost = Number(e.cost); - const pct = (cost / maxCost) * 100; + const barPct = (cost / maxCost) * 100; window._entryChainColors.set(e.id, color); const wrapper = document.createElement('div'); wrapper.className = 'bar-wrapper bar-in-chain'; wrapper.innerHTML = ` - - + + `; wrapper.addEventListener('click', () => openModal(e.data, e.id)); chart.appendChild(wrapper); @@ -202,7 +203,7 @@ function renderEntryChart(entries) { const totalLbl = document.createElement('div'); totalLbl.className = 'chain-cost-label'; totalLbl.style.color = color; - totalLbl.textContent = `$${chainTotal.toFixed(2)}`; + totalLbl.textContent = pct(chainTotal); wrapper.prepend(totalLbl); } @@ -232,7 +233,7 @@ function renderChainBlocks(chains) { ${fmtShort(new Date(c.first))} - ${fmtShort(new Date(c.last))} ${c.count} Einträge - $${c.totalCost.toFixed(4)} + ${pct(c.totalCost)} `; @@ -273,7 +274,7 @@ function renderEntryList(entries) { ${fmtTime(e.timestamp)} ${e.model || '-'} ${shortNum(e.inputTokens)}/${shortNum(e.outputTokens)} - $${Number(e.cost).toFixed(4)} + ${pct(Number(e.cost))} ${e.type} `; row.addEventListener('click', () => openModal(e.data, e.id)); @@ -299,7 +300,7 @@ async function toggleChainBlock(idx, chainId) { ${fmtTime(entry.timestamp)} ${msg.model || '-'} ${shortNum(msg.usage?.input)}/${shortNum(msg.usage?.output)} - ${cost ? '$' + cost.toFixed(4) : '-'} + ${cost ? pct(cost) : '-'} ${msg.role || entry.type} `; @@ -389,7 +390,7 @@ async function openModal(dataStr, clickedId) { const chainCount = chainCosts.filter(c => c > 0).length; let html = `