80 lines
3.4 KiB
TypeScript
80 lines
3.4 KiB
TypeScript
import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
|
|
import { BudgetExecutionDTO } from '@/types/budget';
|
|
import { formatCurrency } from '@/utils/locale';
|
|
|
|
interface BudgetExecutionChartProps {
|
|
data: BudgetExecutionDTO[];
|
|
}
|
|
|
|
export function BudgetExecutionChart({ data = [] }: BudgetExecutionChartProps) {
|
|
// Aggregate data by type
|
|
const chartData = [
|
|
{
|
|
name: 'Compromissos',
|
|
valor: data
|
|
.filter((e) => e.movementType === 'COMMITMENT')
|
|
.reduce((sum, e) => sum + e.amount, 0),
|
|
fill: '#f97316', // orange-500
|
|
},
|
|
{
|
|
name: 'Liquidações',
|
|
valor: data
|
|
.filter((e) => e.movementType === 'LIQUIDATION')
|
|
.reduce((sum, e) => sum + e.amount, 0),
|
|
fill: '#3b82f6', // blue-500
|
|
},
|
|
{
|
|
name: 'Pagamentos',
|
|
valor: data
|
|
.filter((e) => e.movementType === 'PAYMENT')
|
|
.reduce((sum, e) => sum + e.amount, 0),
|
|
fill: '#22c55e', // green-500
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="bg-white p-6 rounded-xl shadow-sm border border-gray-100">
|
|
<h3 className="text-lg font-bold text-gray-900 mb-6">Resumo da Execução Orçamentária</h3>
|
|
<div className="h-[300px] w-full">
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<BarChart data={chartData}>
|
|
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f3f4f6" />
|
|
<XAxis
|
|
dataKey="name"
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{ fill: '#6b7280', fontSize: 12 }}
|
|
/>
|
|
<YAxis
|
|
axisLine={false}
|
|
tickLine={false}
|
|
tick={{ fill: '#6b7280', fontSize: 12 }}
|
|
tickFormatter={(value) => formatCurrency(value).split(',')[0]} // Simplified currency
|
|
/>
|
|
<Tooltip
|
|
formatter={(value: number, name: string) => [formatCurrency(value), name]}
|
|
contentStyle={{ borderRadius: '8px', border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }}
|
|
labelStyle={{ color: '#374151', fontWeight: 600, marginBottom: '0.5rem' }}
|
|
/>
|
|
<Bar
|
|
dataKey="valor"
|
|
radius={[4, 4, 0, 0]}
|
|
barSize={60}
|
|
/>
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
<div className="mt-4 grid grid-cols-3 gap-4">
|
|
{chartData.map((item) => (
|
|
<div key={item.name} className="text-center p-3 rounded-lg bg-gray-50">
|
|
<p className="text-xs text-gray-500 uppercase font-semibold mb-1">{item.name}</p>
|
|
<p className="text-sm font-bold" style={{ color: item.fill }}>
|
|
{formatCurrency(item.valor)}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|