From 3d3c8a1a544002f3146667081c70e5b1bf254cdd Mon Sep 17 00:00:00 2001 From: DJP Date: Thu, 19 Mar 2026 13:48:46 -0400 Subject: [PATCH] feat: Add Visits and Unique Users cards to overview Visits counts total conversations created in the timeframe (from conversations collection). Unique Users counts distinct users who created at least one conversation in the period. Co-Authored-By: Claude Opus 4.6 --- public/css/style.css | 2 ++ public/index.html | 8 ++++++++ public/js/app.js | 2 ++ services/analytics.js | 10 +++++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/public/css/style.css b/public/css/style.css index 071b1af..9d75be1 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -268,6 +268,8 @@ body { .stat-icon.tokens { background: rgba(255, 196, 7, 0.08); color: #FFD54F; } .stat-icon.users { background: rgba(192, 132, 252, 0.1); color: var(--accent-purple); } .stat-icon.convos { background: rgba(255, 196, 7, 0.06); color: #FFAB00; } +.stat-icon.visits { background: rgba(74, 222, 128, 0.1); color: var(--accent-green); } +.stat-icon.unique { background: rgba(248, 113, 113, 0.1); color: var(--accent-red); } .stat-label { display: block; diff --git a/public/index.html b/public/index.html index f12c194..c083160 100644 --- a/public/index.html +++ b/public/index.html @@ -94,6 +94,14 @@
Conversations--
+
+
+
Visits--
+
+
+
+
Unique Users--
+
diff --git a/public/js/app.js b/public/js/app.js index 45a2285..dfe053f 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -176,6 +176,8 @@ async function loadSummary() { document.getElementById('totalTokens').textContent = fmtTokens(d.totalTokens); document.getElementById('activeUsers').textContent = fmtNum(d.activeUsers); document.getElementById('conversations').textContent = fmtNum(d.conversations); + document.getElementById('visits').textContent = fmtNum(d.visits); + document.getElementById('uniqueUsers').textContent = fmtNum(d.uniqueUsers); } catch (e) { console.error('Summary:', e); } } diff --git a/services/analytics.js b/services/analytics.js index 8d50f4f..513fb82 100644 --- a/services/analytics.js +++ b/services/analytics.js @@ -52,7 +52,7 @@ async function getSummary(db, query) { await refreshAgentsCache(db); const { startDate, endDate } = getDateRange(query); - const [tokenResult, userCount, convCount] = await Promise.all([ + const [tokenResult, userCount, convCount, visits, uniqueUsers] = await Promise.all([ db.collection('transactions').aggregate([ { $match: { createdAt: { $gte: startDate, $lte: endDate } } }, { @@ -69,6 +69,12 @@ async function getSummary(db, query) { db.collection('transactions').distinct('conversationId', { createdAt: { $gte: startDate, $lte: endDate } }), + db.collection('conversations').countDocuments({ + createdAt: { $gte: startDate, $lte: endDate } + }), + db.collection('conversations').distinct('user', { + createdAt: { $gte: startDate, $lte: endDate } + }), ]); const t = tokenResult[0] || { totalTokens: 0, totalCost: 0 }; @@ -77,6 +83,8 @@ async function getSummary(db, query) { totalCost: t.totalCost / 1_000_000, activeUsers: userCount.length, conversations: convCount.length, + visits: visits, + uniqueUsers: uniqueUsers.length, }; }