import { useState } from 'react'; import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, } from 'recharts'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import type { CostBreakdown as CostBreakdownType } from '@/types/api'; import { CHART_COLORS, formatCurrency } from './chart-utils'; interface CostBreakdownChartProps { data: CostBreakdownType[]; title?: string; description?: string; } // Map services to colors const SERVICE_COLORS: Record = { sqs: CHART_COLORS.sqs, lambda: CHART_COLORS.lambda, bedrock: CHART_COLORS.bedrock, s3: CHART_COLORS.blue, cloudwatch: CHART_COLORS.green, default: CHART_COLORS.secondary, }; function getServiceColor(service: string): string { const normalized = service.toLowerCase().replace(/[^a-z]/g, ''); return SERVICE_COLORS[normalized] || SERVICE_COLORS.default; } // Tooltip component defined outside main component interface CostTooltipProps { active?: boolean; payload?: Array<{ payload: CostBreakdownType }>; } function CostTooltip({ active, payload }: CostTooltipProps) { if (active && payload && payload.length) { const item = payload[0].payload; return (

{item.service}

Cost: {formatCurrency(item.cost_usd)}

Percentage: {item.percentage.toFixed(1)}%

); } return null; } export function CostBreakdownChart({ data, title = 'Cost Breakdown', description = 'Cost distribution by service', }: CostBreakdownChartProps) { const [hiddenServices, setHiddenServices] = useState>(new Set()); const filteredData = data.filter((item) => !hiddenServices.has(item.service)); const toggleService = (service: string) => { setHiddenServices((prev) => { const next = new Set(prev); if (next.has(service)) { next.delete(service); } else { next.add(service); } return next; }); }; const totalCost = filteredData.reduce((sum, item) => sum + item.cost_usd, 0); return ( {title} {description && (

{description}

)}

{formatCurrency(totalCost)}

{filteredData.map((entry) => ( ))} } />
{data.map((item) => { const isHidden = hiddenServices.has(item.service); return ( ); })}
); }