import { useState, useRef, useCallback } from "react"; import { useTranslation } from "react-i18next"; import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, Cell, LabelList, } from "recharts"; import { Eye } from "lucide-react"; import type { CategoryBreakdownItem } from "../../shared/types"; import { ChartPatternDefs, getPatternFill } from "../../utils/chartPatterns"; import ChartContextMenu from "../shared/ChartContextMenu"; const cadFormatter = (value: number) => new Intl.NumberFormat("en-CA", { style: "currency", currency: "CAD", maximumFractionDigits: 0 }).format(value); interface CategoryBarChartProps { data: CategoryBreakdownItem[]; hiddenCategories: Set; onToggleHidden: (categoryName: string) => void; onShowAll: () => void; onViewDetails: (item: CategoryBreakdownItem) => void; showAmounts?: boolean; } export default function CategoryBarChart({ data, hiddenCategories, onToggleHidden, onShowAll, onViewDetails, showAmounts, }: CategoryBarChartProps) { const { t } = useTranslation(); const hoveredRef = useRef(null); const [hoveredIndex, setHoveredIndex] = useState(null); const [contextMenu, setContextMenu] = useState<{ x: number; y: number; item: CategoryBreakdownItem } | null>(null); const visibleData = data.filter((d) => !hiddenCategories.has(d.category_name)); const handleContextMenu = useCallback((e: React.MouseEvent) => { if (!hoveredRef.current) return; e.preventDefault(); setContextMenu({ x: e.clientX, y: e.clientY, item: hoveredRef.current }); }, []); if (data.length === 0) { return (

{t("dashboard.noData")}

); } return (
{hiddenCategories.size > 0 && (
{t("charts.hiddenCategories")}: {Array.from(hiddenCategories).map((name) => ( ))}
)}
({ color: item.category_color, index }))} /> cadFormatter(v)} tick={{ fill: "var(--muted-foreground)", fontSize: 12 }} stroke="var(--border)" /> cadFormatter(value ?? 0)} contentStyle={{ backgroundColor: "var(--card)", border: "1px solid var(--border)", borderRadius: "8px", color: "var(--foreground)", }} labelStyle={{ color: "var(--foreground)" }} itemStyle={{ color: "var(--foreground)" }} /> {visibleData.map((item, index) => ( { hoveredRef.current = item; setHoveredIndex(index); }} onMouseLeave={() => { hoveredRef.current = null; setHoveredIndex(null); }} cursor="context-menu" style={{ transition: "fill-opacity 150ms" }} /> ))} {showAmounts && ( cadFormatter(Number(v))} style={{ fill: "var(--foreground)", fontSize: 11 }} /> )}
{contextMenu && ( onToggleHidden(contextMenu.item.category_name)} onViewDetails={() => onViewDetails(contextMenu.item)} onClose={() => setContextMenu(null)} /> )}
); }