"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { TrendingUp, TrendingDown, Calculator, DollarSign } from "lucide-react"; import { toast } from "sonner"; import { apiRequest } from "@/lib/api"; interface ProfitAnalysisModalProps { open: boolean; onClose: () => void; productId: string; productName: string; } interface ProfitData { productId: string; name: string; costPerUnit: number; pricing: Array<{ minQuantity: number; pricePerUnit: number; }>; profitMargins: Array<{ minQuantity: number; pricePerUnit: number; profit: number | null; profitMargin: number | null; markup: number | null; }>; summary: { hasCostData: boolean; averageProfit: number | null; averageProfitMargin: number | null; averageMarkup: number | null; }; } export const ProfitAnalysisModal: React.FC = ({ open, onClose, productId, productName, }) => { const [profitData, setProfitData] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { if (open && productId) { fetchProfitAnalysis(); } }, [open, productId]); const fetchProfitAnalysis = async () => { try { setLoading(true); const response = await apiRequest(`/products/${productId}/profit-analysis`); setProfitData(response); } catch (error) { console.error("Error fetching profit analysis:", error); toast.error("Failed to load profit analysis"); } finally { setLoading(false); } }; const formatCurrency = (amount: number | null) => { if (amount === null) return "N/A"; return `£${amount.toFixed(2)}`; }; const formatPercentage = (percentage: number | null) => { if (percentage === null) return "N/A"; return `${percentage.toFixed(1)}%`; }; const getProfitColor = (profit: number | null) => { if (profit === null) return "text-muted-foreground"; return profit >= 0 ? "text-green-600" : "text-red-600"; }; const getProfitIcon = (profit: number | null) => { if (profit === null) return Calculator; return profit >= 0 ? TrendingUp : TrendingDown; }; if (loading) { return ( Profit Analysis - {productName}

Loading profit analysis...

); } if (!profitData) { return ( Profit Analysis - {productName}

No profit data available

); } return ( Profit Analysis - {productName}
{/* Summary Cards */} {profitData.summary.hasCostData ? (
Average Profit
{formatCurrency(profitData.summary.averageProfit)}

Per unit sold

Average Profit Margin
{formatPercentage(profitData.summary.averageProfitMargin)}

Of selling price

Average Markup
{formatPercentage(profitData.summary.averageMarkup)}

On cost price

) : (

No Cost Data Available

Add a cost per unit to this product to see profit calculations.

Cost Per Unit: {formatCurrency(profitData.costPerUnit)}
)} {/* Cost Information */} Cost Information
Cost Per Unit: {formatCurrency(profitData.costPerUnit)}
{/* Pricing Tier Analysis */} Pricing Tier Analysis
{profitData.profitMargins .sort((a, b) => a.minQuantity - b.minQuantity) .map((tier, index) => { const ProfitIcon = getProfitIcon(tier.profit); const totalProfitForMinQty = tier.profit !== null ? tier.profit * tier.minQuantity : null; const totalRevenueForMinQty = tier.pricePerUnit * tier.minQuantity; const totalCostForMinQty = profitData.costPerUnit * tier.minQuantity; return (

{tier.minQuantity}+ units @ {formatCurrency(tier.pricePerUnit)}

Revenue for {tier.minQuantity} units: {formatCurrency(totalRevenueForMinQty)}

Cost for {tier.minQuantity} units: {formatCurrency(totalCostForMinQty)}

Total Profit: {formatCurrency(totalProfitForMinQty)}
Per unit: {formatCurrency(tier.profit)}
Margin: {formatPercentage(tier.profitMargin)} | Markup: {formatPercentage(tier.markup)}
); })}
{/* Help Text */}

Understanding the Metrics:

  • Profit: Selling price minus cost price
  • Profit Margin: Profit as a percentage of selling price
  • Markup: Profit as a percentage of cost price
); };