"use client" import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { useToast } from "@/hooks/use-toast"; import { Skeleton } from "@/components/ui/skeleton"; import { Users, Crown, UserPlus, UserCheck, Star, ChevronLeft, ChevronRight } from "lucide-react"; import { getCustomerInsightsWithStore, type CustomerInsights } from "@/lib/services/analytics-service"; import { formatGBP } from "@/utils/format"; import { CustomerInsightsSkeleton } from './SkeletonLoaders'; export default function CustomerInsightsChart() { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const { toast } = useToast(); useEffect(() => { const fetchCustomerData = async () => { try { setIsLoading(true); setError(null); const response = await getCustomerInsightsWithStore(currentPage, pageSize); setData(response); } catch (err) { console.error('Error fetching customer insights:', err); setError('Failed to load customer data'); toast({ title: "Error", description: "Failed to load customer insights data.", variant: "destructive", }); } finally { setIsLoading(false); } }; fetchCustomerData(); }, [toast, currentPage, pageSize]); const getSegmentColor = (segment: string) => { switch (segment) { case 'new': return 'bg-blue-500'; case 'returning': return 'bg-green-500'; case 'loyal': return 'bg-purple-500'; case 'vip': return 'bg-yellow-500'; default: return 'bg-gray-500'; } }; const getSegmentIcon = (segment: string) => { switch (segment) { case 'new': return ; case 'returning': return ; case 'loyal': return ; case 'vip': return ; default: return ; } }; const getSegmentLabel = (segment: string) => { switch (segment) { case 'new': return 'New Customers'; case 'returning': return 'Returning Customers'; case 'loyal': return 'Loyal Customers'; case 'vip': return 'VIP Customers'; default: return 'Unknown'; } }; if (isLoading) { return ( ); } if (error || !data) { return ( Customer Insights

Failed to load customer data

); } const segments = Object.entries(data.segments); const totalCustomers = data.totalCustomers; const handlePageChange = (newPage: number) => { setCurrentPage(newPage); }; const handlePageSizeChange = (newPageSize: string) => { setPageSize(parseInt(newPageSize)); setCurrentPage(1); // Reset to first page when changing page size }; return (
{/* Customer Overview */} Customer Overview Total customers and average orders per customer
{data.totalCustomers}
Total Customers
{data.averageOrdersPerCustomer}
Avg Orders/Customer
{/* Customer Segments */} Customer Segments Breakdown of customers by purchase frequency
{segments.map(([segment, count]) => { const percentage = totalCustomers > 0 ? (count / totalCustomers * 100).toFixed(1) : '0'; const Icon = getSegmentIcon(segment); return (
{Icon}
{getSegmentLabel(segment)}
{count} customers
{percentage}%
of total
); })}
{/* Top Customers */} Top Customers Your highest-spending customers {data.pagination && ( (Showing {data.pagination.startIndex}-{data.pagination.endIndex} of {data.pagination.totalCustomers}) )} {data.topCustomers.length === 0 ? (

No customer data available

) : ( <>
{data.topCustomers.map((customer, index) => { const globalRank = data.pagination ? (data.pagination.currentPage - 1) * data.pagination.limit + index + 1 : index + 1; return (
{globalRank}
{customer.displayName || `Customer #${customer._id.slice(-6)}`}
{customer.orderCount} orders
{formatGBP(customer.totalSpent)}
{formatGBP(customer.averageOrderValue)} avg
); })}
{/* Pagination Controls */} {data.pagination && data.pagination.totalPages > 1 && (
Show customers per page
Page {data.pagination.currentPage} of {data.pagination.totalPages}
)} )}
); }