import { useEffect, useState } from 'react'; import { apiFetch } from '../api'; import './VisitorAnalytics.css'; function VisitorAnalytics({ onClose }) { const [stats, setStats] = useState({ total_visitors: 0, unique_visitors: 0, status: 'connecting' }); const [loading, setLoading] = useState(true); const fetchStats = async () => { try { setLoading(true); const res = await apiFetch('/api/v1/analytics/stats'); if (res.ok) { const data = await res.json(); setStats(data); } else { setStats({ total_visitors: 0, unique_visitors: 0, status: 'offline' }); } } catch (error) { console.error("Failed to fetch visitor stats:", error); setStats({ total_visitors: 0, unique_visitors: 0, status: 'offline' }); } finally { setLoading(false); } }; useEffect(() => { fetchStats(); }, []); const returningCount = Math.max(0, stats.total_visitors - stats.unique_visitors); const returningPercentage = stats.total_visitors > 0 ? Math.round((returningCount / stats.total_visitors) * 100) : 0; const uniquePercentage = stats.total_visitors > 0 ? Math.round((stats.unique_visitors / stats.total_visitors) * 100) : 100; return (
e.stopPropagation()}>

Visitor Insights

Real-time visitor insights powered by Redis + CDN caching.

{stats.status === 'online' && ( Live Tracking )} {stats.status === 'offline' && ( Simulated )} {stats.status === 'connecting' && ( Connecting... )}
{/* Metric 1: Total Hits */}
visibility
{stats.total_visitors} Total Visits
{/* Metric 2: Unique Hits */}
fingerprint
{stats.unique_visitors} Unique Visitors
{/* Traffic breakdown panel */}

Visitor Retention Breakdown

New ({uniquePercentage}%)
Returning ({returningPercentage}%)
{returningCount}
Repeat Visits
); } export default VisitorAnalytics;