65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
"use client";
|
||
import React, { useEffect, useState } from "react";
|
||
import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer } from "recharts";
|
||
import styles from "../styles/billing.module.css";
|
||
import Cookies from 'js-cookie';
|
||
|
||
const STATUS_COLORS: Record<string, string> = {
|
||
"done": "#10B981",
|
||
"waiting": "#F59E0B",
|
||
"error": "#EF4444",
|
||
"process": "#3B82F6",
|
||
"reject": "#800080",
|
||
"new": "#E30B5C",
|
||
};
|
||
|
||
const BillingPieChart: React.FC = () => {
|
||
const [data, setData] = useState<{ name: string; value: number; fill: string }[]>([]);
|
||
useEffect(() => {
|
||
const token = Cookies.get("access_token");
|
||
if (!token) {
|
||
console.warn("Токен авторизации не найден.");
|
||
return;
|
||
}
|
||
|
||
fetch("/api/billing/chart/pie", {
|
||
headers: {
|
||
'Authorization': `Bearer ${token}`
|
||
}
|
||
})
|
||
.then((res) => res.json())
|
||
.then((apiData) => {
|
||
const mapped = apiData.map((item: { status: string; count: number }) => ({
|
||
name: item.status,
|
||
value: item.count,
|
||
fill: STATUS_COLORS[item.status] || "#A3A3A3",
|
||
}));
|
||
setData(mapped);
|
||
});
|
||
}, []);
|
||
|
||
return (
|
||
<div className={styles.pieChartBlock}>
|
||
<h3 className={styles.blockTitle}>Статистика выплат</h3>
|
||
<ResponsiveContainer width="100%" height={200}>
|
||
<PieChart>
|
||
<Pie
|
||
data={data}
|
||
cx="50%"
|
||
cy="50%"
|
||
outerRadius={70}
|
||
dataKey="value"
|
||
label={({ name, value }) => `${name}: ${value}`}
|
||
>
|
||
{data.map((entry, idx) => (
|
||
<Cell key={`cell-${idx}`} fill={entry.fill} />
|
||
))}
|
||
</Pie>
|
||
<Tooltip />
|
||
</PieChart>
|
||
</ResponsiveContainer>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default BillingPieChart;
|