From 7e8dde88c90a19c46b4f0c2840b10417e8865e69 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Thu, 5 Feb 2026 17:35:32 +0100 Subject: [PATCH] Phase 4: Badge & Empty State Improvements --- app/sites/[id]/realtime/page.tsx | 14 ++++++++--- components/PricingSection.tsx | 4 ++-- components/dashboard/Countries.tsx | 29 +++++++++++++++++++++-- components/dashboard/Locations.tsx | 34 ++++++++++++++++++++------- components/dashboard/TechSpecs.tsx | 14 ++++++++--- components/dashboard/TopPages.tsx | 15 ++++++++++-- components/dashboard/TopReferrers.tsx | 14 ++++++++--- 7 files changed, 100 insertions(+), 24 deletions(-) diff --git a/app/sites/[id]/realtime/page.tsx b/app/sites/[id]/realtime/page.tsx index 06f5440..6285740 100644 --- a/app/sites/[id]/realtime/page.tsx +++ b/app/sites/[id]/realtime/page.tsx @@ -6,7 +6,7 @@ import { getSite, type Site } from '@/lib/api/sites' import { getRealtimeVisitors, getSessionDetails, type Visitor, type SessionEvent } from '@/lib/api/realtime' import { toast } from '@ciphera-net/ui' import { getAuthErrorMessage } from '@/lib/utils/authErrors' -import { LoadingOverlay } from '@ciphera-net/ui' +import { LoadingOverlay, UserIcon } from '@ciphera-net/ui' function formatTimeAgo(dateString: string) { const date = new Date(dateString) @@ -122,8 +122,16 @@ export default function RealtimePage() {
{visitors.length === 0 ? ( -
- No active visitors right now. +
+
+ +
+

+ No active visitors right now +

+

+ New visitors will appear here in real-time +

) : (
diff --git a/components/PricingSection.tsx b/components/PricingSection.tsx index dd42fc3..62570e7 100644 --- a/components/PricingSection.tsx +++ b/components/PricingSection.tsx @@ -285,9 +285,9 @@ export default function PricingSection() { {isTeam && ( <>
-
+ Most Popular -
+ )} diff --git a/components/dashboard/Countries.tsx b/components/dashboard/Countries.tsx index 3099d0d..49ce2ef 100644 --- a/components/dashboard/Countries.tsx +++ b/components/dashboard/Countries.tsx @@ -4,6 +4,7 @@ import { useState } from 'react' import { formatNumber } from '@/lib/utils/format' import * as Flags from 'country-flag-icons/react/3x2' import WorldMap from './WorldMap' +import { GlobeIcon } from '@ciphera-net/ui' interface LocationProps { countries: Array<{ country: string; pageviews: number }> @@ -36,7 +37,19 @@ export default function Locations({ countries, cities }: LocationProps) { const renderContent = () => { if (activeTab === 'countries') { if (!countries || countries.length === 0) { - return

No data available

+ return ( +
+
+ +
+

+ No location data yet +

+

+ Visitor locations will appear here based on anonymous geographic data. +

+
+ ) } return (
@@ -60,7 +73,19 @@ export default function Locations({ countries, cities }: LocationProps) { if (activeTab === 'cities') { if (!cities || cities.length === 0) { - return

No data available

+ return ( +
+
+ +
+

+ No city data yet +

+

+ City-level visitor data will appear as traffic grows. +

+
+ ) } return (
diff --git a/components/dashboard/Locations.tsx b/components/dashboard/Locations.tsx index 80ac11d..eb77305 100644 --- a/components/dashboard/Locations.tsx +++ b/components/dashboard/Locations.tsx @@ -226,8 +226,16 @@ export default function Locations({ countries, cities, regions, geoDataLevel = '
) : activeTab === 'map' ? ( hasData ? : ( -
-

No data available

+
+
+ +
+

+ No location data yet +

+

+ Visitor locations will appear here based on anonymous geographic data. +

) ) : ( @@ -252,14 +260,22 @@ export default function Locations({ countries, cities, regions, geoDataLevel = ' ))} {Array.from({ length: emptySlots }).map((_, i) => ( diff --git a/components/dashboard/TechSpecs.tsx b/components/dashboard/TechSpecs.tsx index 608ded6..e5682a9 100644 --- a/components/dashboard/TechSpecs.tsx +++ b/components/dashboard/TechSpecs.tsx @@ -4,7 +4,7 @@ import { useState, useEffect } from 'react' import { formatNumber } from '@/lib/utils/format' import { getBrowserIcon, getOSIcon, getDeviceIcon } from '@/lib/utils/icons' import { MdMonitor } from 'react-icons/md' -import { Modal } from '@ciphera-net/ui' +import { Modal, GridIcon } from '@ciphera-net/ui' import { getBrowsers, getOS, getDevices, getScreenResolutions } from '@/lib/api/stats' interface TechSpecsProps { @@ -165,8 +165,16 @@ export default function TechSpecs({ browsers, os, devices, screenResolutions, co ))} ) : ( -
-

No data available

+
+
+ +
+

+ No technology data yet +

+

+ Browser, OS, and device information will appear as visitors arrive. +

)}
diff --git a/components/dashboard/TopPages.tsx b/components/dashboard/TopPages.tsx index 82aa893..14d5de3 100644 --- a/components/dashboard/TopPages.tsx +++ b/components/dashboard/TopPages.tsx @@ -1,6 +1,7 @@ 'use client' import { formatNumber } from '@/lib/utils/format' +import { LayoutDashboardIcon } from '@ciphera-net/ui' interface TopPagesProps { pages: Array<{ path: string; pageviews: number }> @@ -9,11 +10,21 @@ interface TopPagesProps { export default function TopPages({ pages }: TopPagesProps) { if (!pages || pages.length === 0) { return ( -
+

Top Pages

-

No data available

+
+
+ +
+

+ No page data yet +

+

+ Your most visited pages will appear here as traffic arrives. +

+
) } diff --git a/components/dashboard/TopReferrers.tsx b/components/dashboard/TopReferrers.tsx index 5abbed0..d398f82 100644 --- a/components/dashboard/TopReferrers.tsx +++ b/components/dashboard/TopReferrers.tsx @@ -3,7 +3,7 @@ import { useState, useEffect } from 'react' import { formatNumber } from '@/lib/utils/format' import { getReferrerIcon } from '@/lib/utils/icons' -import { Modal } from '@ciphera-net/ui' +import { Modal, GlobeIcon } from '@ciphera-net/ui' import { getTopReferrers, TopReferrer } from '@/lib/api/stats' interface TopReferrersProps { @@ -93,8 +93,16 @@ export default function TopReferrers({ referrers, collectReferrers = true, siteI ))} ) : ( -
-

No data available

+
+
+ +
+

+ No referrers yet +

+

+ Traffic sources will appear here when visitors come from external sites. +

)}