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 (
);
}
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 (
{p.pageviews} views
{clicks.toLocaleString()} clicks
{p.ctr}% CTR
€{revenue.toFixed(2)}
);
})}
)}
{sourceData.length > 0 && (
Traffic Sources
{sourceData.map((_, i) => | )}
{sourceData.map((s, i) => (
))}
)}
);
}
export default function AnalyticsPage() {
return ;
}