2024-03-21 14:24:56 +00:00
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
|
|
|
import { LineChart } from "@mui/x-charts";
|
|
|
|
|
import { enqueueSnackbar } from "notistack";
|
|
|
|
|
|
|
|
|
|
import { getGeneral } from "@api/statistic";
|
|
|
|
|
|
|
|
|
|
import type { GeneralResponse } from "@api/statistic";
|
|
|
|
|
|
|
|
|
|
type GeneralProps = {
|
|
|
|
|
title: string;
|
|
|
|
|
general: Record<string, number>;
|
|
|
|
|
color: string;
|
|
|
|
|
numberType: "sum" | "percent";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const COLORS: Record<number, string> = {
|
|
|
|
|
0: "#61BB1A",
|
|
|
|
|
1: "#7E2AEA",
|
|
|
|
|
2: "#FB5607",
|
|
|
|
|
3: "#0886FB",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const GENERAL_MOCK: GeneralResponse = {
|
2024-03-22 14:29:51 +00:00
|
|
|
|
open: { 100: 20, 50: 10, 60: 5 },
|
|
|
|
|
result: { 100: 90, 10: 3, 50: 48 },
|
|
|
|
|
avtime: { 100: 0, 2000: 550, 60: 0 },
|
|
|
|
|
conversation: { 100: 50, 1000: 50, 10000: 50 },
|
2024-03-21 14:24:56 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const GeneralItem = ({ title, general, color, numberType }: GeneralProps) => {
|
|
|
|
|
const theme = useTheme();
|
|
|
|
|
const isMobile = useMediaQuery(theme.breakpoints.down(700));
|
|
|
|
|
|
|
|
|
|
const numberValue =
|
|
|
|
|
numberType === "sum"
|
|
|
|
|
? Object.values(general).reduce((total, item) => total + item, 0)
|
|
|
|
|
: Object.entries(general).reduce(
|
|
|
|
|
(total, [key, value]) => total + (value / Number(key)) * 100,
|
|
|
|
|
0,
|
|
|
|
|
) / Object.keys(general).length;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Paper
|
|
|
|
|
sx={{
|
|
|
|
|
overflow: "hidden",
|
|
|
|
|
borderRadius: "12px",
|
|
|
|
|
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Typography sx={{ margin: "20px 20px 0" }}>{title}</Typography>
|
|
|
|
|
<Typography sx={{ margin: "10px 20px 0", fontWeight: "bold" }}>
|
|
|
|
|
{numberType === "sum" ? numberValue : `${numberValue.toFixed()}%`}
|
|
|
|
|
</Typography>
|
|
|
|
|
<LineChart
|
|
|
|
|
xAxis={[{ data: Object.keys(general) }]}
|
|
|
|
|
series={[{ data: Object.values(general) }]}
|
|
|
|
|
height={220}
|
|
|
|
|
colors={[color]}
|
|
|
|
|
sx={{
|
|
|
|
|
transform: isMobile ? "scale(1.1)" : "scale(1.2)",
|
|
|
|
|
"& .MuiChartsAxis-tickContainer": { display: "none" },
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</Paper>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const General = () => {
|
|
|
|
|
const [general, setGeneral] = useState<GeneralResponse>(GENERAL_MOCK);
|
|
|
|
|
const theme = useTheme();
|
|
|
|
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
|
|
|
|
const isMobile = useMediaQuery(theme.breakpoints.down(700));
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const requestGeneral = async () => {
|
|
|
|
|
const [generalResponse, generalError] = await getGeneral("14761");
|
|
|
|
|
|
|
|
|
|
if (generalError) {
|
|
|
|
|
enqueueSnackbar(generalError);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!generalResponse) {
|
|
|
|
|
enqueueSnackbar("Список девайсов пуст.");
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setGeneral(generalResponse);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// requestGeneral();
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Box sx={{ marginTop: "45px" }}>
|
|
|
|
|
<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: "40px",
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<GeneralItem
|
|
|
|
|
title="Открыли квиз"
|
|
|
|
|
numberType="sum"
|
|
|
|
|
general={general.open}
|
|
|
|
|
color={COLORS[0]}
|
|
|
|
|
/>
|
|
|
|
|
<GeneralItem
|
|
|
|
|
title="Получено заявок"
|
|
|
|
|
numberType="sum"
|
|
|
|
|
general={general.result}
|
|
|
|
|
color={COLORS[1]}
|
|
|
|
|
/>
|
|
|
|
|
<GeneralItem
|
|
|
|
|
title="Конверсия"
|
|
|
|
|
numberType="percent"
|
|
|
|
|
general={general.conversation}
|
|
|
|
|
color={COLORS[2]}
|
|
|
|
|
/>
|
|
|
|
|
<GeneralItem
|
|
|
|
|
title="Среднее время прохождения квиза"
|
|
|
|
|
numberType="percent"
|
|
|
|
|
general={general.avtime}
|
|
|
|
|
color={COLORS[3]}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
);
|
|
|
|
|
};
|