import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { supabase } from '../utils/supabaseClient'; import { Users, Eye, Clock, TrendingUp, MousePointer, ArrowUpRight, ArrowDownRight } from 'lucide-react'; import SEO from '../components/SEO'; import PageTransition from '../components/PageTransition'; interface AnalyticsData { pageViews: number; uniqueVisitors: number; avgTimeOnSite: string; bounceRate: string; conversions: number; conversionRate: string; activeUsers: number; topPages: Array<{ path: string; views: number; change: number; }>; realtimeStats: { currentVisitors: number; pagesPerMinute: number; }; events: Array<{ name: string; count: number; trend: number; }>; } const DashboardPage = () => { const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [analyticsData, setAnalyticsData] = useState({ pageViews: 0, uniqueVisitors: 0, avgTimeOnSite: '0:00', bounceRate: '0%', conversions: 0, conversionRate: '0%', activeUsers: 0, topPages: [], realtimeStats: { currentVisitors: 0, pagesPerMinute: 0 }, events: [] }); useEffect(() => { checkAuth(); fetchAnalyticsData(); const interval = setInterval(fetchRealtimeData, 30000); // Update every 30 seconds return () => clearInterval(interval); }, []); const checkAuth = async () => { const { data: { session } } = await supabase.auth.getSession(); if (!session) { navigate('/login'); } setLoading(false); }; const fetchAnalyticsData = async () => { // Simulated data - replace with actual GA4 API calls setAnalyticsData({ pageViews: 1234, uniqueVisitors: 567, avgTimeOnSite: '2:45', bounceRate: '45%', conversions: 89, conversionRate: '15.7%', activeUsers: 23, topPages: [ { path: '/', views: 450, change: 5.2 }, { path: '/blog', views: 320, change: -2.1 }, { path: '/portfolio', views: 280, change: 8.4 }, { path: '/contact', views: 184, change: 3.7 } ], realtimeStats: { currentVisitors: 23, pagesPerMinute: 4.2 }, events: [ { name: 'Contact Form Submit', count: 45, trend: 12.3 }, { name: 'Portfolio View', count: 156, trend: -4.2 }, { name: 'CV Download', count: 78, trend: 8.7 }, { name: 'Blog Read', count: 234, trend: 15.4 } ] }); }; const fetchRealtimeData = async () => { // Simulated real-time data update setAnalyticsData(prev => ({ ...prev, realtimeStats: { currentVisitors: Math.floor(Math.random() * 30) + 15, pagesPerMinute: +(Math.random() * 5 + 2).toFixed(1) } })); }; if (loading) { return (
); } return (

Analytics Dashboard

{analyticsData.realtimeStats.currentVisitors} active users

Page Views

{analyticsData.pageViews}

{analyticsData.realtimeStats.pagesPerMinute} per minute

Unique Visitors

{analyticsData.uniqueVisitors}

{analyticsData.activeUsers} currently active

Conversions

{analyticsData.conversions}

{analyticsData.conversionRate} conversion rate

Avg. Time on Site

{analyticsData.avgTimeOnSite}

{analyticsData.bounceRate} bounce rate

Top Pages

{analyticsData.topPages.map((page, index) => (
{page.path}
{page.views}
= 0 ? 'text-green-500' : 'text-red-500'}`}> {page.change >= 0 ? ( ) : ( )} {Math.abs(page.change)}%
))}

Event Tracking

{analyticsData.events.map((event, index) => (
{event.name}
{event.count}
= 0 ? 'text-green-500' : 'text-red-500'}`}> {event.trend >= 0 ? ( ) : ( )} {Math.abs(event.trend)}%
))}
); }; export default DashboardPage;