diff --git a/src/frontend/analytics.js b/src/frontend/analytics.js index 0d7dc99..7763ac4 100644 --- a/src/frontend/analytics.js +++ b/src/frontend/analytics.js @@ -216,7 +216,8 @@ async function renderAnalytics(container) { var multiplier = data.totalCost / totalPaid; var savingsPositive = savings > 0; var breakdown = subEntries.map(function(e) { - return escHtml(e.plan || 'Sub') + ' $' + parseFloat(e.paid).toFixed(0); + var prefix = e.service ? escHtml(e.service) + ' ' : ''; + return prefix + escHtml(e.plan || 'Sub') + ' $' + parseFloat(e.paid).toFixed(0); }).join(' + '); html += '
'; html += '
$' + totalPaid.toFixed(2) + 'Paid (' + breakdown + ')
'; @@ -240,7 +241,7 @@ async function renderAnalytics(container) { if (serviceLabel) html += '' + escHtml(serviceLabel) + ''; html += '' + escHtml(e.plan || '\u2014') + ''; html += '$' + parseFloat(e.paid || 0).toFixed(2) + '/mo'; - html += '' + (e.from ? 'from ' + e.from : 'no date') + ''; + html += '' + (e.from ? 'from ' + escHtml(e.from) : 'no date') + ''; html += ''; html += '
'; }); @@ -248,15 +249,16 @@ async function renderAnalytics(container) { html += ''; // Add form - var serviceOptions = '' + - Object.keys(SERVICE_PLANS).map(function(k) { - return ''; - }).join(''); + var serviceDatalistOpts = Object.keys(SERVICE_PLANS).map(function(k) { + return ''; - paidEl.value = ''; + if (paidEl) paidEl.value = ''; if (service && SERVICE_PLANS[service]) { SERVICE_PLANS[service].plans.forEach(function(p) { var opt = document.createElement('option'); opt.value = p.name; - opt.textContent = p.name + ' ($' + p.price + '/mo)'; - planEl.appendChild(opt); + planOpts.appendChild(opt); }); } } @@ -268,10 +267,11 @@ function onSubPlanChange() { var serviceEl = document.getElementById('sub-new-service'); var planEl = document.getElementById('sub-new-plan'); var paidEl = document.getElementById('sub-new-paid'); - var service = serviceEl ? serviceEl.value : ''; - var planName = planEl ? planEl.value : ''; + var service = serviceEl ? serviceEl.value.trim() : ''; + var planName = planEl ? planEl.value.trim() : ''; if (service && planName && SERVICE_PLANS[service]) { - var found = SERVICE_PLANS[service].plans.find(function(p) { return p.name === planName; }); + var planLower = planName.toLowerCase(); + var found = SERVICE_PLANS[service].plans.find(function(p) { return p.name.toLowerCase() === planLower; }); if (found && paidEl) paidEl.value = found.price; } } @@ -293,6 +293,8 @@ function addSubEntry() { var paid = parseFloat(document.getElementById('sub-new-paid').value) || 0; var from = (document.getElementById('sub-new-from').value || '').trim(); if (!paid) return; + _analyticsHtmlCache = null; + _analyticsCacheUrl = null; var cfg = getSubscriptionConfig(); cfg.entries.push({ service: service || '', plan: plan || 'Subscription', paid: paid, from: from }); cfg.entries.sort(function(a,b){return (a.from||'').localeCompare(b.from||'');}); @@ -300,6 +302,8 @@ function addSubEntry() { render(); } function removeSubEntry(idx) { + _analyticsHtmlCache = null; + _analyticsCacheUrl = null; var cfg = getSubscriptionConfig(); cfg.entries.splice(idx, 1); saveSubscriptionConfig(cfg); diff --git a/src/frontend/styles.css b/src/frontend/styles.css index 9ed604b..250c8cc 100644 --- a/src/frontend/styles.css +++ b/src/frontend/styles.css @@ -9,6 +9,7 @@ /* ── CSS Custom Properties (Dark Theme — Default) ──────────────── */ :root { + color-scheme: dark; --bg-primary: #1a1d23; --bg-secondary: #22262e; --bg-card: #2a2e37; @@ -3116,17 +3117,8 @@ body { font-size: 13px; } -.sub-add-form select { - background: var(--bg-card); - border: 1px solid var(--border); - border-radius: 6px; - padding: 6px 10px; - color: var(--text); - font-size: 13px; - cursor: pointer; -} -.sub-add-form select:first-child { width: 170px; } -.sub-add-form select:nth-child(2) { width: 150px; } +#sub-new-service { width: 180px; } +#sub-new-plan { width: 130px; } .sub-add-form input[type="number"] { width: 80px; } .sub-add-form input[type="date"] { width: 140px; }