spdniloy/anycoder-380d34cb
0
1import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';2 3const COLORS = {4 income: {5 Sales: '#4caf50',6 Services: '#66bb6a',7 Consulting: '#81c784',8 Subscriptions: '#a5d6a7',9 Refunds: '#c8e6c9',10 'Other Income': '#e8f5e9',11 },12 expense: {13 Supplies: '#ef5350',14 Equipment: '#e57373',15 Marketing: '#ef9a9a',16 Utilities: '#ffcdd2',17 Software: '#ffebee',18 Travel: '#ffcdd2',19 'Professional Services': '#ef5350',20 Taxes: '#e57373',21 Other: '#ffebee',22 },23};24 25export default function CategoryChart({ transactions, type }) {26 const filtered = transactions.filter((t) => t.type === type);27 28 const data = filtered.reduce((acc, t) => {29 const existing = acc.find((item) => item.name === t.category);30 if (existing) {31 existing.value += t.amount;32 } else {33 acc.push({ name: t.category, value: t.amount });34 }35 return acc;36 }, []);37 38 const total = data.reduce((sum, item) => sum + item.value, 0);39 40 if (data.length === 0) {41 return (42 <div className="text-center py-12">43 <p className="text-neutral-400">No {type} data to display</p>44 </div>45 );46 }47 48 const colors = type === 'income' ? COLORS.income : COLORS.expense;49 50 return (51 <div className="h-64">52 <ResponsiveContainer width="100%" height="100%">53 <PieChart>54 <Pie55 data={data}56 cx="50%"57 cy="50%"58 innerRadius={60}59 outerRadius={80}60 paddingAngle={2}61 dataKey="value"62 >63 {data.map((entry, index) => (64 <Cell65 key={`cell-${index}`}66 fill={colors[entry.name] || '#9e9e9e'}67 />68 ))}69 </Pie>70 <Tooltip71 formatter={(value) => `$${value.toLocaleString()}`}72 contentStyle={{73 backgroundColor: '#fff',74 border: '1px solid #e0e0e0',75 borderRadius: '8px',76 boxShadow: '0 2px 8px rgba(0,0,0,0.1)',77 78 />79 <Legend80 formatter={(value) => (81 <span className="text-sm text-neutral-600">{value}</span>82 )}83 />84 </PieChart>85 </ResponsiveContainer>86 <div className="text-center mt-2">87 <span className="text-lg font-semibold text-neutral-800">88 ${total.toLocaleString()}89 </span>90 <span className="text-sm text-neutral-500 ml-2">total</span>91 </div>92 </div>93 );94}