frontPanel/src/pages/Analytics/Devices.tsx

155 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { FC } from "react";
import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material";
import { PieChart } from "@mui/x-charts";
import type { DevicesResponse } from "@api/statistic";
type DeviceProps = {
title: string;
devices: Record<string, number> | null;
};
type DevicesProps = {
data: DevicesResponse | null;
};
const COLORS: Record<number, string> = {
0: "#7E2AEA",
1: "#FA7738",
2: "#62BB1C",
3: "#0886FB",
};
const Device = ({ title, devices }: DeviceProps) => {
const theme = useTheme();
if (!devices || !Object.keys(devices ?? {}).length) {
return <Typography>{title} - нет данных</Typography>;
}
const data = Object.entries(devices).map(([id, value], index) => ({
id,
value,
color: COLORS[index],
}));
return (
<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
key={id}
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",
},
}}
>
{id ? id : "Неопределено"}
</Typography>
<Typography>{value.toFixed(1)} %</Typography>
</Box>
))}
</Box>
</Paper>
);
};
export const Devices: FC<DevicesProps> = ({ data }) => {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(700));
// useEffect(() => {
// const requestDevices = async () => {
// const [devicesResponse, devicesError] = await getDevices("14761");
// if (devicesError) {
// enqueueSnackbar(devicesError);
// return;
// }
// if (!devicesResponse) {
// enqueueSnackbar("Список девайсов пуст.");
// return;
// }
// setDevices(devicesResponse);
// };
// // requestDevices();
// }, []);
return (
<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",
}}
>
<Device title="Устройства" devices={data?.Device || null} />
<Device title="Операционные системы" devices={data?.OS || null} />
<Device title="Браузеры" devices={data?.Browser || null} />
</Box>
</Box>
);
};