From c8695ff96428df923333185f78972443b33ec80b Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Mon, 19 Jan 2026 12:10:44 +0100 Subject: [PATCH] fix: Enhance dashboard components with site settings for data collection options --- app/share/[id]/page.tsx | 27 +++++++++------ app/sites/[id]/page.tsx | 30 ++++++++++++---- components/dashboard/ContentStats.tsx | 22 +++++++++--- components/dashboard/Locations.tsx | 49 +++++++++++++++++++++++---- components/dashboard/TechSpecs.tsx | 43 ++++++++++++++++++++--- components/dashboard/TopReferrers.tsx | 20 ++++++++--- 6 files changed, 152 insertions(+), 39 deletions(-) diff --git a/app/share/[id]/page.tsx b/app/share/[id]/page.tsx index ae40be7..38666ad 100644 --- a/app/share/[id]/page.tsx +++ b/app/share/[id]/page.tsx @@ -280,26 +280,33 @@ export default function PublicDashboardPage() { {/* Details Grid */}
- + -
- -
diff --git a/app/sites/[id]/page.tsx b/app/sites/[id]/page.tsx index 19947d9..a0a8cd1 100644 --- a/app/sites/[id]/page.tsx +++ b/app/sites/[id]/page.tsx @@ -234,18 +234,34 @@ export default function SiteDashboardPage() {
- + -
- - + +
('top_pages') const [isModalOpen, setIsModalOpen] = useState(false) + // Filter out generic "/" entries when page paths are disabled (all traffic shows as "/") + const filterGenericPaths = (pages: TopPage[]) => { + if (!collectPagePaths) return [] + // Filter out pages that are just "/" with high traffic (indicator of disabled tracking) + return pages.filter(p => p.path && p.path !== '') + } + const getData = () => { switch (activeTab) { case 'top_pages': - return topPages + return filterGenericPaths(topPages) case 'entry_pages': - return entryPages + return filterGenericPaths(entryPages) case 'exit_pages': - return exitPages + return filterGenericPaths(exitPages) default: return [] } @@ -83,7 +91,11 @@ export default function ContentStats({ topPages, entryPages, exitPages, domain }
- {hasData ? ( + {!collectPagePaths ? ( +
+

Page path tracking is disabled in site settings

+
+ ) : hasData ? ( <> {displayedData.map((page, index) => (
diff --git a/components/dashboard/Locations.tsx b/components/dashboard/Locations.tsx index 52b5ae8..6aa4bb3 100644 --- a/components/dashboard/Locations.tsx +++ b/components/dashboard/Locations.tsx @@ -12,13 +12,14 @@ interface LocationProps { countries: Array<{ country: string; pageviews: number }> cities: Array<{ city: string; country: string; pageviews: number }> regions: Array<{ region: string; country: string; pageviews: number }> + geoDataLevel?: 'full' | 'country' | 'none' } type Tab = 'map' | 'countries' | 'regions' | 'cities' const LIMIT = 7 -export default function Locations({ countries, cities, regions }: LocationProps) { +export default function Locations({ countries, cities, regions, geoDataLevel = 'full' }: LocationProps) { const [activeTab, setActiveTab] = useState('map') const [isModalOpen, setIsModalOpen] = useState(false) @@ -68,12 +69,42 @@ export default function Locations({ countries, cities, regions }: LocationProps) } } - const data = activeTab === 'map' ? [] : getData() - const hasData = activeTab === 'map' ? (countries && countries.length > 0) : (data && data.length > 0) + // Check if the current tab's data is disabled by privacy settings + const isTabDisabled = () => { + if (geoDataLevel === 'none') return true + if (geoDataLevel === 'country' && (activeTab === 'regions' || activeTab === 'cities')) return true + return false + } + + // Filter out "Unknown" entries that result from disabled collection + const filterUnknown = (data: any[]) => { + return data.filter(item => { + if (activeTab === 'countries') return item.country && item.country !== 'Unknown' && item.country !== '' + if (activeTab === 'regions') return item.region && item.region !== 'Unknown' && item.region !== '' + if (activeTab === 'cities') return item.city && item.city !== 'Unknown' && item.city !== '' + return true + }) + } + + const rawData = activeTab === 'map' ? [] : getData() + const data = filterUnknown(rawData) + const hasData = activeTab === 'map' + ? (countries && filterUnknown(countries).length > 0) + : (data && data.length > 0) const displayedData = (activeTab !== 'map' && hasData) ? (data as any[]).slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedData.length) const showViewAll = activeTab !== 'map' && hasData && data.length > LIMIT + const getDisabledMessage = () => { + if (geoDataLevel === 'none') { + return 'Geographic data collection is disabled in site settings' + } + if (geoDataLevel === 'country' && (activeTab === 'regions' || activeTab === 'cities')) { + return `${activeTab === 'regions' ? 'Region' : 'City'} tracking is disabled. Only country-level data is collected.` + } + return 'No data available' + } + return ( <>
@@ -109,8 +140,12 @@ export default function Locations({ countries, cities, regions }: LocationProps)
- {activeTab === 'map' ? ( - hasData ? : ( + {isTabDisabled() ? ( +
+

{getDisabledMessage()}

+
+ ) : activeTab === 'map' ? ( + hasData ? : (

No data available

@@ -123,9 +158,9 @@ export default function Locations({ countries, cities, regions }: LocationProps)
{activeTab === 'countries' && {getFlagComponent(item.country)}} {activeTab !== 'countries' && {getFlagComponent(item.country)}} - + - {activeTab === 'countries' ? getCountryName(item.country) : + {activeTab === 'countries' ? getCountryName(item.country) : activeTab === 'regions' ? getRegionName(item.region, item.country) : (item.city === 'Unknown' ? 'Unknown' : item.city)} diff --git a/components/dashboard/TechSpecs.tsx b/components/dashboard/TechSpecs.tsx index 252e913..dcef5a6 100644 --- a/components/dashboard/TechSpecs.tsx +++ b/components/dashboard/TechSpecs.tsx @@ -11,17 +11,24 @@ interface TechSpecsProps { os: Array<{ os: string; pageviews: number }> devices: Array<{ device: string; pageviews: number }> screenResolutions: Array<{ screen_resolution: string; pageviews: number }> + collectDeviceInfo?: boolean + collectScreenResolution?: boolean } type Tab = 'browsers' | 'os' | 'devices' | 'screens' const LIMIT = 7 -export default function TechSpecs({ browsers, os, devices, screenResolutions }: TechSpecsProps) { +export default function TechSpecs({ browsers, os, devices, screenResolutions, collectDeviceInfo = true, collectScreenResolution = true }: TechSpecsProps) { const [activeTab, setActiveTab] = useState('browsers') const [isModalOpen, setIsModalOpen] = useState(false) - const getData = () => { + // Filter out "Unknown" entries that result from disabled collection + const filterUnknown = (items: Array<{ name: string; pageviews: number; icon: React.ReactNode }>) => { + return items.filter(item => item.name && item.name !== 'Unknown' && item.name !== '') + } + + const getRawData = () => { switch (activeTab) { case 'browsers': return browsers.map(b => ({ name: b.browser, pageviews: b.pageviews, icon: getBrowserIcon(b.browser) })) @@ -36,7 +43,29 @@ export default function TechSpecs({ browsers, os, devices, screenResolutions }: } } - const data = getData() + // Check if current tab is disabled by privacy settings + const isTabDisabled = () => { + if (!collectDeviceInfo && (activeTab === 'browsers' || activeTab === 'os' || activeTab === 'devices')) { + return true + } + if (!collectScreenResolution && activeTab === 'screens') { + return true + } + return false + } + + const getDisabledMessage = () => { + if (!collectDeviceInfo && (activeTab === 'browsers' || activeTab === 'os' || activeTab === 'devices')) { + return 'Device info collection is disabled in site settings' + } + if (!collectScreenResolution && activeTab === 'screens') { + return 'Screen resolution collection is disabled in site settings' + } + return 'No data available' + } + + const rawData = getRawData() + const data = filterUnknown(rawData) const hasData = data && data.length > 0 const displayedData = hasData ? data.slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedData.length) @@ -77,13 +106,17 @@ export default function TechSpecs({ browsers, os, devices, screenResolutions }:
- {hasData ? ( + {isTabDisabled() ? ( +
+

{getDisabledMessage()}

+
+ ) : hasData ? ( <> {displayedData.map((item, index) => (
{item.icon && {item.icon}} - {item.name === 'Unknown' ? 'Unknown' : item.name} + {item.name}
{formatNumber(item.pageviews)} diff --git a/components/dashboard/TopReferrers.tsx b/components/dashboard/TopReferrers.tsx index ea41dde..90c0e28 100644 --- a/components/dashboard/TopReferrers.tsx +++ b/components/dashboard/TopReferrers.tsx @@ -7,17 +7,23 @@ import { Modal } from '@ciphera-net/ui' interface TopReferrersProps { referrers: Array<{ referrer: string; pageviews: number }> + collectReferrers?: boolean } const LIMIT = 7 -export default function TopReferrers({ referrers }: TopReferrersProps) { +export default function TopReferrers({ referrers, collectReferrers = true }: TopReferrersProps) { const [isModalOpen, setIsModalOpen] = useState(false) - const hasData = referrers && referrers.length > 0 - const displayedReferrers = hasData ? referrers.slice(0, LIMIT) : [] + // Filter out empty/unknown referrers + const filteredReferrers = (referrers || []).filter( + ref => ref.referrer && ref.referrer !== 'Unknown' && ref.referrer !== '' + ) + + const hasData = filteredReferrers.length > 0 + const displayedReferrers = hasData ? filteredReferrers.slice(0, LIMIT) : [] const emptySlots = Math.max(0, LIMIT - displayedReferrers.length) - const showViewAll = hasData && referrers.length > LIMIT + const showViewAll = hasData && filteredReferrers.length > LIMIT return ( <> @@ -37,7 +43,11 @@ export default function TopReferrers({ referrers }: TopReferrersProps) {
- {hasData ? ( + {!collectReferrers ? ( +
+

Referrer tracking is disabled in site settings

+
+ ) : hasData ? ( <> {displayedReferrers.map((ref, index) => (