import React, { useState, useEffect } from 'react'; import { AuthProvider, AuthGuard, useAuth } from './AdminAuth'; import AdminLayout from './AdminLayout'; import { LineChart, Line, BarChart, Bar, PieChart, Pie, Cell, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, ComposedChart } from 'recharts'; const COLORS = ['#00FF6A', '#00CC55', '#FF6B35', '#FFD700', '#FF3B3B', '#6366F1', '#06B6D4']; function StatCard({ label, value, icon }: { label: string; value: string | number; icon: string }) { return (
{label} {icon}
{value}
); } function fmt(n: number) { return `€${Number(n).toFixed(2)}`; } function RevenueContent() { const { token } = useAuth(); const [days, setDays] = useState(30); const [overview, setOverview] = useState(null); const [timeseries, setTimeseries] = useState([]); const [byShop, setByShop] = useState([]); const [byProduct, setByProduct] = useState([]); const [bySource, setBySource] = useState([]); const [byNetwork, setByNetwork] = useState([]); const [loading, setLoading] = useState(true); const headers = { Authorization: `Bearer ${token}` }; useEffect(() => { setLoading(true); Promise.all([ fetch(`/api/admin/revenue?view=overview`, { headers }).then(r => r.json()), fetch(`/api/admin/revenue?view=timeseries&days=${days}`, { headers }).then(r => r.json()), fetch(`/api/admin/revenue?view=by-shop&days=${days}`, { headers }).then(r => r.json()), fetch(`/api/admin/revenue?view=by-product&days=${days}`, { headers }).then(r => r.json()), fetch(`/api/admin/revenue?view=by-source&days=${days}`, { headers }).then(r => r.json()), fetch(`/api/admin/revenue?view=by-network&days=${days}`, { headers }).then(r => r.json()), ]).then(([ov, ts, shop, prod, src, net]) => { setOverview(ov); setTimeseries(ts.data || []); setByShop(shop.data || []); setByProduct(prod.data || []); setBySource(src.data || []); setByNetwork(net.data || []); }).finally(() => setLoading(false)); }, [days]); if (loading) return (
); return ( {/* Period toggle */}
{[30, 90].map(d => ( ))}
{/* Overview cards */} {overview && (
)} {/* Revenue timeseries */}

Revenue & Conversies

{timeseries.length === 0 ? (
Geen data beschikbaar
) : ( )}
{/* Revenue by shop */}

Revenue per Shop

{byShop.length === 0 ? (
Geen data
) : ( )}
{/* Revenue by source */}

Revenue per Bron

{bySource.length === 0 ? (
Geen data
) : ( `${source} (${(percent * 100).toFixed(0)}%)`}> {bySource.map((_, i) => )} )}
{/* Revenue by product */}

Top 20 Producten

{byProduct.length === 0 ? (
Geen data
) : (
{byProduct.map((p: any, i: number) => ( ))}
ProductClicksConv.RevenueCR%
{p.product} {p.clicks} {p.conversions} {fmt(p.revenue)} {p.cr}%
)}
{/* Network breakdown */}

Network Breakdown

{byNetwork.length === 0 ? (
Geen data
) : ( <> network}> {byNetwork.map((_, i) => )}
{byNetwork.map((n: any, i: number) => (
{n.network || 'Unknown'} {fmt(n.revenue)} ({n.conversions} conv.)
))}
)}
); } export default function RevenueDashboard() { return ; }