Handle cashback commission imports, include commissions in analytics with separate investment metrics, and expose commission/version details in the UI. Made-with: Cursor
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
import {
|
||
BarChart,
|
||
Bar,
|
||
XAxis,
|
||
YAxis,
|
||
CartesianGrid,
|
||
Tooltip,
|
||
Legend,
|
||
ResponsiveContainer,
|
||
} from 'recharts';
|
||
import type { TimeseriesItem } from '@family-budget/shared';
|
||
import { useMediaQuery } from '../hooks/useMediaQuery';
|
||
|
||
interface Props {
|
||
data: TimeseriesItem[];
|
||
}
|
||
|
||
const rubFormatter = new Intl.NumberFormat('ru-RU', {
|
||
style: 'currency',
|
||
currency: 'RUB',
|
||
maximumFractionDigits: 0,
|
||
});
|
||
|
||
export function TimeseriesChart({ data }: Props) {
|
||
const isMobile = useMediaQuery('(max-width: 600px)');
|
||
const chartHeight = isMobile ? 250 : 300;
|
||
|
||
if (data.length === 0) {
|
||
return <div className="chart-empty">Нет данных за период</div>;
|
||
}
|
||
|
||
const chartData = data.map((item) => ({
|
||
period: item.periodStart,
|
||
Расходы: Math.abs(item.expenseAmount) / 100,
|
||
Доходы: item.incomeAmount / 100,
|
||
Инвестиции: Math.abs(item.investmentOutflow) / 100,
|
||
}));
|
||
|
||
return (
|
||
<ResponsiveContainer width="100%" height={chartHeight}>
|
||
<BarChart data={chartData}>
|
||
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
|
||
<XAxis
|
||
dataKey="period"
|
||
tickFormatter={(v: string) => {
|
||
const d = new Date(v);
|
||
return `${d.getDate()}.${String(d.getMonth() + 1).padStart(2, '0')}`;
|
||
}}
|
||
fontSize={12}
|
||
stroke="#64748b"
|
||
/>
|
||
<YAxis
|
||
tickFormatter={(v: number) =>
|
||
v >= 1000 ? `${(v / 1000).toFixed(0)}к` : String(v)
|
||
}
|
||
fontSize={12}
|
||
stroke="#64748b"
|
||
/>
|
||
<Tooltip
|
||
formatter={(value: number) => rubFormatter.format(value)}
|
||
/>
|
||
<Legend />
|
||
<Bar
|
||
dataKey="Расходы"
|
||
fill="#ef4444"
|
||
radius={[4, 4, 0, 0]}
|
||
/>
|
||
<Bar
|
||
dataKey="Доходы"
|
||
fill="#10b981"
|
||
radius={[4, 4, 0, 0]}
|
||
/>
|
||
<Bar
|
||
dataKey="Инвестиции"
|
||
fill="#f59e0b"
|
||
radius={[4, 4, 0, 0]}
|
||
/>
|
||
</BarChart>
|
||
</ResponsiveContainer>
|
||
);
|
||
}
|