anycoder-380d34cb / components /CategoryChart.js
spdniloy's picture
Upload components/CategoryChart.js with huggingface_hub
16a10dd verified
Raw
History Blame Contribute Delete
2.53 kB
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';
const COLORS = {
income: {
Sales: '#4caf50',
Services: '#66bb6a',
Consulting: '#81c784',
Subscriptions: '#a5d6a7',
Refunds: '#c8e6c9',
'Other Income': '#e8f5e9',
},
expense: {
Supplies: '#ef5350',
Equipment: '#e57373',
Marketing: '#ef9a9a',
Utilities: '#ffcdd2',
Software: '#ffebee',
Travel: '#ffcdd2',
'Professional Services': '#ef5350',
Taxes: '#e57373',
Other: '#ffebee',
},
};
export default function CategoryChart({ transactions, type }) {
const filtered = transactions.filter((t) => t.type === type);
const data = filtered.reduce((acc, t) => {
const existing = acc.find((item) => item.name === t.category);
if (existing) {
existing.value += t.amount;
} else {
acc.push({ name: t.category, value: t.amount });
}
return acc;
}, []);
const total = data.reduce((sum, item) => sum + item.value, 0);
if (data.length === 0) {
return (
<div className="text-center py-12">
<p className="text-neutral-400">No {type} data to display</p>
</div>
);
}
const colors = type === 'income' ? COLORS.income : COLORS.expense;
return (
<div className="h-64">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
data={data}
cx="50%"
cy="50%"
innerRadius={60}
outerRadius={80}
paddingAngle={2}
dataKey="value"
>
{data.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={colors[entry.name] || '#9e9e9e'}
/>
))}
</Pie>
<Tooltip
formatter={(value) => `$${value.toLocaleString()}`}
contentStyle={{
backgroundColor: '#fff',
border: '1px solid #e0e0e0',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
/>
<Legend
formatter={(value) => (
<span className="text-sm text-neutral-600">{value}</span>
)}
/>
</PieChart>
</ResponsiveContainer>
<div className="text-center mt-2">
<span className="text-lg font-semibold text-neutral-800">
${total.toLocaleString()}
</span>
<span className="text-sm text-neutral-500 ml-2">total</span>
</div>
</div>
);
}