From ddd345b0d12ef120054574eb0b353d8c468653ee Mon Sep 17 00:00:00 2001 From: Tamara Date: Mon, 29 Apr 2024 16:29:52 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0(=D0=B1=D0=B5=D0=B7=20=D0=B2=D1=8B=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=20=D0=B2=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86?= =?UTF-8?q?=D1=83)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/quizStatistic.ts | 19 ++- .../Content/QuizStatistic/StatisticSchild.tsx | 102 +-------------- .../QuizStatistic/StstisticPromocode.tsx | 50 ++++++++ .../Content/QuizStatistic/dateFilter.tsx | 119 ++++++++++++++++++ .../dashboard/Content/QuizStatistic/index.tsx | 111 +--------------- src/utils/hooks/usePromocodeStatistic.ts | 29 +++++ 6 files changed, 224 insertions(+), 206 deletions(-) create mode 100644 src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx create mode 100644 src/pages/dashboard/Content/QuizStatistic/dateFilter.tsx create mode 100644 src/utils/hooks/usePromocodeStatistic.ts diff --git a/src/api/quizStatistic.ts b/src/api/quizStatistic.ts index 0551ada..217e300 100644 --- a/src/api/quizStatistic.ts +++ b/src/api/quizStatistic.ts @@ -29,7 +29,7 @@ export const getStatistic = async ( }; export const getStatisticSchild = async ( - from: any, to: any): Promise => { + from: number, to: number): Promise => { try { const StatisticResponse = await makeRequest({ url: process.env.REACT_APP_DOMAIN + "/customer/quizlogo/stat" , @@ -48,3 +48,20 @@ export const getStatisticSchild = async ( return [{ID: 0, Regs: 0, Money: 0, Quizes:[{QuizID: 0, Regs: 0, Money: 0}]}]; } }; + export const getStatisticPromocode = async (from: number, to: number): Promise => { + try { + const StatisticPromo = await makeRequest({ + url: process.env.REACT_APP_DOMAIN + "/customer/promocode/ltv" , + method: "post", + useToken: true, + body: { + "to": to, + "from": from, + }, + }); + return StatisticPromo; + } catch (nativeError) { + + console.log(nativeError) + } + } \ No newline at end of file diff --git a/src/pages/dashboard/Content/QuizStatistic/StatisticSchild.tsx b/src/pages/dashboard/Content/QuizStatistic/StatisticSchild.tsx index 74087a0..7694877 100644 --- a/src/pages/dashboard/Content/QuizStatistic/StatisticSchild.tsx +++ b/src/pages/dashboard/Content/QuizStatistic/StatisticSchild.tsx @@ -19,12 +19,10 @@ import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; import ModalUser from "@pages/dashboard/ModalUser"; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import useSchildStatistic from "@root/utils/hooks/useSchildStatistic"; +import DateFilter from "@pages/dashboard/Content/QuizStatistic/dateFilter"; export default function StatisticSchild() { const theme = useTheme() - const [isOpen, setOpen] = useState(false); - const [isOpenEnd, setOpenEnd] = useState(false); - const [openUserModal, setOpenUserModal] = useState(false); const [activeUserId, setActiveUserId] = useState(""); @@ -32,35 +30,6 @@ export default function StatisticSchild() { const [to, setTo] = useState(moment(Date.now())); const statistic = useSchildStatistic(from, to) - const handleClose = () => { - setOpen(false); - }; - - const handleOpen = () => { - setOpen(true); - }; - - const onAdornmentClick = () => { - setOpen((old) => !old); - if (isOpenEnd) { - handleCloseEnd(); - } - }; - - const handleCloseEnd = () => { - setOpenEnd(false); - }; - - const handleOpenEnd = () => { - setOpenEnd(true); - }; - - const onAdornmentClickEnd = () => { - setOpenEnd((old) => !old); - if (isOpen) { - handleClose(); - } - }; useEffect(() => { if (!openUserModal) { setActiveUserId(""); @@ -82,74 +51,7 @@ export default function StatisticSchild() { return( Статистика переходов с шильдика - - - Дата начала - - date && setFrom(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main, - }, - }, - }} - /> - - - - Дата окончания - - date && setTo(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main, - }, - }, - }} - /> - + (moment("01.01.2023")); + const [to, setTo] = useState(moment(Date.now())); + + const statisticPromo = usePromocodeStatistic({to, from}) + + return( + + Статистика промокодов + +
+ + + Промокод + Регистации + Внесено + + + + {/*{Registrations}*/} + {/*{Quizes}*/} + {/*{Results}*/} + +
+
+ ) +} \ No newline at end of file diff --git a/src/pages/dashboard/Content/QuizStatistic/dateFilter.tsx b/src/pages/dashboard/Content/QuizStatistic/dateFilter.tsx new file mode 100644 index 0000000..9d8339e --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistic/dateFilter.tsx @@ -0,0 +1,119 @@ +import {Box, TextField, Typography, useTheme} from "@mui/material"; +import {useState} from "react"; +import moment, {Moment} from "moment"; +import {DatePicker} from "@mui/x-date-pickers"; + +interface Props{ + from: Moment | null, + to: Moment | null, + setFrom: (a: Moment | null) => void, + setTo: (a: Moment | null) => void, +} + +export default function DateFilter({to, setTo, from, setFrom}: Props) { + const theme = useTheme() + const [isOpen, setOpen] = useState(false); + const [isOpenEnd, setOpenEnd] = useState(false); + const handleClose = () => { + setOpen(false); + }; + + const handleOpen = () => { + setOpen(true); + }; + + const onAdornmentClick = () => { + setOpen((old) => !old); + if (isOpenEnd) { + handleCloseEnd(); + } + }; + + const handleCloseEnd = () => { + setOpenEnd(false); + }; + + const handleOpenEnd = () => { + setOpenEnd(true); + }; + + const onAdornmentClickEnd = () => { + setOpenEnd((old) => !old); + if (isOpen) { + handleClose(); + } + }; + return( + <> + + + Дата начала + + date && setFrom(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { + color: theme.palette.secondary.main, + }, + }, + }} + /> + + + + Дата окончания + + date && setTo(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { + color: theme.palette.secondary.main, + }, + }, + }} + /> + + + + ) +} \ No newline at end of file diff --git a/src/pages/dashboard/Content/QuizStatistic/index.tsx b/src/pages/dashboard/Content/QuizStatistic/index.tsx index 172aeba..2dbbcea 100644 --- a/src/pages/dashboard/Content/QuizStatistic/index.tsx +++ b/src/pages/dashboard/Content/QuizStatistic/index.tsx @@ -6,18 +6,16 @@ import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; import { useQuizStatistic } from '@root/utils/hooks/useQuizStatistic'; import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment' import StatisticSchild from "./StatisticSchild"; +import makeRequest from "@root/api/makeRequest"; +import {parseAxiosError} from "@root/utils/parse-error"; +import DateFilter from "@pages/dashboard/Content/QuizStatistic/dateFilter"; +import StstisticPromocode from "@pages/dashboard/Content/QuizStatistic/StstisticPromocode"; export default () => { const theme = useTheme() - - const [isOpen, setOpen] = useState(false); - const [isOpenEnd, setOpenEnd] = useState(false); - const [from, setFrom] = useState(null); const [to, setTo] = useState(moment(Date.now())); - - const { Registrations, Quizes, Results } = useQuizStatistic({ from, to, @@ -28,106 +26,9 @@ export default () => { setTo(moment(Date.now())); }; - const handleClose = () => { - setOpen(false); - }; - - const handleOpen = () => { - setOpen(true); - }; - - const onAdornmentClick = () => { - setOpen((old) => !old); - if (isOpenEnd) { - handleCloseEnd(); - } - }; - - const handleCloseEnd = () => { - setOpenEnd(false); - }; - - const handleOpenEnd = () => { - setOpenEnd(true); - }; - - const onAdornmentClickEnd = () => { - setOpenEnd((old) => !old); - if (isOpen) { - handleClose(); - } - }; - return <> - - - Дата начала - - date && setFrom(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main, - }, - }, - }} - /> - - - - Дата окончания - - date && setTo(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main, - }, - }, - }} - /> - + - - - - Регистраций - Quiz - Результаты - - - - {Registrations} - {Quizes} - {Results} - -
- - - -
- -} \ No newline at end of file diff --git a/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx b/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx new file mode 100644 index 0000000..5bde905 --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx @@ -0,0 +1,148 @@ +import { useState } from "react"; +import moment from "moment"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Typography, + Box, + TextField, + Button, + useTheme, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; + +import { useQuizStatistic } from "@root/utils/hooks/useQuizStatistic"; + +import type { Moment } from "moment"; + +export const QuizInfo = () => { + const [from, setFrom] = useState(null); + const [to, setTo] = useState(moment(Date.now())); + const theme = useTheme(); + const { Registrations, Quizes, Results } = useQuizStatistic({ + from, + to, + }); + + const resetTime = () => { + setFrom(moment()); + setTo(moment(Date.now())); + }; + + return ( + <> + + + Дата начала + + date && setFrom(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, + }, + }} + /> + + + + Дата окончания + + date && setTo(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, + }, + }} + /> + + + + + + + Регистраций + + + Quiz + + + Результаты + + + + + + + {Registrations} + + + {Quizes} + + + {Results} + + + +
+ + ); +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx b/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx new file mode 100644 index 0000000..df90247 --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx @@ -0,0 +1,256 @@ +import moment from "moment"; +import { useEffect, useState } from "react"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + TextField, + Typography, + Button, + useTheme, +} from "@mui/material"; +import { DatePicker } from "@mui/x-date-pickers"; +import { enqueueSnackbar } from "notistack"; + +import ModalUser from "@pages/dashboard/ModalUser"; + +import { useSchildStatistics } from "@root/utils/hooks/useSchildStatistics"; + +import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; + +import type { Moment } from "moment"; + +export const StatisticSchild = () => { + const [openUserModal, setOpenUserModal] = useState(false); + const [activeUserId, setActiveUserId] = useState(""); + + const [from, setFrom] = useState( + moment(new Date("01.01.2023")) + ); + const [to, setTo] = useState(moment(Date.now())); + + const theme = useTheme(); + const statistics = useSchildStatistics(from, to); + + useEffect(() => { + if (!openUserModal) { + setActiveUserId(""); + } + }, [openUserModal]); + + useEffect(() => { + if (activeUserId) { + setOpenUserModal(true); + + return; + } + + setOpenUserModal(false); + }, [activeUserId]); + + const copyQuizLink = (quizId: string) => { + navigator.clipboard.writeText( + `https://${ + window.location.href.includes("/admin.") ? "" : "s." + }hbpn.link/${quizId}` + ); + + enqueueSnackbar("Ссылка успешно скопирована"); + }; + + return ( + <> + + Статистика переходов с шильдика + + + + Дата начала + + date && setFrom(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, + }, + }} + /> + + + + Дата окончания + + date && setTo(date)} + renderInput={(params) => ( + + )} + InputProps={{ + sx: { + height: "40px", + color: theme.palette.secondary.main, + border: "1px solid", + borderColor: theme.palette.secondary.main, + "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, + }, + }} + /> + + + + + + Пользователь + + + Регистраций + + + Деньги + + + Квизы + + + + + {statistics.map(({ ID, Regs, Money, Quizes }) => ( + + setActiveUserId(ID)} + > + {ID} + + setOpenUserModal(false)} + userId={activeUserId} + /> + + {Regs} + + + {Money} + + + + } + aria-controls="panel1-content" + id="panel1-header" + > + Статистика по квизам + + +
+ + + + QuizID + + + Регистрации + + + Деньги + + + + + + {Quizes.map(({ QuizID, Regs, Money }) => ( + + + + + + {Regs} + + + {Money} + + + ))} + +
+ + + + + ))} + + + + ); +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/index.tsx b/src/pages/dashboard/Content/QuizStatistics/index.tsx new file mode 100644 index 0000000..86e860d --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/index.tsx @@ -0,0 +1,12 @@ +import { LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment"; + +import { QuizInfo } from "./QuizInfo"; +import { StatisticSchild } from "./StatisticSchild"; + +export const QuizStatistics = () => ( + + + + +); diff --git a/src/utils/hooks/useQuizStatistic.ts b/src/utils/hooks/useQuizStatistic.ts index 22458a7..25b1ed8 100644 --- a/src/utils/hooks/useQuizStatistic.ts +++ b/src/utils/hooks/useQuizStatistic.ts @@ -1,8 +1,5 @@ import { useEffect, useState } from "react"; -import { - QuizStatisticResponse, - getStatistic -} from "@root/api/quizStatistic"; +import { QuizStatisticResponse, getStatistic } from "@root/api/quizStatistic"; import type { Moment } from "moment"; @@ -15,15 +12,20 @@ export function useQuizStatistic({ to, from }: useQuizStatisticProps) { const formatTo = to?.unix(); const formatFrom = from?.unix(); - const [data, setData] = useState({ Registrations: 0, Quizes: 0, Results: 0 }); + const [data, setData] = useState({ + Registrations: 0, + Quizes: 0, + Results: 0, + }); useEffect(() => { - const requestStatistics = async () => { - - const gottenData = await getStatistic(Number(formatTo), Number(formatFrom)); - setData(gottenData) - } + const gottenData = await getStatistic( + Number(formatTo), + Number(formatFrom) + ); + setData(gottenData); + }; requestStatistics(); }, [to, from]); diff --git a/src/utils/hooks/useSchildStatistic.ts b/src/utils/hooks/useSchildStatistic.ts deleted file mode 100644 index 4167d25..0000000 --- a/src/utils/hooks/useSchildStatistic.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {useEffect, useState} from "react"; -import {getStatisticSchild} from "@root/api/quizStatistic"; - - -export default function useSchildStatistic (from: any, to: any){ - const formatTo = to?.unix(); - const formatFrom = from?.unix(); - const [statistic, setStatistic] = useState([]) - useEffect(() => { - const StatisticsShild = async () => { - const gottenData = await getStatisticSchild(Number(formatFrom), Number(formatTo)); - setStatistic(gottenData) - } - StatisticsShild() - }, []); - return statistic -} diff --git a/src/utils/hooks/useSchildStatistics.ts b/src/utils/hooks/useSchildStatistics.ts new file mode 100644 index 0000000..6915b02 --- /dev/null +++ b/src/utils/hooks/useSchildStatistics.ts @@ -0,0 +1,27 @@ +import { useEffect, useState } from "react"; +import { getStatisticSchild } from "@root/api/quizStatistic"; + +import type { Moment } from "moment"; + +import type { QuizStatisticsItem } from "@root/api/quizStatistic/types"; + +export const useSchildStatistics = (from: Moment | null, to: Moment | null) => { + const formatTo = to?.unix(); + const formatFrom = from?.unix(); + const [statistics, setStatistics] = useState([]); + + useEffect(() => { + const StatisticsShild = async () => { + const gottenData = await getStatisticSchild( + Number(formatFrom), + Number(formatTo) + ); + + setStatistics(gottenData); + }; + + StatisticsShild(); + }, [formatTo, formatFrom]); + + return statistics; +}; diff --git a/tsconfig.json b/tsconfig.json index 64018cf..fe01ca0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,9 +16,7 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "types": ["node"], + "types": ["node"] }, "include": ["src", "**/*.ts"] } - - From 56f1a2f7ab428dec4422a6f835dd9a3ff5089f20 Mon Sep 17 00:00:00 2001 From: Tamara Date: Tue, 30 Apr 2024 03:25:46 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0(=D0=B1=D0=B5=D0=B7=20=D0=BA=D0=BE=D0=B4=D0=B2?= =?UTF-8?q?=D0=BE=D1=80=D0=B4=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QuizStatistic/StstisticPromocode.tsx | 44 ++++++++++++++++--- src/utils/hooks/usePromocodeStatistic.ts | 2 +- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx b/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx index 7ab1072..14d6dfc 100644 --- a/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx +++ b/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx @@ -1,21 +1,34 @@ -import {Table, TableBody, TableCell, TableHead, TableRow, Typography, useTheme} from "@mui/material"; +import {Button, Table, TableBody, TableCell, TableHead, TableRow, Typography, useTheme} from "@mui/material"; import {AdapterMoment} from "@mui/x-date-pickers/AdapterMoment"; import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; import DateFilter from "@pages/dashboard/Content/QuizStatistic/dateFilter"; -import {useState} from "react"; +import {useEffect, useState} from "react"; import moment, {Moment} from "moment"; import {usePromocodeStatistic} from "@root/utils/hooks/usePromocodeStatistic"; +import {promocodeApi} from "@root/api/promocode/requests"; +import {useAllPromocodes} from "@root/api/promocode/swr"; export default function StstisticPromocode() { const theme = useTheme() const [from, setFrom] = useState(moment("01.01.2023")); const [to, setTo] = useState(moment(Date.now())); + const promocodes = useAllPromocodes(); const statisticPromo = usePromocodeStatistic({to, from}) + for (statisticPromo.key in statisticPromo) { + const codewordSearch = promocodes.find(obj => obj.id === statisticPromo.key) + let codeword = codewordSearch?.codeword + console.log( "xnj 'nj", codeword) + } + + return( Статистика промокодов + Внесено - - {/*{Registrations}*/} - {/*{Quizes}*/} - {/*{Results}*/} - + + {Object.values(statisticPromo).map((sPromo:any)=> { + let codeword + let listPromo = promocodes + let statisticP = statisticPromo + console.log("in map", sPromo.key) + + for (statisticP.key in statisticP) { + const codewordSearch = listPromo.find(obj => obj.id === statisticP.key) + codeword = codewordSearch?.codeword + console.log(codeword) + } + + return( + + {codeword} + {sPromo.Regs} + {sPromo.Money} + + ) + }) + }
) diff --git a/src/utils/hooks/usePromocodeStatistic.ts b/src/utils/hooks/usePromocodeStatistic.ts index b876579..b881980 100644 --- a/src/utils/hooks/usePromocodeStatistic.ts +++ b/src/utils/hooks/usePromocodeStatistic.ts @@ -18,7 +18,7 @@ export function usePromocodeStatistic({ to, from }: useStatisticProps) { const requestStatistics = async () => { - const gottenData = await getStatisticPromocode(Number(formatTo), Number(formatFrom)); + const gottenData = await getStatisticPromocode(Number(formatFrom), Number(formatTo)); setStatisticPromo(gottenData) } From eb6cd2face7571fa852ef25b56ba612a68d9e1e4 Mon Sep 17 00:00:00 2001 From: Tamara Date: Tue, 30 Apr 2024 04:20:34 +0300 Subject: [PATCH 4/6] =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=20=D0=BF=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0(=D0=B1=D0=B5=D0=B7=20=D0=BA=D0=BE=D0=B4=D0=B2?= =?UTF-8?q?=D0=BE=D1=80=D0=B4=D0=BE=D0=B2,=20=D0=BF=D0=BE=D1=87=D0=B8?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D0=BE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../QuizStatistic/StstisticPromocode.tsx | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx b/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx index 14d6dfc..edd80a3 100644 --- a/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx +++ b/src/pages/dashboard/Content/QuizStatistic/StstisticPromocode.tsx @@ -2,10 +2,9 @@ import {Button, Table, TableBody, TableCell, TableHead, TableRow, Typography, us import {AdapterMoment} from "@mui/x-date-pickers/AdapterMoment"; import { DatePicker, LocalizationProvider } from '@mui/x-date-pickers'; import DateFilter from "@pages/dashboard/Content/QuizStatistic/dateFilter"; -import {useEffect, useState} from "react"; +import {useState} from "react"; import moment, {Moment} from "moment"; import {usePromocodeStatistic} from "@root/utils/hooks/usePromocodeStatistic"; -import {promocodeApi} from "@root/api/promocode/requests"; import {useAllPromocodes} from "@root/api/promocode/swr"; export default function StstisticPromocode() { @@ -16,19 +15,9 @@ export default function StstisticPromocode() { const statisticPromo = usePromocodeStatistic({to, from}) - for (statisticPromo.key in statisticPromo) { - const codewordSearch = promocodes.find(obj => obj.id === statisticPromo.key) - let codeword = codewordSearch?.codeword - console.log( "xnj 'nj", codeword) - } - - return( Статистика промокодов - - {Object.values(statisticPromo).map((sPromo:any)=> { + {Object.values(statisticPromo || {}).map((sPromo:any)=> { let codeword let listPromo = promocodes let statisticP = statisticPromo - console.log("in map", sPromo.key) - for (statisticP.key in statisticP) { - const codewordSearch = listPromo.find(obj => obj.id === statisticP.key) + for (let key in statisticP) { + const codewordSearch = listPromo.find(obj => obj.id === key) codeword = codewordSearch?.codeword - console.log(codeword) + // console.log(codeword) } return( From 6d67a11265a9287958bbe9541d7bf67b0c3365ba Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 30 Apr 2024 13:34:29 +0300 Subject: [PATCH 5/6] feat: schild pagination --- .../QuizStatistics/StatisticSchild.tsx | 128 +++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx b/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx index df90247..8a00cde 100644 --- a/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx @@ -1,5 +1,5 @@ import moment from "moment"; -import { useEffect, useState } from "react"; +import { ReactNode, useEffect, useState } from "react"; import { Accordion, AccordionDetails, @@ -15,8 +15,10 @@ import { Button, useTheme, } from "@mui/material"; +import { GridToolbar } from "@mui/x-data-grid"; import { DatePicker } from "@mui/x-date-pickers"; import { enqueueSnackbar } from "notistack"; +import DataGrid from "@kitUI/datagrid"; import ModalUser from "@pages/dashboard/ModalUser"; @@ -25,10 +27,35 @@ import { useSchildStatistics } from "@root/utils/hooks/useSchildStatistics"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import type { Moment } from "moment"; +import type { QuizStatisticsItem } from "@root/api/quizStatistic/types"; +import type { GridColDef } from "@mui/x-data-grid"; + +const COLUMNS: GridColDef[] = [ + { + field: "user", + headerName: "Пользователь", + width: 250, + valueGetter: ({ row }) => row.ID, + }, + { + field: "regs", + headerName: "Регистраций", + width: 200, + valueGetter: ({ row }) => String(row.Regs), + }, + { + field: "money", + headerName: "Деньги", + width: 200, + valueGetter: ({ row }) => String(row.Money), + }, +]; export const StatisticSchild = () => { const [openUserModal, setOpenUserModal] = useState(false); const [activeUserId, setActiveUserId] = useState(""); + const [page, setPage] = useState(1); + const [pageSize, setPageSize] = useState(10); const [from, setFrom] = useState( moment(new Date("01.01.2023")) @@ -133,7 +160,7 @@ export const StatisticSchild = () => { }} /> -
{ ))} -
+ */} + ID} + checkboxSelection={true} + rows={statistics} + components={{ Toolbar: GridToolbar }} + rowCount={statistics.length} + rowsPerPageOptions={[1, 10, 25, 50, 100]} + paginationMode="client" + disableSelectionOnClick + page={page} + pageSize={pageSize} + onPageChange={setPage} + onPageSizeChange={setPageSize} + onCellClick={({ id, field }) => + field === "user" && setActiveUserId(String(id)) + } + getRowHeight={() => "auto"} + columns={[ + ...COLUMNS, + { + field: "quizes", + headerName: "Квизы", + flex: 1, + minWidth: 220, + valueGetter: ({ row }) => String(row.Quizes.length), + renderCell: ({ row }) => ( + + } + aria-controls="panel1-content" + id="panel1-header" + > + Статистика по квизам + + + + + + + QuizID + + + Регистрации + + + Деньги + + + + + + {row.Quizes.map(({ QuizID, Regs, Money }) => ( + + + + + + {Regs} + + + {Money} + + + ))} + +
+
+
+ ), + }, + ]} + /> + setOpenUserModal(false)} + userId={activeUserId} + /> ); }; From 9e4d13303e8748dac8c2293ad2c582c4f6647b2b Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 30 Apr 2024 18:30:24 +0300 Subject: [PATCH 6/6] refactor: promocode statistics --- src/api/quizStatistics/index.ts | 21 ++++-- src/api/quizStatistics/types.ts | 10 +++ .../Content/QuizStatistics/DateFilter.tsx | 48 ++----------- .../Content/QuizStatistics/QuizInfo.tsx | 71 +------------------ .../QuizStatistics/StastisticsPromocode.tsx | 47 ++++++------ .../Content/QuizStatistics/index.tsx | 2 + src/utils/hooks/usePromocodeStatistics.ts | 18 +++-- src/utils/hooks/useQuizStatistic.ts | 2 +- 8 files changed, 65 insertions(+), 154 deletions(-) diff --git a/src/api/quizStatistics/index.ts b/src/api/quizStatistics/index.ts index f2cc2f7..5cd9ff6 100644 --- a/src/api/quizStatistics/index.ts +++ b/src/api/quizStatistics/index.ts @@ -1,6 +1,11 @@ import makeRequest from "@root/api/makeRequest"; -import type { GetStatisticSchildBody, QuizStatisticsItem } from "./types"; +import type { + GetStatisticSchildBody, + QuizStatisticsItem, + GetPromocodeStatisticsBody, + AllPromocodeStatistics, +} from "./types"; export type QuizStatisticResponse = { Registrations: number; @@ -63,20 +68,22 @@ export const getStatisticSchild = async ( export const getStatisticPromocode = async ( from: number, to: number -): Promise => { +): Promise> => { try { - const StatisticPromo = await makeRequest({ + const StatisticPromo = await makeRequest< + GetPromocodeStatisticsBody, + Record + >({ url: process.env.REACT_APP_DOMAIN + "/customer/promocode/ltv", method: "post", useToken: true, - body: { - to: to, - from: from, - }, + body: { to, from }, }); return StatisticPromo; } catch (nativeError) { console.log(nativeError); + + return {}; } }; diff --git a/src/api/quizStatistics/types.ts b/src/api/quizStatistics/types.ts index 7aaf69d..284b7c8 100644 --- a/src/api/quizStatistics/types.ts +++ b/src/api/quizStatistics/types.ts @@ -19,3 +19,13 @@ export type QuizStatisticsItem = { Quizes: StatisticsQuizes[]; Regs: number; }; + +export type GetPromocodeStatisticsBody = { + from: number; + to: number; +}; + +export type AllPromocodeStatistics = { + Money: number; + Regs: number; +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx b/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx index e664b8a..c2b7fff 100644 --- a/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx @@ -1,51 +1,18 @@ import { Box, TextField, Typography, useTheme } from "@mui/material"; -import { useState } from "react"; import { DatePicker } from "@mui/x-date-pickers"; -import { StatisticsPromocode } from "./StastisticsPromocode"; - import type { Moment } from "moment"; -interface Props { +type DateFilterProps = { from: Moment | null; to: Moment | null; - setFrom: (a: Moment | null) => void; - setTo: (a: Moment | null) => void; -} + setFrom: (date: Moment | null) => void; + setTo: (date: Moment | null) => void; +}; -export const DateFilter = ({ to, setTo, from, setFrom }: Props) => { +export const DateFilter = ({ to, setTo, from, setFrom }: DateFilterProps) => { const theme = useTheme(); - const [isOpen, setOpen] = useState(false); - const [isOpenEnd, setOpenEnd] = useState(false); - const handleClose = () => { - setOpen(false); - }; - const handleOpen = () => { - setOpen(true); - }; - - const onAdornmentClick = () => { - setOpen((old) => !old); - if (isOpenEnd) { - handleCloseEnd(); - } - }; - - const handleCloseEnd = () => { - setOpenEnd(false); - }; - - const handleOpenEnd = () => { - setOpenEnd(true); - }; - - const onAdornmentClickEnd = () => { - setOpenEnd((old) => !old); - if (isOpen) { - handleClose(); - } - }; return ( <> @@ -75,9 +42,7 @@ export const DateFilter = ({ to, setTo, from, setFrom }: Props) => { color: theme.palette.secondary.main, border: "1px solid", borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { - color: theme.palette.secondary.main, - }, + "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, }, }} /> @@ -115,7 +80,6 @@ export const DateFilter = ({ to, setTo, from, setFrom }: Props) => { }, }} /> - ); diff --git a/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx b/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx index 5bde905..7ee5adb 100644 --- a/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/QuizInfo.tsx @@ -6,13 +6,11 @@ import { TableCell, TableHead, TableRow, - Typography, - Box, - TextField, Button, useTheme, } from "@mui/material"; -import { DatePicker } from "@mui/x-date-pickers"; + +import { DateFilter } from "./DateFilter"; import { useQuizStatistic } from "@root/utils/hooks/useQuizStatistic"; @@ -34,70 +32,7 @@ export const QuizInfo = () => { return ( <> - - - Дата начала - - date && setFrom(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, - }, - }} - /> - - - - Дата окончания - - date && setTo(date)} - renderInput={(params) => ( - - )} - InputProps={{ - sx: { - height: "40px", - color: theme.palette.secondary.main, - border: "1px solid", - borderColor: theme.palette.secondary.main, - "& .MuiSvgIcon-root": { color: theme.palette.secondary.main }, - }, - }} - /> - + diff --git a/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx b/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx index 5f596e8..d62c139 100644 --- a/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx @@ -1,3 +1,5 @@ +import { useState } from "react"; +import moment from "moment"; import { Table, TableBody, @@ -7,25 +9,26 @@ import { Typography, useTheme, } from "@mui/material"; -import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment"; -import { LocalizationProvider } from "@mui/x-date-pickers"; + import { DateFilter } from "./DateFilter"; -import { useState } from "react"; -import moment, { Moment } from "moment"; -import { usePromocodeStatistics } from "@root/utils/hooks/usePromocodeStatistics"; + import { useAllPromocodes } from "@root/api/promocode/swr"; -import { QuizStatisticsItem } from "@root/api/quizStatistics/types"; +import { usePromocodeStatistics } from "@root/utils/hooks/usePromocodeStatistics"; + +import type { Moment } from "moment"; export const StatisticsPromocode = () => { - const [from, setFrom] = useState(moment("01.01.2023")); + const [from, setFrom] = useState( + moment(new Date("01.01.2023")) + ); const [to, setTo] = useState(moment(Date.now())); const promocodes = useAllPromocodes(); const promocodeStatistics = usePromocodeStatistics({ to, from }); const theme = useTheme(); return ( - - Статистика промокодов + <> + Статистика промокодов { borderColor: theme.palette.secondary.main, bgcolor: theme.palette.content.main, color: "white", + marginTop: "30px", }} > @@ -55,20 +59,11 @@ export const StatisticsPromocode = () => { - - {/* {Object.values(promocodeStatistics).map(({ Regs, Money }) => { - let codeword = ""; - - for (let value in promocodeStatistics) { - const codewordSearch = promocodes.find(({ id }) => id === value); - - codeword = codewordSearch?.codeword ?? ""; - } - - return ( - + {Object.entries(promocodeStatistics).map(([key, { Regs, Money }]) => ( + + - {codeword} + {promocodes.find(({ id }) => id === key)?.codeword ?? ""} {Regs} @@ -76,10 +71,10 @@ export const StatisticsPromocode = () => { {Money} - - ); - })} */} + + + ))}
-
+ ); }; diff --git a/src/pages/dashboard/Content/QuizStatistics/index.tsx b/src/pages/dashboard/Content/QuizStatistics/index.tsx index b060d99..968cba0 100644 --- a/src/pages/dashboard/Content/QuizStatistics/index.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/index.tsx @@ -3,10 +3,12 @@ import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment"; import { QuizInfo } from "./QuizInfo"; import { StatisticsSchild } from "./StatisticsSchild"; +import { StatisticsPromocode } from "./StastisticsPromocode"; export const QuizStatistics = () => ( + ); diff --git a/src/utils/hooks/usePromocodeStatistics.ts b/src/utils/hooks/usePromocodeStatistics.ts index 91420ce..7669907 100644 --- a/src/utils/hooks/usePromocodeStatistics.ts +++ b/src/utils/hooks/usePromocodeStatistics.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from "react"; import { getStatisticPromocode } from "@root/api/quizStatistics"; import type { Moment } from "moment"; -import type { QuizStatisticsItem } from "@root/api/quizStatistics/types"; +import type { AllPromocodeStatistics } from "@root/api/quizStatistics/types"; interface useStatisticProps { to: Moment | null; @@ -13,12 +13,9 @@ export function usePromocodeStatistics({ to, from }: useStatisticProps) { const formatTo = to?.unix(); const formatFrom = from?.unix(); - const [statisticPromo, setStatisticPromo] = useState({ - ID: "0", - Regs: 0, - Money: 0, - Quizes: [{ QuizID: "0", Regs: 0, Money: 0 }], - }); + const [promocodeStatistics, setPromocodeStatistics] = useState< + Record + >({}); useEffect(() => { const requestStatistics = async () => { @@ -26,11 +23,12 @@ export function usePromocodeStatistics({ to, from }: useStatisticProps) { Number(formatFrom), Number(formatTo) ); - setStatisticPromo(gottenData); + + setPromocodeStatistics(gottenData); }; requestStatistics(); - }, []); + }, [formatTo, formatFrom]); - return statisticPromo; + return promocodeStatistics; } diff --git a/src/utils/hooks/useQuizStatistic.ts b/src/utils/hooks/useQuizStatistic.ts index 605b485..8164965 100644 --- a/src/utils/hooks/useQuizStatistic.ts +++ b/src/utils/hooks/useQuizStatistic.ts @@ -28,7 +28,7 @@ export function useQuizStatistic({ to, from }: useQuizStatisticProps) { }; requestStatistics(); - }, [to, from]); + }, [formatTo, formatFrom]); return { ...data }; }