2024-04-01 18:09:26 +00:00
|
|
|
|
import { FC } from "react";
|
2024-03-21 14:24:56 +00:00
|
|
|
|
import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material";
|
2024-03-20 14:44:51 +00:00
|
|
|
|
import { PieChart } from "@mui/x-charts";
|
|
|
|
|
|
2024-03-21 14:24:56 +00:00
|
|
|
|
import type { DevicesResponse } from "@api/statistic";
|
2024-03-20 14:44:51 +00:00
|
|
|
|
|
|
|
|
|
type DeviceProps = {
|
|
|
|
|
title: string;
|
2024-04-01 18:09:26 +00:00
|
|
|
|
devices: Record<string, number> | null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type DevicesProps = {
|
|
|
|
|
data: DevicesResponse | null;
|
2024-03-20 14:44:51 +00:00
|
|
|
|
};
|
|
|
|
|
|
2024-03-21 14:24:56 +00:00
|
|
|
|
const COLORS: Record<number, string> = {
|
|
|
|
|
0: "#7E2AEA",
|
|
|
|
|
1: "#FA7738",
|
|
|
|
|
2: "#62BB1C",
|
|
|
|
|
3: "#0886FB",
|
|
|
|
|
};
|
|
|
|
|
|
2024-03-20 14:44:51 +00:00
|
|
|
|
const Device = ({ title, devices }: DeviceProps) => {
|
2024-03-21 14:24:56 +00:00
|
|
|
|
const theme = useTheme();
|
2024-04-05 11:27:52 +00:00
|
|
|
|
if (!devices || !Object.keys(devices ?? {}).length) {
|
2024-03-30 18:54:28 +00:00
|
|
|
|
return <Typography>{title} - нет данных</Typography>;
|
2024-04-01 18:09:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-21 14:24:56 +00:00
|
|
|
|
const data = Object.entries(devices).map(([id, value], index) => ({
|
|
|
|
|
id,
|
|
|
|
|
value,
|
|
|
|
|
color: COLORS[index],
|
|
|
|
|
}));
|
|
|
|
|
|
2024-03-20 14:44:51 +00:00
|
|
|
|
return (
|
2024-03-21 14:24:56 +00:00
|
|
|
|
<Paper
|
|
|
|
|
sx={{
|
|
|
|
|
overflow: "hidden",
|
|
|
|
|
minHeight: "500px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
gap: "30px",
|
|
|
|
|
borderRadius: "12px",
|
|
|
|
|
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Typography sx={{ margin: "20px" }}>{title}</Typography>
|
|
|
|
|
<Box sx={{ flexGrow: 1 }}>
|
|
|
|
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
|
|
|
|
<PieChart
|
|
|
|
|
height={245}
|
|
|
|
|
width={245}
|
|
|
|
|
margin={{ right: 0 }}
|
|
|
|
|
series={[{ data, innerRadius: 50 }]}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{ background: theme.palette.background.default, padding: "20px" }}
|
|
|
|
|
>
|
|
|
|
|
{data.map(({ id, value, color }) => (
|
|
|
|
|
<Box
|
2024-03-22 14:29:51 +00:00
|
|
|
|
key={id}
|
2024-03-21 14:24:56 +00:00
|
|
|
|
sx={{
|
|
|
|
|
display: "flex",
|
|
|
|
|
marginBottom: "10px",
|
|
|
|
|
"&:last-child": { margin: 0 },
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Typography
|
|
|
|
|
sx={{
|
|
|
|
|
flexGrow: 1,
|
|
|
|
|
position: "relative",
|
|
|
|
|
paddingLeft: "30px",
|
|
|
|
|
"&::before": {
|
|
|
|
|
content: "''",
|
|
|
|
|
display: "block",
|
|
|
|
|
position: "absolute",
|
|
|
|
|
left: "0",
|
|
|
|
|
background: color,
|
|
|
|
|
height: "20px",
|
|
|
|
|
width: "20px",
|
|
|
|
|
borderRadius: "6px",
|
|
|
|
|
},
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-05 18:23:08 +00:00
|
|
|
|
{id ? id : "Неопределено"}
|
2024-03-21 14:24:56 +00:00
|
|
|
|
</Typography>
|
2024-04-03 23:35:36 +00:00
|
|
|
|
<Typography>{value.toFixed(1)} %</Typography>
|
2024-03-21 14:24:56 +00:00
|
|
|
|
</Box>
|
|
|
|
|
))}
|
2024-03-20 14:44:51 +00:00
|
|
|
|
</Box>
|
|
|
|
|
</Paper>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-01 18:09:26 +00:00
|
|
|
|
export const Devices: FC<DevicesProps> = ({ data }) => {
|
2024-03-20 14:44:51 +00:00
|
|
|
|
const theme = useTheme();
|
|
|
|
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
2024-03-21 14:24:56 +00:00
|
|
|
|
const isMobile = useMediaQuery(theme.breakpoints.down(700));
|
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// const requestDevices = async () => {
|
|
|
|
|
// const [devicesResponse, devicesError] = await getDevices("14761");
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// if (devicesError) {
|
|
|
|
|
// enqueueSnackbar(devicesError);
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// return;
|
|
|
|
|
// }
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// if (!devicesResponse) {
|
|
|
|
|
// enqueueSnackbar("Список девайсов пуст.");
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// return;
|
|
|
|
|
// }
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// setDevices(devicesResponse);
|
|
|
|
|
// };
|
2024-03-21 14:24:56 +00:00
|
|
|
|
|
2024-03-29 06:10:33 +00:00
|
|
|
|
// // requestDevices();
|
|
|
|
|
// }, []);
|
2024-03-20 14:44:51 +00:00
|
|
|
|
|
|
|
|
|
return (
|
2024-03-21 14:24:56 +00:00
|
|
|
|
<Box sx={{ marginTop: "120px" }}>
|
|
|
|
|
<Typography
|
|
|
|
|
component="h3"
|
|
|
|
|
sx={{
|
|
|
|
|
fontSize: "24px",
|
|
|
|
|
fontWeight: "bold",
|
|
|
|
|
color: theme.palette.text.primary,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Статистика пользователей
|
|
|
|
|
</Typography>
|
|
|
|
|
<Box
|
|
|
|
|
sx={{
|
|
|
|
|
display: "grid",
|
|
|
|
|
gridTemplateColumns: isTablet
|
|
|
|
|
? isMobile
|
|
|
|
|
? "1fr"
|
|
|
|
|
: "1fr 1fr"
|
|
|
|
|
: "1fr 1fr 1fr",
|
|
|
|
|
gap: "20px",
|
|
|
|
|
marginTop: "30px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
2024-04-03 14:22:51 +00:00
|
|
|
|
<Device title="Устройства" devices={data?.Device || null} />
|
|
|
|
|
<Device title="Операционные системы" devices={data?.OS || null} />
|
|
|
|
|
<Device title="Браузеры" devices={data?.Browser || null} />
|
2024-03-21 14:24:56 +00:00
|
|
|
|
</Box>
|
2024-03-20 14:44:51 +00:00
|
|
|
|
</Box>
|
|
|
|
|
);
|
|
|
|
|
};
|