diff --git a/src/api/quizStatistic/index.ts b/src/api/quizStatistics/index.ts similarity index 75% rename from src/api/quizStatistic/index.ts rename to src/api/quizStatistics/index.ts index 308bb46..f2cc2f7 100644 --- a/src/api/quizStatistic/index.ts +++ b/src/api/quizStatistics/index.ts @@ -59,3 +59,24 @@ export const getStatisticSchild = async ( ]; } }; + +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); + } +}; diff --git a/src/api/quizStatistic/types.ts b/src/api/quizStatistics/types.ts similarity index 100% rename from src/api/quizStatistic/types.ts rename to src/api/quizStatistics/types.ts diff --git a/src/index.tsx b/src/index.tsx index ed8ace0..dcff6e9 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -106,7 +106,7 @@ root.render( } /> diff --git a/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx b/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx new file mode 100644 index 0000000..e664b8a --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/DateFilter.tsx @@ -0,0 +1,122 @@ +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 { + from: Moment | null; + to: Moment | null; + setFrom: (a: Moment | null) => void; + setTo: (a: Moment | null) => void; +} + +export const 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, + }, + }, + }} + /> + + + + ); +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx b/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx new file mode 100644 index 0000000..5f596e8 --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/StastisticsPromocode.tsx @@ -0,0 +1,85 @@ +import { + Table, + TableBody, + TableCell, + TableHead, + TableRow, + 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"; + +export const StatisticsPromocode = () => { + const [from, setFrom] = useState(moment("01.01.2023")); + const [to, setTo] = useState(moment(Date.now())); + const promocodes = useAllPromocodes(); + const promocodeStatistics = usePromocodeStatistics({ to, from }); + const theme = useTheme(); + + return ( + + Статистика промокодов + + + + + + Промокод + + + Регистации + + + Внесено + + + + + {/* {Object.values(promocodeStatistics).map(({ Regs, Money }) => { + let codeword = ""; + + for (let value in promocodeStatistics) { + const codewordSearch = promocodes.find(({ id }) => id === value); + + codeword = codewordSearch?.codeword ?? ""; + } + + return ( + + + {codeword} + + + {Regs} + + + {Money} + + + ); + })} */} +
+
+ ); +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx b/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx deleted file mode 100644 index 8a00cde..0000000 --- a/src/pages/dashboard/Content/QuizStatistics/StatisticSchild.tsx +++ /dev/null @@ -1,378 +0,0 @@ -import moment from "moment"; -import { ReactNode, useEffect, useState } from "react"; -import { - Accordion, - AccordionDetails, - AccordionSummary, - Box, - Table, - TableBody, - TableCell, - TableHead, - TableRow, - TextField, - Typography, - 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"; - -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")) - ); - 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} - - - ))} - -
- - - - - ))} - - */} - 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} - /> - - ); -}; diff --git a/src/pages/dashboard/Content/QuizStatistics/StatisticsSchild.tsx b/src/pages/dashboard/Content/QuizStatistics/StatisticsSchild.tsx new file mode 100644 index 0000000..6e0d494 --- /dev/null +++ b/src/pages/dashboard/Content/QuizStatistics/StatisticsSchild.tsx @@ -0,0 +1,195 @@ +import moment from "moment"; +import { useEffect, useState } from "react"; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Table, + TableBody, + TableCell, + TableHead, + TableRow, + Typography, + Button, + useTheme, +} from "@mui/material"; +import { GridToolbar } from "@mui/x-data-grid"; +import { enqueueSnackbar } from "notistack"; +import DataGrid from "@kitUI/datagrid"; + +import ModalUser from "@pages/dashboard/ModalUser"; +import { DateFilter } from "./DateFilter"; + +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/quizStatistics/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 StatisticsSchild = () => { + 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")) + ); + 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 ( + <> + + Статистика переходов с шильдика + + + 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} + /> + + ); +}; diff --git a/src/pages/dashboard/Content/QuizStatistics/index.tsx b/src/pages/dashboard/Content/QuizStatistics/index.tsx index 86e860d..b060d99 100644 --- a/src/pages/dashboard/Content/QuizStatistics/index.tsx +++ b/src/pages/dashboard/Content/QuizStatistics/index.tsx @@ -2,11 +2,11 @@ import { LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment"; import { QuizInfo } from "./QuizInfo"; -import { StatisticSchild } from "./StatisticSchild"; +import { StatisticsSchild } from "./StatisticsSchild"; export const QuizStatistics = () => ( - + ); diff --git a/src/pages/dashboard/Menu/index.tsx b/src/pages/dashboard/Menu/index.tsx index 8856555..a4e355c 100644 --- a/src/pages/dashboard/Menu/index.tsx +++ b/src/pages/dashboard/Menu/index.tsx @@ -100,7 +100,7 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== "open" })); const links: { path: string; element: JSX.Element; title: string; className: string }[] = [ - { path: "/quizStatistic", element: <>📝, title: "Статистика Quiz", className: "menu" }, + { path: "/quizStatistics", element: <>📝, title: "Статистика Quiz", className: "menu" }, { path: "/users", element: , title: "Информация о проекте", className: "menu" }, { path: "/entities", element: , title: "Юридические лица", className: "menu" }, { path: "/tariffs", element: , title: "Тарифы", className: "menu" }, diff --git a/src/utils/hooks/usePromocodeStatistics.ts b/src/utils/hooks/usePromocodeStatistics.ts new file mode 100644 index 0000000..91420ce --- /dev/null +++ b/src/utils/hooks/usePromocodeStatistics.ts @@ -0,0 +1,36 @@ +import { useEffect, useState } from "react"; +import { getStatisticPromocode } from "@root/api/quizStatistics"; + +import type { Moment } from "moment"; +import type { QuizStatisticsItem } from "@root/api/quizStatistics/types"; + +interface useStatisticProps { + to: Moment | null; + from: Moment | null; +} + +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 }], + }); + + useEffect(() => { + const requestStatistics = async () => { + const gottenData = await getStatisticPromocode( + Number(formatFrom), + Number(formatTo) + ); + setStatisticPromo(gottenData); + }; + + requestStatistics(); + }, []); + + return statisticPromo; +} diff --git a/src/utils/hooks/useQuizStatistic.ts b/src/utils/hooks/useQuizStatistic.ts index 25b1ed8..605b485 100644 --- a/src/utils/hooks/useQuizStatistic.ts +++ b/src/utils/hooks/useQuizStatistic.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { QuizStatisticResponse, getStatistic } from "@root/api/quizStatistic"; +import { QuizStatisticResponse, getStatistic } from "@root/api/quizStatistics"; import type { Moment } from "moment"; diff --git a/src/utils/hooks/useSchildStatistics.ts b/src/utils/hooks/useSchildStatistics.ts index 6915b02..4bcba2c 100644 --- a/src/utils/hooks/useSchildStatistics.ts +++ b/src/utils/hooks/useSchildStatistics.ts @@ -1,9 +1,9 @@ import { useEffect, useState } from "react"; -import { getStatisticSchild } from "@root/api/quizStatistic"; +import { getStatisticSchild } from "@root/api/quizStatistics"; import type { Moment } from "moment"; -import type { QuizStatisticsItem } from "@root/api/quizStatistic/types"; +import type { QuizStatisticsItem } from "@root/api/quizStatistics/types"; export const useSchildStatistics = (from: Moment | null, to: Moment | null) => { const formatTo = to?.unix();