"use client" import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { TrendingUp, TrendingDown, DollarSign, PieChart, Calculator, Info, AlertTriangle } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; import { formatGBP } from "@/utils/format"; import { getProfitOverview, type ProfitOverview } from "@/lib/services/profit-analytics-service"; import { TableSkeleton } from './SkeletonLoaders'; interface ProfitAnalyticsChartProps { timeRange: string; hideNumbers?: boolean; } export default function ProfitAnalyticsChart({ timeRange, hideNumbers = false }: ProfitAnalyticsChartProps) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const { toast } = useToast(); const maskValue = (value: string): string => { if (!hideNumbers) return value; if (value.includes('£')) return '£***'; if (value.match(/^\d/)) { const numLength = value.replace(/[,\.%]/g, '').length; return '*'.repeat(Math.min(numLength, 4)); } return value; }; useEffect(() => { const fetchData = async () => { try { setIsLoading(true); setError(null); const response = await getProfitOverview(timeRange); setData(response); } catch (error) { console.error('Error fetching profit data:', error); setError('Failed to load profit analytics'); toast({ title: "Error", description: "Failed to load profit analytics data.", variant: "destructive", }); } finally { setIsLoading(false); } }; fetchData(); }, [timeRange, toast]); if (isLoading) { return ; } if (error || !data) { return ( Profit Analytics

Failed to load profit data

); } if (!data.hasCostData) { return ( Profit Analytics Track your actual profits based on sales and cost data No cost data available
Add cost prices to your products to see profit analytics. Go to Products → Edit → Cost & Profit Tracking section.
); } const profitDirection = data.summary.totalProfit >= 0; return (
{/* Summary Cards */}
Total Revenue
{maskValue(formatGBP(data.summary.totalRevenue))}

From {data.summary.totalProductsSold} items sold

Total Cost
{maskValue(formatGBP(data.summary.totalCost))}

From {data.summary.productsWithCostData} tracked items

Total Profit
{profitDirection ? ( ) : ( )} {maskValue(formatGBP(data.summary.totalProfit))}

{maskValue(`${data.summary.overallProfitMargin.toFixed(1)}%`)} margin

Avg Profit/Unit
{maskValue(formatGBP(data.summary.averageProfitPerUnit))}

Per unit sold

{/* Cost Data Coverage */} Cost Data Coverage Percentage of sold items that have cost data for profit calculation
{hideNumbers ? "**%" : `${data.summary.costDataCoverage.toFixed(1)}%`}
{hideNumbers ? "** / **" : `${data.summary.productsWithCostData} / ${data.summary.totalProductsSold}`}
{/* Top Profitable Products */} Most Profitable Products Products generating the highest total profit (last {timeRange} days) {data.topProfitableProducts.length === 0 ? (

No profitable products data available

) : (
{data.topProfitableProducts.map((product, index) => { const profitPositive = product.totalProfit >= 0; return (
{index + 1}

{product.productName}

{product.totalQuantitySold} units sold

{maskValue(formatGBP(product.totalProfit))}
{maskValue(`${product.profitMargin.toFixed(1)}%`)} margin
); })}
)}
); }