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 (
);
}
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
) : (
| Product | Clicks | Conv. | Revenue | CR% |
{byProduct.map((p: any, i: number) => (
| {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 ;
}