From df2b3cadd729f13ab2edcf8fee3391a4077beff8 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Sun, 15 Mar 2026 20:39:25 +0100 Subject: [PATCH] feat: add inline bar charts to all dashboard list components Add proportional background bars (brand-orange) to Pages, Referrers, Locations, Technology, and Campaigns tables. Bars scale relative to the top item in each list. --- components/dashboard/Campaigns.tsx | 12 ++++-- components/dashboard/ContentStats.tsx | 62 +++++++++++++++------------ components/dashboard/Locations.tsx | 12 ++++-- components/dashboard/TechSpecs.tsx | 12 ++++-- components/dashboard/TopReferrers.tsx | 46 ++++++++++++-------- 5 files changed, 89 insertions(+), 55 deletions(-) diff --git a/components/dashboard/Campaigns.tsx b/components/dashboard/Campaigns.tsx index 38e5cb0..0d5c745 100644 --- a/components/dashboard/Campaigns.tsx +++ b/components/dashboard/Campaigns.tsx @@ -155,13 +155,19 @@ export default function Campaigns({ siteId, dateRange, filters, onFilter }: Camp ) : hasData ? ( <> {displayedData.map((item) => { + const maxVis = displayedData[0]?.visitors ?? 0 + const barWidth = maxVis > 0 ? (item.visitors / maxVis) * 100 : 0 return (
onFilter?.({ dimension: 'utm_source', operator: 'is', values: [item.source] })} - className={`flex items-center justify-between py-1.5 group hover:bg-neutral-50 dark:hover:bg-neutral-800 rounded-lg px-2 -mx-2 transition-colors${onFilter ? ' cursor-pointer' : ''}`} + className={`relative flex items-center justify-between py-1.5 group hover:bg-neutral-50/50 dark:hover:bg-neutral-800/50 rounded-lg px-2 -mx-2 transition-colors${onFilter ? ' cursor-pointer' : ''}`} > -
+
+
{renderSourceIcon(item.source)}
@@ -174,7 +180,7 @@ export default function Campaigns({ siteId, dateRange, filters, onFilter }: Camp
-
+
{totalVisitors > 0 ? `${Math.round((item.visitors / totalVisitors) * 100)}%` : ''} diff --git a/components/dashboard/ContentStats.tsx b/components/dashboard/ContentStats.tsx index f56b5df..4b0a460 100644 --- a/components/dashboard/ContentStats.tsx +++ b/components/dashboard/ContentStats.tsx @@ -148,34 +148,42 @@ export default function ContentStats({ topPages, entryPages, exitPages, domain,
) : hasData ? ( <> - {displayedData.map((page) => ( -
onFilter?.({ dimension: 'page', operator: 'is', values: [page.path] })} - className={`flex items-center justify-between h-9 group hover:bg-neutral-50 dark:hover:bg-neutral-800 rounded-lg px-2 -mx-2 transition-colors${onFilter ? ' cursor-pointer' : ''}`} - > -
- {page.path} - e.stopPropagation()} - className="ml-2 flex-shrink-0" - > - - + {displayedData.map((page, idx) => { + const maxPv = displayedData[0]?.pageviews ?? 0 + const barWidth = maxPv > 0 ? (page.pageviews / maxPv) * 100 : 0 + return ( +
onFilter?.({ dimension: 'page', operator: 'is', values: [page.path] })} + className={`relative flex items-center justify-between h-9 group hover:bg-neutral-50/50 dark:hover:bg-neutral-800/50 rounded-lg px-2 -mx-2 transition-colors${onFilter ? ' cursor-pointer' : ''}`} + > +
+ +
+ + {totalPageviews > 0 ? `${Math.round((page.pageviews / totalPageviews) * 100)}%` : ''} + + + {formatNumber(page.pageviews)} + +
-
- - {totalPageviews > 0 ? `${Math.round((page.pageviews / totalPageviews) * 100)}%` : ''} - - - {formatNumber(page.pageviews)} - -
-
- ))} + ) + })} {Array.from({ length: emptySlots }).map((_, i) => (