import React, { useState, useEffect } from 'react'; import { AuthProvider, AuthGuard, useAuth } from './AdminAuth'; import AdminLayout from './AdminLayout'; import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'; const COLORS = ['#00FF6A', '#00CC55', '#FF6B35', '#FFD700', '#FF3B3B', '#6366F1', '#06B6D4']; interface OverviewData { total_clicks: number; total_conversions: number; total_revenue: number; total_pageviews: number; ctr: string; total_watchlist: number; active_price_watches: number; } interface TopProduct { product_id: string; product_name: string | null; slug: string | null; total_clicks: string; total_conversions: string; total_revenue: string; pageviews: number; ctr: string; } interface SourceData { source: string; total_clicks: string; } interface TimeseriesRow { date: string; clicks: number; conversions: number; revenue: number; } function StatCard({ label, value }: { label: string; value: string }) { return (
{value}
{label}
); } function AnalyticsContent() { const { token } = useAuth(); const [days, setDays] = useState(30); const [tab, setTab] = useState<'clicks' | 'revenue' | 'conversions'>('clicks'); const [timeseries, setTimeseries] = useState([]); const [overview, setOverview] = useState(null); const [topProducts, setTopProducts] = useState([]); const [sources, setSources] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const h = { Authorization: `Bearer ${token}` }; setLoading(true); Promise.all([ fetch(`/api/admin/analytics?type=timeseries&days=${days}`, { headers: h }).then(r => r.json()), fetch(`/api/admin/analytics?type=overview&days=${days}`, { headers: h }).then(r => r.json()), fetch(`/api/admin/analytics?type=top-products&days=${days}`, { headers: h }).then(r => r.json()), fetch(`/api/admin/analytics?type=sources&days=${days}`, { headers: h }).then(r => r.json()), ]).then(([ts, ov, tp, src]) => { setTimeseries(ts.data || []); setOverview(ov); setTopProducts(tp.data || []); setSources(src.data || []); }).catch(() => {}).finally(() => setLoading(false)); }, [token, days]); const hasData = timeseries.length > 0; if (loading) return
Laden...
; if (!hasData) { return (
📊
Begin met adverteren om analytics te zien
Zodra er clicks en conversies binnenkomen verschijnt hier je data
); } const totalClicks = Number(overview?.total_clicks || 0); const totalConversions = Number(overview?.total_conversions || 0); const totalRevenue = Number(overview?.total_revenue || 0); const totalPageviews = Number(overview?.total_pageviews || 0); const ctr = overview?.ctr || '0'; const totalWatchlist = Number(overview?.total_watchlist || 0); const activePriceWatches = Number(overview?.active_price_watches || 0); const sourceData = sources.map(s => ({ name: s.source || 'Unknown', value: Number(s.total_clicks || 0), })).filter(s => s.value > 0); return (
{[7, 14, 30, 90].map(d => ( ))}
0 ? `${((totalConversions / totalClicks) * 100).toFixed(2)}%` : '0%'} />
{(['clicks', 'revenue', 'conversions'] as const).map(t => ( ))}
v.slice(5)} />
{topProducts.length > 0 && (

Top Producten

{topProducts.slice(0, 10).map((p, i) => { const clicks = Number(p.total_clicks); const revenue = Number(p.total_revenue || 0); const displayName = p.product_name || p.product_id; return (
{i + 1}. {p.slug ? ( {displayName} ) : ( {displayName} )}
{p.pageviews} views {clicks.toLocaleString()} clicks {p.ctr}% CTR €{revenue.toFixed(2)}
); })}
)} {sourceData.length > 0 && (

Traffic Sources

{sourceData.map((_, i) => )}
{sourceData.map((s, i) => (
{s.name} {s.value}
))}
)}
); } export default function AnalyticsPage() { return ; }