import { useState, useEffect, useMemo } from "react"; import { supabase } from "@/integrations/supabase/client"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, LineChart, Line, Legend, } from "recharts"; import { TrendingUp, TrendingDown, DollarSign, ShoppingCart, Users, CreditCard, Calendar, RefreshCw, } from "lucide-react"; import { CONFIG } from "@/config/payments"; interface Order { id: string; amount: number; status: string; payment_method: string; created_at: string; customer_email: string; } const COLORS = ["hsl(142, 76%, 36%)", "hsl(38, 92%, 50%)", "hsl(0, 84%, 60%)", "hsl(240, 4%, 46%)"]; const AnalyticsTab = () => { const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(true); const [timeRange, setTimeRange] = useState("30"); useEffect(() => { fetchOrders(); }, [timeRange]); const fetchOrders = async () => { setLoading(true); try { const startDate = new Date(); startDate.setDate(startDate.getDate() - parseInt(timeRange)); const { data, error } = await supabase .from("orders") .select("id, amount, status, payment_method, created_at, customer_email") .gte("created_at", startDate.toISOString()) .order("created_at", { ascending: true }); if (error) throw error; setOrders(data || []); } catch (error) { console.error("Failed to fetch analytics data:", error); } finally { setLoading(false); } }; const stats = useMemo(() => { const verifiedOrders = orders.filter(o => o.status === "verified" || o.status === "completed"); const totalRevenue = verifiedOrders.reduce((sum, o) => sum + Number(o.amount), 0); const avgOrderValue = verifiedOrders.length > 0 ? totalRevenue / verifiedOrders.length : 0; const uniqueCustomers = new Set(orders.map(o => o.customer_email)).size; const conversionRate = orders.length > 0 ? (verifiedOrders.length / orders.length) * 100 : 0; return { totalRevenue, totalOrders: orders.length, verifiedOrders: verifiedOrders.length, avgOrderValue, uniqueCustomers, conversionRate, }; }, [orders]); const revenueByDay = useMemo(() => { const grouped: Record = {}; orders.forEach(order => { if (order.status === "verified" || order.status === "completed") { const date = new Date(order.created_at).toLocaleDateString("en-US", { month: "short", day: "numeric", }); if (!grouped[date]) { grouped[date] = { date, revenue: 0, orders: 0 }; } grouped[date].revenue += Number(order.amount); grouped[date].orders += 1; } }); return Object.values(grouped); }, [orders]); const paymentMethodData = useMemo(() => { const grouped: Record = {}; orders.forEach(order => { const method = order.payment_method || "unknown"; grouped[method] = (grouped[method] || 0) + 1; }); return Object.entries(grouped).map(([name, value]) => ({ name: name.charAt(0).toUpperCase() + name.slice(1), value, })); }, [orders]); const statusData = useMemo(() => { const grouped: Record = {}; orders.forEach(order => { grouped[order.status] = (grouped[order.status] || 0) + 1; }); return Object.entries(grouped).map(([name, value]) => ({ name: name.charAt(0).toUpperCase() + name.slice(1), value, })); }, [orders]); if (loading) { return (
Loading analytics...
); } return (
{/* Time Range Selector */}

Analytics Overview

{/* Key Metrics */}
Total Revenue
{CONFIG.store.currencySymbol}{stats.totalRevenue.toFixed(2)}

From {stats.verifiedOrders} verified orders

Total Orders
{stats.totalOrders}

{stats.verifiedOrders} completed

Avg. Order Value
{CONFIG.store.currencySymbol}{stats.avgOrderValue.toFixed(2)}

Per verified order

Conversion Rate
{stats.conversionRate.toFixed(1)}%

{stats.uniqueCustomers} unique customers

{/* Charts */}
{/* Revenue Over Time */} Revenue Over Time {revenueByDay.length === 0 ? (
No revenue data for this period
) : ( `$${value}`} /> [`$${value.toFixed(2)}`, "Revenue"]} /> )}
{/* Orders by Status */} Orders by Status {statusData.length === 0 ? (
No order data for this period
) : ( `${name}: ${value}`} > {statusData.map((_, index) => ( ))} )}
{/* Payment Methods */} Orders by Payment Method {paymentMethodData.length === 0 ? (
No payment data for this period
) : ( [value, "Orders"]} /> )}
); }; export default AnalyticsTab;