import moment from "moment"; import { Box, Paper, Typography, useMediaQuery, useTheme } from "@mui/material"; import { LineChart } from "@mui/x-charts"; import type { FC } from "react"; import type { GeneralResponse } from "@api/statistic"; type GeneralItemsProps = { title: string; general: Record; color: string; numberType: "sum" | "percent" | "time"; calculateTime?: boolean; conversionValue?: number; day: boolean; }; type GeneralProps = { data: GeneralResponse | null; day: boolean; }; const getCalculatedTime = (time: number) => { const hours = String(Math.floor(time / 3600)).padStart(2, "0"); const minutes = String(Math.floor((time % 3600) / 60)).padStart(2, "0"); const seconds = String(Math.floor((time % 3600) % 60)).padStart(2, "0"); return `${hours}:${minutes}:${seconds}`; }; const GeneralItem = ({ title, general, color, numberType, calculateTime = false, conversionValue, day, }: GeneralItemsProps) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(700)); const numberValue = numberType === "sum" ? Object.values(general).reduce((total, item) => total + item, 0) : title === "Конверсия" ? conversionValue : 0; if ( Object.keys(general).length === 0 || Object.values(general).every((x) => x === 0) ) { return ( {`${title} - нет данных`} ); } const getCalculatedTime = (time: number) => { const hours = String(Math.floor(time / 3600)).padStart(2, "0"); const minutes = String(Math.floor((time % 3600) / 60)).padStart(2, "0"); const seconds = String(Math.floor((time % 3600) % 60)).padStart(2, "0"); return `${hours}:${minutes}:${seconds}`; }; return ( {title} {numberType === "percent" ? `${numberValue?.toFixed(2)}%` : numberValue} moment.unix(Number(value)).format("DD/MM/YYYY HH") + "ч", }, ]} series={[ { data: Object.values(general), valueFormatter: (value) => calculateTime ? getCalculatedTime(value) : String(value.toFixed(2)), }, ]} height={220} colors={[color]} sx={{ transform: isMobile ? "scale(1.1)" : "scale(1.2)", "& .MuiChartsAxis-tickContainer": { display: "none" }, }} /> ); }; const GeneralItemTimeConv = ({ title, general, color, numberType, calculateTime = false, conversionValue, }: GeneralItemsProps) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(700)); const data = Object.entries(general).sort((a, b) => a[0] - b[0]); const days = [...data].map((e) => e[0]); let buffer = 0; const time = [...data].map((e) => { if (e[1] > 0) { buffer = e[1]; } return buffer; }); console.log("data", data); console.log( "time", time.reduce((a, b) => Number(a) + Number(b), 0), ); console.log( "time", getCalculatedTime(time.reduce((a, b) => Number(a) + Number(b), 0)), ); console.log("days", days.length); const numberValue = calculateTime ? time.reduce((a, b) => Number(a) + Number(b), 0) / days.length || 0 : conversionValue; if ( Object.keys(general).length === 0 || Object.values(general).every((x) => x === 0) ) { return ( {`${title} - нет данных`} ); } return ( {title} {calculateTime ? `${getCalculatedTime(numberValue)} с` : `${numberValue.toFixed(2)}%`} moment.utc(Number(value) * 1000).format("DD/MM/YYYY"), }, ]} series={[ { data: Object.values(time), valueFormatter: (value) => { console.log("log", value); return calculateTime ? getCalculatedTime(value) : String((value * 100).toFixed(2)) + "%"; }, }, ]} height={220} colors={[color]} sx={{ transform: isMobile ? "scale(1.1)" : "scale(1.2)", "& .MuiChartsAxis-tickContainer": { display: "none" }, }} /> ); }; export const General: FC = ({ data, day }) => { const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const isMobile = useMediaQuery(theme.breakpoints.down(700)); if (!data) { return ( нет данных о ключевых метриках ); } const currentDate = moment().unix(); const generalResponse = Object.entries(data).reduce( (total, [fatherKey, values]) => { const value = Object.keys(values).reduce((totalValue, key) => { if (Number(key) - currentDate < 0) { return { ...totalValue, [key]: values[key] }; } return totalValue; }, {}); return { ...total, [fatherKey]: value }; }, {} as GeneralResponse, ); const resultSum = Object.values(generalResponse.Result).reduce( (total, item) => total + item, 0, ); const openSum = Object.values(generalResponse.Open).reduce( (total, item) => total + item, 0, ); const conversionValue = (resultSum / openSum) * 100; return ( Ключевые метрики ); };