diff --git a/src/pages/Analytics/Analytics.tsx b/src/pages/Analytics/Analytics.tsx index dd5d44ca..75d3b1d2 100644 --- a/src/pages/Analytics/Analytics.tsx +++ b/src/pages/Analytics/Analytics.tsx @@ -58,7 +58,7 @@ export default function Analytics() { useEffect(() => { if (quizes.length > 0) { const quiz = quizes.find((q) => q.backendId === editQuizId); - if (quiz === undefined) throw new Error("Не удалось получить квиз") + if (quiz === undefined) throw new Error("Не удалось получить квиз"); setQuiz(quiz); setFrom(moment(new Date(quiz.created_at))); } @@ -68,10 +68,8 @@ export default function Analytics() { const getData = async (): Promise => { try { if (editQuizId !== null) { - const gottenQuizes = await quizApi.getList(); - setQuizes(gottenQuizes) - + setQuizes(gottenQuizes); } } catch (error) { console.error("Не удалось получить квизы", error); diff --git a/src/pages/Analytics/Answers/Answers.tsx b/src/pages/Analytics/Answers/Answers.tsx index 397fd7d8..3811f6e4 100644 --- a/src/pages/Analytics/Answers/Answers.tsx +++ b/src/pages/Analytics/Answers/Answers.tsx @@ -1,5 +1,4 @@ -import { FC, useState } from "react"; -import type { PaginationRenderItemParams } from "@mui/material"; +import { FC, useEffect, useMemo, useState } from "react"; import { Box, ButtonBase, @@ -18,6 +17,8 @@ import { ReactComponent as NextIcon } from "@icons/Analytics/next.svg"; import { ReactComponent as LeftArrowIcon } from "@icons/Analytics/leftArrow.svg"; import { ReactComponent as RightArrowIcon } from "@icons/Analytics/rightArrow.svg"; +import type { PaginationRenderItemParams } from "@mui/material"; + type AnswerProps = { title: string; percent: number; @@ -28,12 +29,14 @@ type AnswersProps = { data: Record> | null; }; -const ANSWERS_MOCK: Record = { - "Добавьте ответ": 67, - "Вопрос пропущен": 7, - Другое: 27, +type PaginationProps = { + page: number; + pagesAmount: number; + setPage: (page: number) => void; }; +const ANSWERS_PER_PAGE = 5; + const Answer = ({ title, percent, highlight }: AnswerProps) => { const theme = useTheme(); @@ -60,7 +63,7 @@ const Answer = ({ title, percent, highlight }: AnswerProps) => { border: `1px solid ${highlight ? theme.palette.brightPurple.main : theme.palette.grey2.main}`, "& > span": { background: highlight ? "#D9C0F9" : "#9A9AAF1A" }, "&::before": { - content: `"${title}"`, + content: title ? `"${title}"` : `"Без имени"`, position: "absolute", zIndex: 1, left: "20px", @@ -88,12 +91,15 @@ const Answer = ({ title, percent, highlight }: AnswerProps) => { ); }; -const Pagination = () => { - const [count, setCount] = useState(50); - const [page, setPage] = useState(1); +const Pagination = ({ page, setPage, pagesAmount }: PaginationProps) => { + const [count, setCount] = useState(0); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(855)); + useEffect(() => { + setCount(pagesAmount); + }, [pagesAmount]); + const getPaginationItem = (props: PaginationRenderItemParams) => { if (props.type === "start-ellipsis" || props.type === "end-ellipsis") { return; @@ -147,9 +153,13 @@ const Pagination = () => { disableUnderline placeholder="1" value={page} - onChange={({ target }) => - setPage(Number(target.value.replace(/\D/, ""))) - } + onChange={({ target }) => { + const newPage = Number(target.value.replace(/\D/, "")); + + if (newPage <= count) { + setPage(newPage); + } + }} sx={{ height: "30px", width: "65px", @@ -190,7 +200,27 @@ const Pagination = () => { }; export const Answers: FC = ({ data }) => { + const [page, setPage] = useState(1); const theme = useTheme(); + const answers = useMemo( + () => + data === null ? + [] + : + Object.keys(data ?? {}) + .map((key) => + Object.entries(data[key]).map(([title, percent]) => ({ + title, + percent, + key, + })), + ) + .flat(), + [data], + ); + +console.log(answers) +console.log(page) if (!data) { return ( @@ -244,7 +274,7 @@ export const Answers: FC = ({ data }) => { }, }} > - Заголовок вопроса. Варианты ответов + Заголовок вопроса. {answers.slice(ANSWERS_PER_PAGE * (page - 1), ANSWERS_PER_PAGE * page)[0]?.key} @@ -253,26 +283,22 @@ export const Answers: FC = ({ data }) => { - {/*{Object.entries(data).map(([title, percent], index) => (*/} - {/* */} - {/*))}*/} - {Object.entries(data).map(([title, values], index) => - Object.entries(values).map(([subTitle, percent]) => ( + {answers + .slice(ANSWERS_PER_PAGE * (page - 1), ANSWERS_PER_PAGE * page) + .map(({ title, percent }, index) => ( - )), - )} + ))} - + ); }; diff --git a/src/pages/Analytics/Answers/Results.tsx b/src/pages/Analytics/Answers/Results.tsx index 9d192457..965f41e0 100644 --- a/src/pages/Analytics/Answers/Results.tsx +++ b/src/pages/Analytics/Answers/Results.tsx @@ -5,7 +5,8 @@ import { Typography, useTheme, } from "@mui/material"; -import { FC } from "react"; + +import type { FC } from "react"; type ResultProps = { title: string; @@ -17,12 +18,6 @@ type ResultsProps = { data: Record | null; }; -const RESULTS_MOCK: Record = { - "Заголовок результата": 100, - "Результат пропущен": 7, - Другое: 27, -}; - const Result = ({ title, percent, highlight }: ResultProps) => { const theme = useTheme(); @@ -76,12 +71,13 @@ const Result = ({ title, percent, highlight }: ResultProps) => { export const Results: FC = ({ data }) => { const theme = useTheme(); - if (!data) + if (!data || !Object.keys(data).length) return ( нет данных о результатах ); + return ( = { const Device = ({ title, devices }: DeviceProps) => { const theme = useTheme(); - if (!devices) { + if (!devices || !Object.keys(devices ?? {}).length) { return {title} - нет данных; } @@ -84,7 +84,7 @@ const Device = ({ title, devices }: DeviceProps) => { }, }} > - {id} + {id ? id : "Неопределено"} {value.toFixed(1)} % diff --git a/src/pages/Analytics/General.tsx b/src/pages/Analytics/General.tsx index 0e55ab09..abd9cc8a 100644 --- a/src/pages/Analytics/General.tsx +++ b/src/pages/Analytics/General.tsx @@ -9,7 +9,7 @@ type GeneralItemsProps = { title: string; general: Record; color: string; - numberType: "sum" | "percent"; + numberType: "sum" | "percent" | "time"; }; type GeneralProps = { @@ -24,13 +24,13 @@ const COLORS: Record = { }; const dateParser = (object: Record): Record => { - const result = {} as Record + const result = {} as Record; for (var key in object) { - result[moment.utc(Number(key)*1000).format('MM/DD/YYYY')] = object[key] - console.log(result) + result[moment.utc(Number(key) * 1000).format("DD/MM/YYYY")] = object[key]; + console.log(result); } return result; -} +}; const GeneralItem = ({ title, @@ -44,10 +44,15 @@ const GeneralItem = ({ const numberValue = numberType === "sum" ? Object.values(general).reduce((total, item) => total + item, 0) - : Object.entries(general).reduce( + : 0 + Object.entries(general).reduce( (total, [key, value]) => total + (value / Number(key)) * 100, 0, ) / Object.keys(general).length || Number(0); + + console.log("general" , general) + console.log(Object.keys(general).length === 0) + if (Object.keys(general).length === 0) return {`${title} - нет данных`} return ( moment.utc(Number(value)*1000).format('MM/DD/YYYY') }]} + + xAxis={[ + { + data: Object.keys(general), + valueFormatter: (value) => + moment.utc(Number(value) * 1000).format("DD/MM/YYYY"), + }, + ]} series={[{ data: Object.values(general) }]} + // dataset={Object.entries(general).map(([, v]) => moment.unix(v).format("ss/mm/HH")).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})} height={220} colors={[color]} sx={{ @@ -113,25 +126,25 @@ export const General: FC = ({ data }) => { v > 0).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}) || { 0: 0 }} color={COLORS[0]} /> v > 0).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}) || { 0: 0 }} color={COLORS[1]} /> v > 0).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}) || { 0: 0 }} color={COLORS[2]} /> v > 0).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}) || { 0: 0 }} color={COLORS[3]} /> diff --git a/src/pages/Tariffs/Tabs.tsx b/src/pages/Tariffs/Tabs.tsx index 329ea1ef..005e8640 100644 --- a/src/pages/Tariffs/Tabs.tsx +++ b/src/pages/Tariffs/Tabs.tsx @@ -4,8 +4,8 @@ import { CustomTab } from "./CustomTab"; type TabsProps = { names: string[]; items: string[]; - selectedItem: "count" | "day" | "dop"; - setSelectedItem: (num: "count" | "day" | "dop") => void; + selectedItem: "day" | "count" | "dop"; + setSelectedItem: (num: "day" | "count" | "dop") => void; }; export const Tabs = ({ @@ -18,7 +18,7 @@ export const Tabs = ({ sx={{ m: "25px" }} TabIndicatorProps={{ sx: { display: "none" } }} value={selectedItem} - onChange={(event, newValue: "count" | "day" | "dop") => { + onChange={(event, newValue: "day" | "count" | "dop") => { setSelectedItem(newValue); }} variant="scrollable" diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index 5d1f4f0b..2797d110 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -32,8 +32,8 @@ import { createTariffElements } from "./tariffsUtils/createTariffElements"; import { currencyFormatter } from "./tariffsUtils/currencyFormatter"; const StepperText: Record = { - count: "Тарифы на объём", day: "Тарифы на время", + count: "Тарифы на объём", dop: "Доп. услуги", }; @@ -50,7 +50,9 @@ function TariffPage() { const [discounts, setDiscounts] = useState(); const [openModal, setOpenModal] = useState({}); const [cash, setCash] = useState("0"); - const [selectedItem, setSelectedItem] = useState<"count" | "day">("count"); + const [selectedItem, setSelectedItem] = useState<"count" | "day" | "dop">( + "day", + ); const { isTestServer } = useDomainDefine(); const [promocodeField, setPromocodeField] = useState(""); @@ -297,7 +299,6 @@ function TariffPage() { justifyContent: "left", display: "grid", gap: "40px", - p: "20px", gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${ isTablet ? "436px" : "360px" }))`,