diff --git a/src/api/makeRequest.ts b/src/api/makeRequest.ts index f3fd8dac..a3bdef6c 100644 --- a/src/api/makeRequest.ts +++ b/src/api/makeRequest.ts @@ -6,26 +6,38 @@ import { clearUserData } from "@root/user"; import { clearQuizData } from "@root/quizes/store"; import { redirect } from "react-router-dom"; +interface MakeRequest { + method?: Method | undefined; + url: string; + body?: unknown; + useToken?: boolean | undefined; + contentType?: boolean | undefined; + responseType?: ResponseType | undefined; + signal?: AbortSignal | undefined; + withCredentials?: boolean | undefined; +} -interface MakeRequest { method?: Method | undefined; url: string; body?: unknown; useToken?: boolean | undefined; contentType?: boolean | undefined; responseType?: ResponseType | undefined; signal?: AbortSignal | undefined; withCredentials?: boolean | undefined; } +async function makeRequest( + data: MakeRequest, +): Promise { + try { + const response = await KIT.makeRequest(data); -async function makeRequest(data: MakeRequest): Promise { - try { - const response = await KIT.makeRequest(data) - - return response as TResponse - } catch (e) { - const error = e as AxiosError; - //@ts-ignore - if (error.response?.status === 400 && error.response?.data?.message === "refreshToken is empty") { - - cleanAuthTicketData(); - clearAuthToken(); - clearUserData(); - clearQuizData(); - redirect("/"); - } - throw e - }; -}; -export default makeRequest; \ No newline at end of file + return response as TResponse; + } catch (e) { + const error = e as AxiosError; + //@ts-ignore + if ( + error.response?.status === 400 && + error.response?.data?.message === "refreshToken is empty" + ) { + cleanAuthTicketData(); + clearAuthToken(); + clearUserData(); + clearQuizData(); + redirect("/"); + } + throw e; + } +} +export default makeRequest; diff --git a/src/assets/icons/designs/smallSize/design1.jpg b/src/assets/icons/designs/smallSize/design1.jpg new file mode 100644 index 00000000..d3886588 Binary files /dev/null and b/src/assets/icons/designs/smallSize/design1.jpg differ diff --git a/src/assets/icons/designs/smallSize/design10.jpg b/src/assets/icons/designs/smallSize/design10.jpg new file mode 100644 index 00000000..ce2e3b7b Binary files /dev/null and b/src/assets/icons/designs/smallSize/design10.jpg differ diff --git a/src/assets/icons/designs/smallSize/design2.jpg b/src/assets/icons/designs/smallSize/design2.jpg new file mode 100644 index 00000000..fa586fa2 Binary files /dev/null and b/src/assets/icons/designs/smallSize/design2.jpg differ diff --git a/src/assets/icons/designs/smallSize/design3.jpg b/src/assets/icons/designs/smallSize/design3.jpg new file mode 100644 index 00000000..a3802a6a Binary files /dev/null and b/src/assets/icons/designs/smallSize/design3.jpg differ diff --git a/src/assets/icons/designs/smallSize/design4.jpg b/src/assets/icons/designs/smallSize/design4.jpg new file mode 100644 index 00000000..c1a0b287 Binary files /dev/null and b/src/assets/icons/designs/smallSize/design4.jpg differ diff --git a/src/assets/icons/designs/smallSize/design5.jpg b/src/assets/icons/designs/smallSize/design5.jpg new file mode 100644 index 00000000..e1353864 Binary files /dev/null and b/src/assets/icons/designs/smallSize/design5.jpg differ diff --git a/src/assets/icons/designs/smallSize/design6.jpg b/src/assets/icons/designs/smallSize/design6.jpg new file mode 100644 index 00000000..83b7f27f Binary files /dev/null and b/src/assets/icons/designs/smallSize/design6.jpg differ diff --git a/src/assets/icons/designs/smallSize/design7.jpg b/src/assets/icons/designs/smallSize/design7.jpg new file mode 100644 index 00000000..2b819452 Binary files /dev/null and b/src/assets/icons/designs/smallSize/design7.jpg differ diff --git a/src/assets/icons/designs/smallSize/design8.jpg b/src/assets/icons/designs/smallSize/design8.jpg new file mode 100644 index 00000000..262c94cc Binary files /dev/null and b/src/assets/icons/designs/smallSize/design8.jpg differ diff --git a/src/assets/icons/designs/smallSize/design9.jpg b/src/assets/icons/designs/smallSize/design9.jpg new file mode 100644 index 00000000..97b8492c Binary files /dev/null and b/src/assets/icons/designs/smallSize/design9.jpg differ diff --git a/src/pages/Analytics/Analytics.tsx b/src/pages/Analytics/Analytics.tsx index 87a7635c..de409bfb 100644 --- a/src/pages/Analytics/Analytics.tsx +++ b/src/pages/Analytics/Analytics.tsx @@ -154,6 +154,7 @@ export default function Analytics() { onClose={handleClose} onOpen={handleOpen} // defaultValue={now} + minDate={moment(quiz?.created_at)} sx={{ width: isMobile ? "285px" : "170px", "& .MuiOutlinedInput-root": { @@ -199,6 +200,7 @@ export default function Analytics() { onClose={handleCloseEnd} onOpen={handleOpenEnd} // defaultValue={now} + minDate={moment(quiz?.created_at)} sx={{ width: isMobile ? "285px" : "170px", "& .MuiOutlinedInput-root": { diff --git a/src/pages/Analytics/General.tsx b/src/pages/Analytics/General.tsx index d8bf3ebf..1ba30350 100644 --- a/src/pages/Analytics/General.tsx +++ b/src/pages/Analytics/General.tsx @@ -112,30 +112,48 @@ const GeneralItemTimeConv = ({ numberType, calculateTime = false, conversionValue, - day, }: GeneralItemsProps) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(700)); - const data = Object.entries(general).sort( - ([nextValue], [currentValue]) => Number(nextValue) - Number(currentValue), - ); - const days = data.map(([value]) => value); - const time = data.map(([_, value]) => value); + const data = Object.entries(general) + .sort((a, b) => a[0] - b[0]); - const numberValue = calculateTime - ? time.reduce((total, value) => total + value, 0) / days.length - : conversionValue; + 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((item) => item === 0) + Object.values(general).every((x) => x === 0) ) { return ( {`${title} - нет данных`} ); } + return ( {title} - {calculateTime - ? `${getCalculatedTime(numberValue ?? 0)} с` - : `${numberValue?.toFixed(2) ?? 0}%`} + {calculateTime ? `${getCalculatedTime(numberValue)} с` : `${numberValue.toFixed(2)}%`} - moment.unix(Number(value)).format("DD/MM/YYYY HH") + "ч", + moment.utc(Number(value) * 1000).format("DD/MM/YYYY"), }, ]} series={[ { data: Object.values(time), - valueFormatter: (value) => - calculateTime - ? getCalculatedTime(value) - : String((value * 100).toFixed(2)) + "%", + valueFormatter: (value) => { + console.log("log", value) + return calculateTime ? getCalculatedTime(value) : String((value*100).toFixed(2)) + "%" + } + , }, ]} // dataset={Object.entries(general).map(([, v]) => moment.unix(v).format("ss:mm:HH")).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})} @@ -179,6 +196,7 @@ const GeneralItemTimeConv = ({ ); }; + export const General: FC = ({ data, day }) => { const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); diff --git a/src/pages/DesignPage/DesignFilling.tsx b/src/pages/DesignPage/DesignFilling.tsx index df0c1173..ade55b80 100644 --- a/src/pages/DesignPage/DesignFilling.tsx +++ b/src/pages/DesignPage/DesignFilling.tsx @@ -8,20 +8,19 @@ import { } from "@mui/material"; import { updateQuiz } from "@root/quizes/actions"; import { useCurrentQuiz } from "@root/quizes/hooks"; +import type { DesignItem } from "./DesignGroup"; import { DesignGroup } from "./DesignGroup"; -import Desgin1 from "@icons/designs/design1.jpg"; -import Desgin2 from "@icons/designs/design2.jpg"; -import Desgin3 from "@icons/designs/design3.jpg"; -import Desgin4 from "@icons/designs/design4.jpg"; -import Desgin5 from "@icons/designs/design5.jpg"; -import Desgin6 from "@icons/designs/design6.jpg"; -import Desgin7 from "@icons/designs/design7.jpg"; -import Desgin8 from "@icons/designs/design8.jpg"; -import Desgin9 from "@icons/designs/design9.jpg"; -import Desgin10 from "@icons/designs/design10.jpg"; - -import type { DesignItem } from "./DesignGroup"; +import Desgin1 from "@icons/designs/smallSize/design1.jpg"; +import Desgin2 from "@icons/designs/smallSize/design2.jpg"; +import Desgin3 from "@icons/designs/smallSize/design3.jpg"; +import Desgin4 from "@icons/designs/smallSize/design4.jpg"; +import Desgin5 from "@icons/designs/smallSize/design5.jpg"; +import Desgin6 from "@icons/designs/smallSize/design6.jpg"; +import Desgin7 from "@icons/designs/smallSize/design7.jpg"; +import Desgin8 from "@icons/designs/smallSize/design8.jpg"; +import Desgin9 from "@icons/designs/smallSize/design9.jpg"; +import Desgin10 from "@icons/designs/smallSize/design10.jpg"; const LIGHT_THEME_BUTTONS: DesignItem[] = [ { diff --git a/src/pages/InstallQuiz/InstallQuiz.tsx b/src/pages/InstallQuiz/InstallQuiz.tsx index d63f3257..47f8268f 100644 --- a/src/pages/InstallQuiz/InstallQuiz.tsx +++ b/src/pages/InstallQuiz/InstallQuiz.tsx @@ -76,8 +76,10 @@ export default function InstallQuiz() { const isMobile = useMediaQuery(theme.breakpoints.down(600)); const isSmallMonitor = useMediaQuery(theme.breakpoints.down(1065)); const CopyLink = () => { - let one = document.getElementById("inputLinkone").value; - let text = document.getElementById("inputLink").value; + let one = (document.getElementById("inputLinkone") as HTMLInputElement) + ?.value; + let text = (document.getElementById("inputLink") as HTMLInputElement) + ?.value; // text.select(); navigator.clipboard.writeText(one + text); // document.execCommand("copy"); @@ -408,7 +410,7 @@ export default function InstallQuiz() { id="outlined-multiline-static" multiline rows={9} - value={`
`} + value={`
`} sx={{ "& .MuiInputBase-root": { maxWidth: "520px", diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index d2c6a1a1..650705f5 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -140,7 +140,7 @@ function TariffPage() { link.href = `https://${isTestServer ? "s" : ""}hub.pena.digital/quizpayment?action=squizpay&dif=${cashDif}&data=${token}&userid=${userId}`; document.body.appendChild(link); link.click(); - return + return; } //другая ошибка enqueueSnackbar("Произошла ошибка. Попробуйте позже"); @@ -171,18 +171,18 @@ function TariffPage() { return tariff.privileges[0].privilegeId !== "squizHideBadge"; }); - function handleApplyPromocode () { + function handleApplyPromocode() { if (!promocodeField) return; activatePromocode(promocodeField) .then(async (greetings) => { - enqueueSnackbar(greetings) + enqueueSnackbar(greetings); - const discounts = await makeRequest({ - method: "GET", - url: `${process.env.REACT_APP_DOMAIN}/price/discount/user/${userId}`, - }); - setDiscounts(discounts.Discounts); + const discounts = await makeRequest({ + method: "GET", + url: `${process.env.REACT_APP_DOMAIN}/price/discount/user/${userId}`, + }); + setDiscounts(discounts.Discounts); }) .catch(enqueueSnackbar); } diff --git a/src/ui_kit/Sidebar/SidebarMobile.tsx b/src/ui_kit/Sidebar/SidebarMobile.tsx index 12645cab..8dee27c4 100644 --- a/src/ui_kit/Sidebar/SidebarMobile.tsx +++ b/src/ui_kit/Sidebar/SidebarMobile.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useRef, useState } from "react"; +import React, { ChangeEvent, FC, useEffect, useRef, useState } from "react"; import { Box, FormControl, @@ -49,7 +49,7 @@ export const SidebarMobile: FC = ({ const [inputOpen, setInputOpen] = useState(false); const quiz = useCurrentQuiz(); const [inputValue, setInputValue] = useState(quiz.name); - const ref = useRef(null); + const ref = useRef(null); const heightSidebar = useRef(null); const navigate = useNavigate(); const { pathname } = useLocation(); @@ -62,15 +62,19 @@ export const SidebarMobile: FC = ({ ); useEffect(() => { - observer.current.observe(heightSidebar.current); + if (heightSidebar.current) { + observer.current.observe(heightSidebar.current); + } }, [heightSidebar, observer]); - const handleClick = (event) => { + const handleClick = (event: ChangeEvent) => { setAnchorEl(anchorEl ? null : event.currentTarget); }; - const clickInput = (event) => { - if (ref.current && !ref.current.contains(event.target)) setInputOpen(false); + const clickInput = (event: MouseEvent) => { + debugger; + if (ref.current && !ref.current?.contains(event.target as Node)) + setInputOpen(false); }; useEffect(() => { document.addEventListener("mousedown", clickInput); @@ -88,7 +92,7 @@ export const SidebarMobile: FC = ({ changePage(index); }; const openPopper = Boolean(anchorEl); - const id = openPopper ? "simple-popper" : undefined; + const id = openPopper ? "simple-popper" : ""; return ( void; changePage: (step: number) => void; - anchorEl: HTMLElement; + anchorEl: HTMLElement | null; id: string; }; export const SidebarModal = ({ diff --git a/src/utils/checkQuestionHint.ts b/src/utils/checkQuestionHint.ts index 9c10a9df..d3460f28 100644 --- a/src/utils/checkQuestionHint.ts +++ b/src/utils/checkQuestionHint.ts @@ -10,7 +10,7 @@ import { import { Quiz } from "@model/quiz/quiz"; export const checkQuestionHint = ( - questions: AnyTypedQuizQuestion, + questions: AnyTypedQuizQuestion[], quiz: Quiz, ): Record => { const problems: any = {}; @@ -77,12 +77,17 @@ export const checkQuestionHint = ( (condition: QuestionBranchingRuleMain) => { buffer.forEach((oldCondition: QuestionBranchingRuleMain) => { if (areRulesEqual(condition.rules, oldCondition.rules)) { - const q = getQuestionByContentId(condition.next); - const oldq = getQuestionByContentId(oldCondition.next); + const currentQuestion = getQuestionByContentId(condition.next); + const oldQuestions = getQuestionByContentId(oldCondition.next); + + if (!currentQuestion?.type || !oldQuestions?.type) { + return; + } + pushProblem( question.content.id, - `У вопроса "${q?.title || "noname №" + q?.page}" и "${ - oldq?.title || "noname №" + oldq?.page + `У вопроса "${currentQuestion.title || "noname №" + currentQuestion.page}" и "${ + oldQuestions.title || "noname №" + oldQuestions.page }" одинаковые условия ветвления`, question.title, ); diff --git a/src/utils/deleteFunc.ts b/src/utils/deleteFunc.ts index 580a6ed7..f07db4f1 100644 --- a/src/utils/deleteFunc.ts +++ b/src/utils/deleteFunc.ts @@ -1,4 +1,3 @@ -import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; import { clearRuleForAll, createResult, @@ -10,6 +9,13 @@ import { useQuestionsStore } from "@root/questions/store"; import { updateRootContentId } from "@root/quizes/actions"; import { getCurrentQuiz } from "@root/quizes/hooks"; +import type { + AnyTypedQuizQuestion, + QuestionBranchingRule, + QuestionBranchingRuleMain, +} from "@model/questionTypes/shared"; +import { QuizQuestionResult } from "@model/questionTypes/result"; + //Всё здесь нужно сделать последовательно. И пусть весь мир ждёт. export const DeleteFunction = async (questionId: string) => { @@ -33,7 +39,9 @@ export const DeleteFunction = async (questionId: string) => { const parentQuestion = getQuestionByContentId( question.content.rule.parentId, ); - let startCountParentChildren = parentQuestion.content.rule.children; + let startCountParentChildren = parentQuestion?.type + ? parentQuestion.content.rule.children + : null; //записываем потомков , а их результаты удаляем const getChildren = (parentQuestion: AnyTypedQuizQuestion) => { @@ -67,8 +75,10 @@ export const DeleteFunction = async (questionId: string) => { }), ); - //чистим rule родителя - const newRule = {}; + if (!parentQuestion?.type) { + return; + } + const parentChildren = [...parentQuestion.content.rule.children]; if (parentChildren.includes(question.content.id)) @@ -77,15 +87,21 @@ export const DeleteFunction = async (questionId: string) => { 1, ); - newRule.main = parentQuestion.content.rule.main.filter( - (data) => data.next !== question.content.id, + const main = parentQuestion.content.rule.main.filter( + (data: QuestionBranchingRuleMain) => data.next !== question.content.id, ); //удаляем условия перехода от родителя к этому вопросу - newRule.parentId = parentQuestion.content.rule.parentId; - newRule.default = + const defaultValue = parentQuestion.content.rule.parentId === question.content.id ? "" : parentQuestion.content.rule.parentId; - newRule.children = parentChildren; + + //чистим rule родителя + const newRule: QuestionBranchingRule = { + main, + default: defaultValue, + children: parentChildren, + parentId: parentQuestion.content.rule.parentId, + }; await updateQuestion(question.content.rule.parentId, (PQ) => { PQ.content.rule = newRule; @@ -101,10 +117,13 @@ export const DeleteFunction = async (questionId: string) => { //сделать результ родителя видимым если у него не осталось потомков if (startCountParentChildren.length === 1) { - if (parentResult) { - await updateQuestion(parentResult.content.id, (q) => { - q.content.usage = true; - }); + if (parentResult?.type) { + await updateQuestion( + parentResult.content.id, + (item) => { + item.content.usage = true; + }, + ); } else { //почему-то не существует результа у родителя. Создаём. Новосозданные результы видны сразу await createResult(quiz.backendId, parentQuestion.content.id);