бек статистики

This commit is contained in:
Nastya 2024-03-29 09:10:33 +03:00
parent dd58065255
commit 93ddfb8570
8 changed files with 86 additions and 81 deletions

@ -29,13 +29,16 @@ export default function Analytics() {
const [isOpen, setOpen] = useState(false);
const [isOpenEnd, setOpenEnd] = useState(false);
const [to, setTo] = useState(0);
const [from, setFrom] = useState(0);
const [to, setTo] = useState(null);
const [from, setFrom] = useState(null);
const { devices, general, questions } = useAnalytics({quizId: editQuizId?.toString(), to, from})
const resetTime = () => {
setTo(null);
setFrom(null);
}
useLayoutEffect(() => {
console.log("editQuizId ", editQuizId)
if (editQuizId === undefined) redirect("/list")
}, [editQuizId])
const theme = useTheme();
@ -67,6 +70,9 @@ export default function Analytics() {
handleClose();
}
};
console.log("questions",questions)
console.log("general",general)
console.log("devices",devices)
const now = moment();
return (
@ -123,6 +129,8 @@ export default function Analytics() {
},
},
}}
value={to}
onChange={(newValue) => setTo(newValue)}
/>
</Box>
<Box>
@ -134,6 +142,8 @@ export default function Analytics() {
color: "4D4D4D",
}}
>
value={from}
onChange={(newValue) => setValue(setFrom)}
Дата окончания
</Typography>
<DatePicker
@ -167,6 +177,7 @@ export default function Analytics() {
</Box>
<Button
onClick={resetTime}
variant="outlined"
sx={{
minWidth: isMobile ? "144px" : "180px",
@ -185,9 +196,9 @@ export default function Analytics() {
Сбросить
</Button>
</Box>
<General />
<AnswersStatistics />
<Devices />
<General data={ general }/>
<AnswersStatistics data={ questions }/>
<Devices data={ devices }/>
</SectionWrapper>
</>
);

@ -186,10 +186,11 @@ const Pagination = () => {
);
};
export const Answers = () => {
const [answers, setAnswers] = useState<Record<string, number>>(ANSWERS_MOCK);
export const Answers = (props) => {
const theme = useTheme();
console.log(props.data)
if (Object.keys(props.data).length === 0) return <Typography textAlign="center" m="10px 0">нет данных об ответах</Typography>
return (
<Box sx={{ flexGrow: 1 }}>
<Paper
@ -244,7 +245,7 @@ export const Answers = () => {
<NextIcon />
</ButtonBase>
</Box>
{Object.entries(answers).map(([title, percent], index) => (
{Object.entries(props.data).map(([title, percent], index) => (
<Answer
key={title}
title={title}

@ -16,9 +16,9 @@ type FunnelItemProps = {
const FUNNEL_MOCK: Record<string, number> = {
"Стартовая страница": 100,
"Воронка квиза": 69,
Заявки: 56,
Результаты: 56,
"Воронка квиза": 0,
Заявки: 0,
Результаты: 0,
};
const FunnelItem = ({ title, percent }: FunnelItemProps) => {
@ -100,12 +100,11 @@ const FunnelItem = ({ title, percent }: FunnelItemProps) => {
);
};
export const Funnel = () => {
const [funnel, setFunnel] = useState<Record<string, number>>(FUNNEL_MOCK);
export const Funnel = (props) => {
const theme = useTheme();
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1150));
const isMobile = useMediaQuery(theme.breakpoints.down(850));
console.log(props)
useEffect(() => {
// const requestFunnel = async () => {
// const [funnelResponse, funnelError] = await getGeneral("14761");
@ -122,6 +121,7 @@ export const Funnel = () => {
// requestFunnel();
}, []);
if (Object.keys(props.data).length === 0) return <Typography textAlign="center" m="10px 0">нет данных о разделах</Typography>
return (
<Paper
sx={{
@ -132,8 +132,8 @@ export const Funnel = () => {
maxWidth: isSmallMonitor && !isMobile ? "366px" : "none",
}}
>
{Object.entries(funnel).map(([title, percent]) => (
<FunnelItem key={title} title={title} percent={percent} />
{Object.entries(FUNNEL_MOCK).map(([title, percent], index) => (
<FunnelItem key={title} title={title} percent={index > 0 ? props.data[index-1] : percent} />
))}
</Paper>
);

@ -69,10 +69,10 @@ const Result = ({ title, percent, highlight }: ResultProps) => {
);
};
export const Results = () => {
const [results, setResults] = useState<Record<string, number>>(RESULTS_MOCK);
export const Results = (props) => {
const theme = useTheme();
if (Object.keys(props.data).length === 0) return <Typography margin="20px 0 0 0" textAlign="center" m="10px 0">нет данных о результатах</Typography>
return (
<Box>
<Typography
@ -93,7 +93,7 @@ export const Results = () => {
marginTop: "30px",
}}
>
{Object.entries(results).map(([title, percent], index) => (
{Object.entries(props.data).map(([title, percent], index) => (
<Result
key={title}
title={title}

@ -12,11 +12,13 @@ import { Results } from "./Results";
import { ReactComponent as OpenIcon } from "@icons/Analytics/open.svg";
export const AnswersStatistics = () => {
export const AnswersStatistics = (props) => {
const theme = useTheme();
const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1150));
const isMobile = useMediaQuery(theme.breakpoints.down(850));
console.log(props)
return (
<Box sx={{ marginTop: "120px" }}>
<Typography
@ -29,7 +31,7 @@ export const AnswersStatistics = () => {
>
Статистика по ответам
</Typography>
<ButtonBase
{/* <ButtonBase
sx={{
marginTop: "35px",
display: "flex",
@ -50,17 +52,17 @@ export const AnswersStatistics = () => {
<Box>
<OpenIcon />
</Box>
</ButtonBase>
</ButtonBase> */}
<Box
sx={{
display: isSmallMonitor && !isMobile ? "flex" : "block",
gap: "40px",
}}
>
<Answers />
<Funnel />
<Answers data={props.data?.Questions || {}}/>
<Funnel data={props.data?.Funnel || {}}/>
</Box>
<Results />
<Results data={props.data?.Results || {}}/>
</Box>
);
};

@ -27,6 +27,8 @@ const DEVICES_MOCK: DevicesResponse = {
const Device = ({ title, devices }: DeviceProps) => {
const theme = useTheme();
console.log("devices ", devices)
if (devices === undefined || Object.keys(devices).length === 0) return <Typography>{title} - нет данных</Typography>
const data = Object.entries(devices).map(([id, value], index) => ({
id,
value,
@ -95,33 +97,33 @@ const Device = ({ title, devices }: DeviceProps) => {
);
};
export const Devices = () => {
const [devices, setDevices] = useState<DevicesResponse>(DEVICES_MOCK);
export const Devices = ({data = {}}) => {
const [devices, setDevices] = useState<DevicesResponse>(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");
// useEffect(() => {
// const requestDevices = async () => {
// const [devicesResponse, devicesError] = await getDevices("14761");
if (devicesError) {
enqueueSnackbar(devicesError);
// if (devicesError) {
// enqueueSnackbar(devicesError);
return;
}
// return;
// }
if (!devicesResponse) {
enqueueSnackbar("Список девайсов пуст.");
// if (!devicesResponse) {
// enqueueSnackbar("Список девайсов пуст.");
return;
}
// return;
// }
setDevices(devicesResponse);
};
// setDevices(devicesResponse);
// };
// requestDevices();
}, []);
// // requestDevices();
// }, []);
return (
<Box sx={{ marginTop: "120px" }}>

@ -38,7 +38,10 @@ const GeneralItem = ({ title, general, color, numberType }: GeneralProps) => {
: Object.entries(general).reduce(
(total, [key, value]) => total + (value / Number(key)) * 100,
0,
) / Object.keys(general).length;
) / Object.keys(general).length
||
Number(0)
;
return (
<Paper
@ -66,34 +69,13 @@ const GeneralItem = ({ title, general, color, numberType }: GeneralProps) => {
);
};
export const General = () => {
const [general, setGeneral] = useState<GeneralResponse>(GENERAL_MOCK);
export const General = (props:any) => {
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();
}, []);
if (Object.keys(props.data).length === 0) return <Typography textAlign="center" m="10px 0">нет данных о ключевых метриках</Typography>
return (
<Box sx={{ marginTop: "45px" }}>
<Typography
@ -121,25 +103,25 @@ export const General = () => {
<GeneralItem
title="Открыли квиз"
numberType="sum"
general={general.open}
general={props.data.open || {0:0}}
color={COLORS[0]}
/>
<GeneralItem
title="Получено заявок"
numberType="sum"
general={general.result}
general={props.data.result || {0:0}}
color={COLORS[1]}
/>
<GeneralItem
title="Конверсия"
numberType="percent"
general={general.conversation}
general={props.data.conversation || {0:0}}
color={COLORS[2]}
/>
<GeneralItem
title="Среднее время прохождения квиза"
numberType="percent"
general={general.avtime}
general={props.data.avtime || {0:0}}
color={COLORS[3]}
/>
</Box>

@ -1,5 +1,6 @@
import { getGeneral, getDevices, getQuestions } from "@api/statistic";
import { useEffect, useState } from "react";
import moment from "moment";
interface Props {
quizId: string;
@ -12,18 +13,24 @@ export function useAnalytics({
to,
from,
}: Props) {
const [devices, setDevices] = useState();
const [general, setGeneral] = useState();
const [questions, setQuestions] = useState();
const formatTo = to === null ? 0 : moment(to).unix()
const formatFrom = from === null ? 0 : moment(from).unix()
console.log(
to,
from,)
if (quizId === undefined) return {}
const [devices, setDevices] = useState({});
const [general, setGeneral] = useState({});
const [questions, setQuestions] = useState({});
useEffect(() => {
(async () => {
const gottenGeneral = await getGeneral(quizId, to, from)
const gottenDevices = await getDevices(quizId, to, from)
const gottenQuestions = await getQuestions(quizId, to, from)
setDevices(gottenGeneral)
setGeneral(gottenDevices)
setQuestions(gottenQuestions)
const gottenGeneral = await getGeneral(quizId, formatTo, formatFrom)
const gottenDevices = await getDevices(quizId, formatTo, formatFrom)
const gottenQuestions = await getQuestions(quizId, formatTo, formatFrom)
setDevices(gottenGeneral[0])
setGeneral(gottenDevices[0])
setQuestions(gottenQuestions[0])
})()
}, [to, from]);