"use client"; import { useState, useEffect, Suspense } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { TrendingUp, ShoppingCart, Users, Package, DollarSign, BarChart3, PieChart, Activity, RefreshCw, Eye, EyeOff, Calculator, } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; import MetricsCard from "./MetricsCard"; import { getAnalyticsOverviewWithStore, type AnalyticsOverview, } from "@/lib/services/analytics-service"; import { formatGBP } from "@/utils/format"; import { MetricsCardSkeleton } from "./SkeletonLoaders"; import dynamic from "next/dynamic"; import { Skeleton } from "@/components/ui/skeleton"; import { DateRangePicker } from "@/components/ui/date-picker"; import { DateRange } from "react-day-picker"; import { addDays, startOfDay, endOfDay } from "date-fns"; import type { DateRange as ProfitDateRange } from "@/lib/services/profit-analytics-service"; // Lazy load chart components - already handled individually below const RevenueChart = dynamic(() => import("./RevenueChart"), { loading: () => , }); const ProductPerformanceChart = dynamic( () => import("./ProductPerformanceChart"), { loading: () => , }, ); const CustomerInsightsChart = dynamic(() => import("./CustomerInsightsChart"), { loading: () => , }); const OrderAnalyticsChart = dynamic(() => import("./OrderAnalyticsChart"), { loading: () => , }); const ProfitAnalyticsChart = dynamic(() => import("./ProfitAnalyticsChart"), { loading: () => , }); const GrowthAnalyticsChart = dynamic(() => import("./GrowthAnalyticsChart"), { loading: () => , }); const PredictionsChart = dynamic(() => import("./PredictionsChart"), { loading: () => , }); // Chart loading skeleton function ChartSkeleton() { return (
); } interface AnalyticsDashboardProps { initialData: AnalyticsOverview; } export default function AnalyticsDashboard({ initialData, }: AnalyticsDashboardProps) { const [data, setData] = useState(initialData); const [isLoading, setIsLoading] = useState(false); const [timeRange, setTimeRange] = useState("90"); const [hideNumbers, setHideNumbers] = useState(false); const [profitDateRange, setProfitDateRange] = useState( { from: startOfDay(addDays(new Date(), -29)), to: endOfDay(new Date()), }, ); const { toast } = useToast(); // Function to mask sensitive numbers const maskValue = (value: string): string => { if (!hideNumbers) return value; // For currency values (£X.XX), show £*** if (value.includes("£")) { return "£***"; } // For regular numbers, replace with asterisks maintaining similar length if (value.match(/^\d/)) { const numLength = value.replace(/[,\.]/g, "").length; return "*".repeat(Math.min(numLength, 4)); } return value; }; const refreshData = async () => { try { setIsLoading(true); const newData = await getAnalyticsOverviewWithStore(); setData(newData); toast({ title: "Data refreshed", description: "Analytics data has been updated successfully.", }); } catch (error) { toast({ title: "Error", description: "Failed to refresh analytics data.", variant: "destructive", }); } finally { setIsLoading(false); } }; const metrics = [ { title: "Total Revenue", value: maskValue(formatGBP(data.revenue.total)), description: "All-time revenue", icon: DollarSign, trend: data.revenue.monthly > 0 ? ("up" as const) : ("neutral" as const), trendValue: hideNumbers ? "Hidden" : `${formatGBP(data.revenue.monthly)} this month`, }, { title: "Total Orders", value: maskValue(data.orders.total.toLocaleString()), description: "All-time orders", icon: ShoppingCart, trend: data.orders.completed > 0 ? ("up" as const) : ("neutral" as const), trendValue: hideNumbers ? "Hidden" : `${data.orders.completed} completed`, }, { title: "Unique Customers", value: maskValue(data.customers.unique.toLocaleString()), description: "Total customers", icon: Users, trend: "neutral" as const, trendValue: "Lifetime customers", }, { title: "Products", value: maskValue(data.products.total.toLocaleString()), description: "Active products", icon: Package, trend: "neutral" as const, trendValue: "In your store", }, ]; return (
{/* Header with Privacy Toggle */}

Analytics Dashboard

Overview of your store's performance and metrics.

{/* Key Metrics Cards */}
{isLoading ? [...Array(4)].map((_, i) => ) : metrics.map((metric) => ( ))}
{/* Completion Rate Card */} Order Completion Rate Percentage of orders that have been successfully completed {isLoading ? (
) : (
{hideNumbers ? "**%" : `${data.orders.completionRate}%`}
{hideNumbers ? "** / **" : `${data.orders.completed} / ${data.orders.total}`}
)} {/* Time Period Selector */}

Time Period

Revenue, Profit, and Orders tabs use time filtering. Products and Customers show all-time data.

{/* Analytics Tabs */}
Growth Revenue Profit Products Customers Orders Predictions }> }> {/* Date Range Selector for Profit Calculator */} Date Range Select a custom date range for profit calculations
{profitDateRange?.from && profitDateRange?.to && (
{profitDateRange.from.toLocaleDateString()} -{" "} {profitDateRange.to.toLocaleDateString()}
)}
}>
}> }> }> }>
); }