"use client"; import { useState, useEffect } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { useToast } from "@/hooks/use-toast"; import { RefreshCw } from "lucide-react"; import { getGrowthAnalyticsWithStore, type GrowthAnalytics, } from "@/lib/services/analytics-service"; import { ComposedChart, Bar, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from "recharts"; interface GrowthAnalyticsChartProps { hideNumbers?: boolean; } export default function GrowthAnalyticsChart({ hideNumbers = false, }: GrowthAnalyticsChartProps) { const [growthData, setGrowthData] = useState(null); const [growthLoading, setGrowthLoading] = useState(true); const { toast } = useToast(); const fetchGrowthData = async () => { try { setGrowthLoading(true); const response = await getGrowthAnalyticsWithStore(); setGrowthData(response); } catch (err) { console.error("Error fetching growth data:", err); toast({ title: "Error", description: "Failed to load growth analytics data.", variant: "destructive", }); } finally { setGrowthLoading(false); } }; useEffect(() => { fetchGrowthData(); }, []); const handleGrowthRefresh = () => { fetchGrowthData(); }; const formatCurrency = (value: number) => { if (hideNumbers) return "£***"; return new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP", maximumFractionDigits: 0, }).format(value); }; return (
{/* Growth Header */}

Growth Since First Sale

{growthData?.launchDate ? `Tracking since ${new Date(growthData.launchDate).toLocaleDateString("en-GB", { month: "long", year: "numeric" })}` : "Loading..."} {growthData?.generatedAt && ( - Last updated:{" "} {new Date(growthData.generatedAt).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit", })} )}

{/* Cumulative Stats Cards */} {growthData?.cumulative && (
Total Orders
{hideNumbers ? "***" : growthData.cumulative.orders.toLocaleString()}
Total Revenue
{formatCurrency(growthData.cumulative.revenue)}
Customers
{hideNumbers ? "***" : growthData.cumulative.customers.toLocaleString()}
Products
{hideNumbers ? "***" : growthData.cumulative.products.toLocaleString()}
Avg Order Value
{formatCurrency(growthData.cumulative.avgOrderValue)}
)} {/* Monthly Revenue & Orders Chart */} Monthly Revenue & Orders Store performance by month since first sale {growthLoading ? (
) : growthData?.monthly && growthData.monthly.length > 0 ? (
({ ...m, formattedMonth: new Date( m.month + "-01", ).toLocaleDateString("en-GB", { month: "short", year: "2-digit", }), }))} margin={{ top: 5, right: 30, left: 20, bottom: 5 }} > hideNumbers ? "***" : `£${(value / 1000).toFixed(0)}k` } /> { if (active && payload?.length) { const data = payload[0].payload; return (

{data.month}

Orders:{" "} {hideNumbers ? "***" : data.orders.toLocaleString()}

Revenue: {formatCurrency(data.revenue)}

Customers:{" "} {hideNumbers ? "***" : data.customers.toLocaleString()}

{data.newCustomers !== undefined && (

New Customers:{" "} {hideNumbers ? "***" : data.newCustomers}

)}
); } return null; }} />
) : (
No growth data available
)}
{/* Monthly Growth Table */} {growthData?.monthly && growthData.monthly.length > 0 && ( Monthly Breakdown Detailed metrics by month
{growthData.monthly.map((month) => ( ))}
Month Orders Revenue Customers Avg Order New Customers
{new Date(month.month + "-01").toLocaleDateString( "en-GB", { month: "long", year: "numeric" }, )} {hideNumbers ? "***" : month.orders.toLocaleString()} {formatCurrency(month.revenue)} {hideNumbers ? "***" : month.customers.toLocaleString()} {formatCurrency(month.avgOrderValue)} {hideNumbers ? "***" : (month.newCustomers ?? 0)}
)}
); }