"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 } 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"; // Lazy load chart components const RevenueChart = dynamic(() => import('./RevenueChart'), { loading: () => }); const ProductPerformanceChart = dynamic(() => import('./ProductPerformanceChart'), { loading: () => }); const CustomerInsightsChart = dynamic(() => import('./CustomerInsightsChart'), { loading: () => }); const OrderAnalyticsChart = dynamic(() => import('./OrderAnalyticsChart'), { 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('30'); const { toast } = useToast(); 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: formatGBP(data.revenue.total), description: "All-time revenue", icon: DollarSign, trend: data.revenue.monthly > 0 ? "up" as const : "neutral" as const, trendValue: `${formatGBP(data.revenue.monthly)} this month` }, { title: "Total Orders", value: data.orders.total.toLocaleString(), description: "All-time orders", icon: ShoppingCart, trend: data.orders.completed > 0 ? "up" as const : "neutral" as const, trendValue: `${data.orders.completed} completed` }, { title: "Unique Customers", value: data.customers.unique.toLocaleString(), description: "Total customers", icon: Users, trend: "neutral" as const, trendValue: "Lifetime customers" }, { title: "Products", value: data.products.total.toLocaleString(), description: "Active products", icon: Package, trend: "neutral" as const, trendValue: "In your store" } ]; return ( {/* 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 ? ( ) : ( {data.orders.completionRate}% {data.orders.completed} / {data.orders.total} )} {/* Time Period Selector */} Time period: Revenue and Orders tabs use time filtering. Products and Customers show all-time data. Last 7 days Last 30 days Last 90 days {/* Analytics Tabs */} Revenue Products Customers Orders }> }> }> }> ); }
Revenue and Orders tabs use time filtering. Products and Customers show all-time data.