frontPanel/src/pages/Analytics/Devices.tsx
2024-03-22 17:29:51 +03:00

157 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 { useEffect, useState } from "react";
import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material";
import { PieChart } from "@mui/x-charts";
import { enqueueSnackbar } from "notistack";
import { getDevices } from "@api/statistic";
import type { DevicesResponse } from "@api/statistic";
type DeviceProps = {
title: string;
devices: Record<string, number>;
};
const COLORS: Record<number, string> = {
0: "#7E2AEA",
1: "#FA7738",
2: "#62BB1C",
3: "#0886FB",
};
const DEVICES_MOCK: DevicesResponse = {
device: { PC: 75, Mobile: 25 },
os: { Windows: 44, AndroidOS: 25, "OS X": 19, Linux: 13 },
browser: { Chrome: 75, Firefox: 25 },
};
const Device = ({ title, devices }: DeviceProps) => {
const theme = useTheme();
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}
</Typography>
<Typography>{value} %</Typography>
</Box>
))}
</Box>
</Paper>
);
};
export const Devices = () => {
const [devices, setDevices] = useState<DevicesResponse>(DEVICES_MOCK);
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={devices.device} />
<Device title="Операционные системы" devices={devices.os} />
<Device title="Браузеры" devices={devices.browser} />
</Box>
</Box>
);
};