From 012169e12b50ca01c9d2a42605b8573dc422696e Mon Sep 17 00:00:00 2001 From: aleksandr-raw <104529174+aleksandr-raw@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:23:58 +0400 Subject: [PATCH 1/3] Implemented universal usage for button and modal, added VK pixel --- src/model/quizSettings.ts | 5 ++ .../IntegrationsPage/IntegrationsPage.tsx | 3 +- .../PartnersBoard/PartnersBoard.tsx | 70 +++++++++++++------ .../ServiceButton/ServiceButton.tsx} | 27 +++++-- .../ServiceModal/ServiceModal.tsx} | 34 ++++++--- src/pages/IntegrationsPage/mocks/VKLogo.svg | 10 +++ .../IntegrationsPage/mocks/VKPixelLogo.tsx | 6 ++ 7 files changed, 116 insertions(+), 39 deletions(-) rename src/pages/IntegrationsPage/{IntegrationYandex/YandexButton.tsx => PartnersBoard/ServiceButton/ServiceButton.tsx} (54%) rename src/pages/IntegrationsPage/{IntegrationYandex/YandexModal.tsx => PartnersBoard/ServiceModal/ServiceModal.tsx} (84%) create mode 100644 src/pages/IntegrationsPage/mocks/VKLogo.svg create mode 100644 src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx diff --git a/src/model/quizSettings.ts b/src/model/quizSettings.ts index b728326a..b068fbb2 100644 --- a/src/model/quizSettings.ts +++ b/src/model/quizSettings.ts @@ -118,6 +118,11 @@ export interface QuizConfig { vkMetricNumber: number | undefined; } +export enum QuizMetricType { + yandex = "yandexMetricNumber", + vk = "vkMetricNumber", +} + export type FormContactFieldName = | "name" | "email" diff --git a/src/pages/IntegrationsPage/IntegrationsPage.tsx b/src/pages/IntegrationsPage/IntegrationsPage.tsx index c090b11a..03c02029 100644 --- a/src/pages/IntegrationsPage/IntegrationsPage.tsx +++ b/src/pages/IntegrationsPage/IntegrationsPage.tsx @@ -22,7 +22,7 @@ export const IntegrationsPage = ({ const navigate = useNavigate(); const isMobile = useMediaQuery(theme.breakpoints.down(660)); const [isModalOpen, setIsModalOpen] = useState(false); - const [companyName, setCompanyName] = useState(null); + const [companyName, setCompanyName] = useState(""); useEffect(() => { if (editQuizId === null) navigate("/list"); }, [navigate, editQuizId]); @@ -62,6 +62,7 @@ export const IntegrationsPage = ({ void; + companyName: string; setCompanyName: (value: string) => void; isModalOpen: boolean; handleCloseModal: () => void; @@ -22,17 +25,18 @@ export const PartnersBoard: FC = ({ setIsModalOpen, isModalOpen, handleCloseModal, + companyName, setCompanyName, }) => { const theme = useTheme(); - const partnersByCategory = partners.reduce( - (acc, partner) => { - (acc[partner.category] = acc[partner.category] || []).push(partner); - return acc; - }, - {} as Record, - ); + // const partnersByCategory = partners.reduce( + // (acc, partner) => { + // (acc[partner.category] = acc[partner.category] || []).push(partner); + // return acc; + // }, + // {} as Record, + // ); return ( = ({ {/* */} {/* */} {/*))}*/} - - Аналитика - - - + + Аналитика + + + } + setIsModalOpen={setIsModalOpen} + name={"yandex"} + setCompanyName={setCompanyName} + /> + } + title={"VK Пиксель"} + name={"vk"} + setIsModalOpen={setIsModalOpen} + setCompanyName={setCompanyName} + > + + + ); diff --git a/src/pages/IntegrationsPage/IntegrationYandex/YandexButton.tsx b/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx similarity index 54% rename from src/pages/IntegrationsPage/IntegrationYandex/YandexButton.tsx rename to src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx index 89d55334..26f27bb9 100644 --- a/src/pages/IntegrationsPage/IntegrationYandex/YandexButton.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx @@ -1,19 +1,25 @@ -import { Box, useTheme } from "@mui/material"; +import { Box, Typography, useTheme } from "@mui/material"; import { FC } from "react"; -import { YandexMetricaLogo } from "../mocks/YandexMetricaLogo"; type PartnerItemProps = { setIsModalOpen: (value: boolean) => void; - setCompanyName?: (value: string) => void; + setCompanyName: (value: string) => void; + logo?: JSX.Element; + title?: string; + name: string; }; -export const YandexButton: FC = ({ +export const ServiceButton: FC = ({ setIsModalOpen, + logo, + title, + name, setCompanyName, }) => { const theme = useTheme(); const handleClick = () => { + setCompanyName(name); setIsModalOpen(true); }; @@ -32,9 +38,18 @@ export const YandexButton: FC = ({ marginRight: "2%", cursor: "pointer", }} - onClick={() => setIsModalOpen(true)} + onClick={handleClick} > - + {logo && logo} + + {title && title} + ); diff --git a/src/pages/IntegrationsPage/IntegrationYandex/YandexModal.tsx b/src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx similarity index 84% rename from src/pages/IntegrationsPage/IntegrationYandex/YandexModal.tsx rename to src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx index da6fd076..f6a106c7 100644 --- a/src/pages/IntegrationsPage/IntegrationYandex/YandexModal.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx @@ -8,45 +8,49 @@ import { } from "@mui/material"; import Box from "@mui/material/Box"; import CloseIcon from "@mui/icons-material/Close"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import CustomTextField from "@ui_kit/CustomTextField"; import EditPencil from "@icons/EditPencil"; import Trash from "@icons/trash"; import { updateQuiz } from "@root/quizes/actions"; import { useCurrentQuiz } from "@root/quizes/hooks"; +import { QuizMetricType } from "@model/quizSettings"; interface Props { isModalOpen: boolean; handleCloseModal: () => void; + companyName: string; } -export default function YandexModal({ isModalOpen, handleCloseModal }: Props) { +export default function ServiceModal({ + isModalOpen, + handleCloseModal, + companyName, +}: Props) { const theme = useTheme(); const quiz = useCurrentQuiz(); const isMobile = useMediaQuery(theme.breakpoints.down(600)); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); - const yandexNumber = quiz?.config.yandexMetricNumber; - const [isSave, setIsSave] = useState(!!yandexNumber); + const configName = QuizMetricType[companyName as keyof typeof QuizMetricType]; + const meterNumber = quiz?.config[configName]; + const [isSave, setIsSave] = useState(!!meterNumber); const [currentValue, setCurrentValue] = useState( - yandexNumber ? yandexNumber.toString() : "", + meterNumber ? meterNumber.toString() : "", ); const handleClose = () => { handleCloseModal(); - if (!yandexNumber) { + if (!meterNumber) { setIsSave(false); setCurrentValue(""); return; } setIsSave(true); - setCurrentValue(yandexNumber.toString()); + setCurrentValue(meterNumber.toString()); }; - const handleSave = () => { handleCloseModal(); updateQuiz(quiz?.id, (quiz) => { - quiz.config.yandexMetricNumber = currentValue - ? Number(currentValue) - : undefined; + quiz.config[configName] = currentValue ? Number(currentValue) : undefined; }); if (!currentValue) { setIsSave(false); @@ -63,6 +67,14 @@ export default function YandexModal({ isModalOpen, handleCloseModal }: Props) { setIsSave(false); }; + useEffect(() => { + const configName = + QuizMetricType[companyName as keyof typeof QuizMetricType]; + const meterNumber = quiz?.config[configName]; + setCurrentValue(meterNumber ? meterNumber.toString() : ""); + setIsSave(!!meterNumber); + }, [companyName]); + return ( + + + + + + + + diff --git a/src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx b/src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx new file mode 100644 index 00000000..059b8c67 --- /dev/null +++ b/src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import { ReactComponent as VKLogo } from "./VKLogo.svg"; + +export const VKPixelLogo = () => { + return ; +}; From 93574151bbf83695b361a475e154ff649f894782 Mon Sep 17 00:00:00 2001 From: aleksandr-raw <104529174+aleksandr-raw@users.noreply.github.com> Date: Wed, 1 May 2024 13:34:37 +0400 Subject: [PATCH 2/3] created new analytics modal design --- .../IntegrationsPage/IntegrationsPage.tsx | 5 +- .../AnalyticsModal/AnalyticsModal.tsx | 328 ++++++++++++++++++ .../PartnersBoard/PartnersBoard.tsx | 19 +- .../ServiceButton/ServiceButton.tsx | 5 +- .../ServiceModal/ServiceModal.tsx | 209 ----------- src/pages/createQuize/AvailablePrivilege.tsx | 57 +-- src/ui_kit/Sidebar/SidebarMobile.tsx | 1 - 7 files changed, 381 insertions(+), 243 deletions(-) create mode 100644 src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx delete mode 100644 src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx diff --git a/src/pages/IntegrationsPage/IntegrationsPage.tsx b/src/pages/IntegrationsPage/IntegrationsPage.tsx index 03c02029..7357dca1 100644 --- a/src/pages/IntegrationsPage/IntegrationsPage.tsx +++ b/src/pages/IntegrationsPage/IntegrationsPage.tsx @@ -6,6 +6,7 @@ import { useQuizStore } from "@root/quizes/store"; import { useNavigate } from "react-router-dom"; import { PartnersBoard } from "./PartnersBoard/PartnersBoard"; import { partnersMock } from "./mocks/MockData"; +import { QuizMetricType } from "@model/quizSettings"; interface IntegrationsPageProps { heightSidebar: number; @@ -22,7 +23,9 @@ export const IntegrationsPage = ({ const navigate = useNavigate(); const isMobile = useMediaQuery(theme.breakpoints.down(660)); const [isModalOpen, setIsModalOpen] = useState(false); - const [companyName, setCompanyName] = useState(""); + const [companyName, setCompanyName] = useState< + keyof typeof QuizMetricType | null + >(null); useEffect(() => { if (editQuizId === null) navigate("/list"); }, [navigate, editQuizId]); diff --git a/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx new file mode 100644 index 00000000..dab29fcd --- /dev/null +++ b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx @@ -0,0 +1,328 @@ +import { + Button, + Dialog, + IconButton, + Typography, + useMediaQuery, + useTheme, +} from "@mui/material"; +import Box from "@mui/material/Box"; +import CloseIcon from "@mui/icons-material/Close"; +import React, { useEffect, useMemo, useState } from "react"; +import CustomTextField from "@ui_kit/CustomTextField"; +import EditPencil from "@icons/EditPencil"; +import Trash from "@icons/trash"; +import { updateQuiz } from "@root/quizes/actions"; +import { useCurrentQuiz } from "@root/quizes/hooks"; +import { QuizMetricType } from "@model/quizSettings"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; + +interface Props { + isModalOpen: boolean; + handleCloseModal: () => void; + companyName: keyof typeof QuizMetricType; +} + +export default function AnalyticsModal({ + isModalOpen, + handleCloseModal, + companyName, +}: Props) { + const theme = useTheme(); + const quiz = useCurrentQuiz(); + const isMobile = useMediaQuery(theme.breakpoints.down(600)); + const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const configName = QuizMetricType[companyName]; + const meterNumber = quiz?.config[configName]; + const [isSave, setIsSave] = useState(!!meterNumber); + const [currentValue, setCurrentValue] = useState( + meterNumber ? meterNumber.toString() : "", + ); + const [isInstructionOpen, setIsInstructionOpen] = useState(false); + const analyticTexts = useMemo(() => { + return { + yandex: { + header: "Яндекс.Метрикой", + counterName: "счетчика", + instructionTitle: "Как установить Яндекс Метрику в квиз?", + instructionSubTitle: "Инструкция по настройке Яндекс Метрики", + instructionHeader: "Настройка счётчика и интеграции", + instructionText: + "Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.", + }, + vk: { + header: "VK Пиксель", + counterName: "пикселя", + instructionTitle: "Как установить VK Пиксель в квиз?", + instructionSubTitle: "Инструкция по настройке VK Пиксель", + instructionHeader: "Настройка счётчика и интеграции", + instructionText: + "Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.", + }, + }; + }, []); + + const handleClose = () => { + handleCloseModal(); + setIsInstructionOpen(false); + if (!meterNumber) { + setIsSave(false); + setCurrentValue(""); + return; + } + setIsSave(true); + setCurrentValue(meterNumber.toString()); + }; + const handleSave = () => { + handleCloseModal(); + updateQuiz(quiz?.id, (quiz) => { + quiz.config[configName] = currentValue ? Number(currentValue) : undefined; + }); + if (!currentValue) { + setIsSave(false); + return; + } + setIsSave(true); + }; + const handleEdit = () => { + setIsSave(false); + }; + + const handleClear = () => { + setCurrentValue(""); + setIsSave(false); + }; + + useEffect(() => { + const configName = + QuizMetricType[companyName as keyof typeof QuizMetricType]; + const meterNumber = quiz?.config[configName]; + setCurrentValue(meterNumber ? meterNumber.toString() : ""); + setIsSave(!!meterNumber); + setIsInstructionOpen(false); + }, [companyName]); + + return ( + + + + Аналитика с {analyticTexts[companyName]?.header} + + + + + + + + + + {isSave + ? `Ваш номер ${analyticTexts[companyName]?.counterName}` + : `Введите номер ${analyticTexts[companyName]?.counterName}`} + + {isSave && ( + + + + + + + + + )} + + + { + const onlyNums = e.target.value.replace(/[^0-9]/g, ""); + setCurrentValue(onlyNums); + }} + /> + {!isSave && ( + + {meterNumber && !isSave && ( + + )} + + + )} + + + + setIsInstructionOpen(!isInstructionOpen)} + sx={{ + cursor: "pointer", + backgroundColor: theme.palette.background.default, + borderRadius: isInstructionOpen ? "12px 12px 0 0" : "12px", + padding: "20px", + border: "1px solid #E5E5E5", + borderBottom: isInstructionOpen ? "none" : "1px solid #E5E5E5", + position: "relative", + }} + > + {isMobile && ( + + )} + + {analyticTexts[companyName]?.instructionTitle} + + + {analyticTexts[companyName]?.instructionSubTitle} + + + {isInstructionOpen && ( + + + {analyticTexts[companyName]?.instructionHeader} + + + {analyticTexts[companyName]?.instructionText} + + + )} + + + + ); +} diff --git a/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx b/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx index b5e377e4..e39d98e8 100644 --- a/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx @@ -2,8 +2,9 @@ import { Box, Typography, useTheme } from "@mui/material"; import { FC } from "react"; import { ServiceButton } from "./ServiceButton/ServiceButton"; import { YandexMetricaLogo } from "../mocks/YandexMetricaLogo"; -import ServiceModal from "./ServiceModal/ServiceModal"; +import AnalyticsModal from "./AnalyticsModal/AnalyticsModal"; import { VKPixelLogo } from "../mocks/VKPixelLogo"; +import { QuizMetricType } from "@model/quizSettings"; export type Partner = { name: string; @@ -14,8 +15,8 @@ export type Partner = { type PartnersBoardProps = { partners: Partner[]; setIsModalOpen: (value: boolean) => void; - companyName: string; - setCompanyName: (value: string) => void; + companyName: keyof typeof QuizMetricType | null; + setCompanyName: (value: keyof typeof QuizMetricType) => void; isModalOpen: boolean; handleCloseModal: () => void; }; @@ -112,11 +113,13 @@ export const PartnersBoard: FC = ({ > - + {companyName && ( + + )} ); }; diff --git a/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx b/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx index 26f27bb9..4773e19f 100644 --- a/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/ServiceButton/ServiceButton.tsx @@ -1,9 +1,10 @@ import { Box, Typography, useTheme } from "@mui/material"; import { FC } from "react"; +import { QuizMetricType } from "@model/quizSettings"; type PartnerItemProps = { setIsModalOpen: (value: boolean) => void; - setCompanyName: (value: string) => void; + setCompanyName: (value: keyof typeof QuizMetricType) => void; logo?: JSX.Element; title?: string; name: string; @@ -19,7 +20,7 @@ export const ServiceButton: FC = ({ const theme = useTheme(); const handleClick = () => { - setCompanyName(name); + setCompanyName(name as keyof typeof QuizMetricType); setIsModalOpen(true); }; diff --git a/src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx b/src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx deleted file mode 100644 index f6a106c7..00000000 --- a/src/pages/IntegrationsPage/PartnersBoard/ServiceModal/ServiceModal.tsx +++ /dev/null @@ -1,209 +0,0 @@ -import { - Button, - Dialog, - IconButton, - Typography, - useMediaQuery, - useTheme, -} from "@mui/material"; -import Box from "@mui/material/Box"; -import CloseIcon from "@mui/icons-material/Close"; -import React, { useEffect, useState } from "react"; -import CustomTextField from "@ui_kit/CustomTextField"; -import EditPencil from "@icons/EditPencil"; -import Trash from "@icons/trash"; -import { updateQuiz } from "@root/quizes/actions"; -import { useCurrentQuiz } from "@root/quizes/hooks"; -import { QuizMetricType } from "@model/quizSettings"; - -interface Props { - isModalOpen: boolean; - handleCloseModal: () => void; - companyName: string; -} - -export default function ServiceModal({ - isModalOpen, - handleCloseModal, - companyName, -}: Props) { - const theme = useTheme(); - const quiz = useCurrentQuiz(); - const isMobile = useMediaQuery(theme.breakpoints.down(600)); - const isTablet = useMediaQuery(theme.breakpoints.down(1000)); - const configName = QuizMetricType[companyName as keyof typeof QuizMetricType]; - const meterNumber = quiz?.config[configName]; - const [isSave, setIsSave] = useState(!!meterNumber); - const [currentValue, setCurrentValue] = useState( - meterNumber ? meterNumber.toString() : "", - ); - const handleClose = () => { - handleCloseModal(); - if (!meterNumber) { - setIsSave(false); - setCurrentValue(""); - return; - } - setIsSave(true); - setCurrentValue(meterNumber.toString()); - }; - const handleSave = () => { - handleCloseModal(); - updateQuiz(quiz?.id, (quiz) => { - quiz.config[configName] = currentValue ? Number(currentValue) : undefined; - }); - if (!currentValue) { - setIsSave(false); - return; - } - setIsSave(true); - }; - const handleEdit = () => { - setIsSave(false); - }; - - const handleClear = () => { - setCurrentValue(""); - setIsSave(false); - }; - - useEffect(() => { - const configName = - QuizMetricType[companyName as keyof typeof QuizMetricType]; - const meterNumber = quiz?.config[configName]; - setCurrentValue(meterNumber ? meterNumber.toString() : ""); - setIsSave(!!meterNumber); - }, [companyName]); - - return ( - - - - Аналитика с Яндекс.Метрикой - - - - - - - - - - {isSave ? "Ваш номер счетчика" : "Введите номер счетчика"} - - {isSave && ( - - - - - - - - - )} - - - { - const onlyNums = e.target.value.replace(/[^0-9]/g, ""); - setCurrentValue(onlyNums); - }} - /> - - {!isSave && ( - - - - - )} - - - ); -} diff --git a/src/pages/createQuize/AvailablePrivilege.tsx b/src/pages/createQuize/AvailablePrivilege.tsx index 3d1cbd3b..abcdd9e0 100644 --- a/src/pages/createQuize/AvailablePrivilege.tsx +++ b/src/pages/createQuize/AvailablePrivilege.tsx @@ -50,19 +50,38 @@ export default function AvailablePrivilege() { const squizHideBadge = userPrivileges?.squizHideBadge?.amount || 0; //Где дни - amount - это на сколько дней выдан безлимит. т.е. не сколько осталось, а на сколько дней выдано - function getCramps (amount: number, created_at: string) { - if (created_at.length === 0) return 0 - const currentDate = moment() + function getCramps(amount: number, created_at: string) { + if (created_at.length === 0) return 0; + const currentDate = moment(); - return Number((moment(moment(created_at).add(amount, "days").diff(currentDate)).unix() / 86400).toFixed(1)) + return Number( + ( + moment( + moment(created_at).add(amount, "days").diff(currentDate), + ).unix() / 86400 + ).toFixed(1), + ); } - const quizUnlimDays = getCramps(quizUnlimTime, userPrivileges?.quizUnlimTime?.created_at || "") - const squizBadgeDays = getCramps(squizHideBadge, userPrivileges?.squizHideBadge?.created_at || "") + const quizUnlimDays = getCramps( + quizUnlimTime, + userPrivileges?.quizUnlimTime?.created_at || "", + ); + const squizBadgeDays = getCramps( + squizHideBadge, + userPrivileges?.squizHideBadge?.created_at || "", + ); - const currentDate = moment() - console.log(quizUnlimDays) - console.log(moment()) - console.log(moment(moment(userPrivileges?.quizUnlimTime?.created_at).add(quizUnlimTime, "days"))) + const currentDate = moment(); + console.log(quizUnlimDays); + console.log(moment()); + console.log( + moment( + moment(userPrivileges?.quizUnlimTime?.created_at).add( + quizUnlimTime, + "days", + ), + ), + ); return ( Безлимитные заявки:{" "} - { - quizUnlimDays > 0 && quizUnlimDays < 1 ? - "последний день" - : - `${Math.trunc(quizUnlimDays)} ${declOfNum(Math.trunc(quizUnlimDays), DayForm)}` - } + {quizUnlimDays > 0 && quizUnlimDays < 1 + ? "последний день" + : `${Math.trunc(quizUnlimDays)} ${declOfNum(Math.trunc(quizUnlimDays), DayForm)}`} {quizCnt !== 0 && ( @@ -99,12 +115,9 @@ export default function AvailablePrivilege() { Скрытие логотипа PenaQuiz:{" "} - { - squizBadgeDays > 0 && squizBadgeDays < 1 ? - "последний день" - : - `${Math.trunc(squizBadgeDays)} ${declOfNum(Math.trunc(squizBadgeDays), DayForm)}` - } + {squizBadgeDays > 0 && squizBadgeDays < 1 + ? "последний день" + : `${Math.trunc(squizBadgeDays)} ${declOfNum(Math.trunc(squizBadgeDays), DayForm)}`} )} diff --git a/src/ui_kit/Sidebar/SidebarMobile.tsx b/src/ui_kit/Sidebar/SidebarMobile.tsx index 462361f3..4cf2b29f 100644 --- a/src/ui_kit/Sidebar/SidebarMobile.tsx +++ b/src/ui_kit/Sidebar/SidebarMobile.tsx @@ -72,7 +72,6 @@ export const SidebarMobile: FC = ({ }; const clickInput = (event: MouseEvent) => { - debugger; if (ref.current && !ref.current?.contains(event.target as Node)) setInputOpen(false); }; From 7dc2dd1ec162ba6e9e08213a24b44680b8fe93b8 Mon Sep 17 00:00:00 2001 From: aleksandr-raw <104529174+aleksandr-raw@users.noreply.github.com> Date: Wed, 1 May 2024 13:49:13 +0400 Subject: [PATCH 3/3] refactored analytics modal component --- .../AnalyticsModal/AnalyticsModal.tsx | 79 ++--------------- .../IntsructionsBlock/InstructionsBlock.tsx | 88 +++++++++++++++++++ 2 files changed, 95 insertions(+), 72 deletions(-) create mode 100644 src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx diff --git a/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx index dab29fcd..32461c20 100644 --- a/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/AnalyticsModal.tsx @@ -15,7 +15,7 @@ import Trash from "@icons/trash"; import { updateQuiz } from "@root/quizes/actions"; import { useCurrentQuiz } from "@root/quizes/hooks"; import { QuizMetricType } from "@model/quizSettings"; -import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import { InstructionsBlock } from "./IntsructionsBlock/InstructionsBlock"; interface Props { isModalOpen: boolean; @@ -38,7 +38,6 @@ export default function AnalyticsModal({ const [currentValue, setCurrentValue] = useState( meterNumber ? meterNumber.toString() : "", ); - const [isInstructionOpen, setIsInstructionOpen] = useState(false); const analyticTexts = useMemo(() => { return { yandex: { @@ -64,7 +63,6 @@ export default function AnalyticsModal({ const handleClose = () => { handleCloseModal(); - setIsInstructionOpen(false); if (!meterNumber) { setIsSave(false); setCurrentValue(""); @@ -99,7 +97,6 @@ export default function AnalyticsModal({ const meterNumber = quiz?.config[configName]; setCurrentValue(meterNumber ? meterNumber.toString() : ""); setIsSave(!!meterNumber); - setIsInstructionOpen(false); }, [companyName]); return ( @@ -254,74 +251,12 @@ export default function AnalyticsModal({ )} - - setIsInstructionOpen(!isInstructionOpen)} - sx={{ - cursor: "pointer", - backgroundColor: theme.palette.background.default, - borderRadius: isInstructionOpen ? "12px 12px 0 0" : "12px", - padding: "20px", - border: "1px solid #E5E5E5", - borderBottom: isInstructionOpen ? "none" : "1px solid #E5E5E5", - position: "relative", - }} - > - {isMobile && ( - - )} - - {analyticTexts[companyName]?.instructionTitle} - - - {analyticTexts[companyName]?.instructionSubTitle} - - - {isInstructionOpen && ( - - - {analyticTexts[companyName]?.instructionHeader} - - - {analyticTexts[companyName]?.instructionText} - - - )} - + ); diff --git a/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx new file mode 100644 index 00000000..afa87ee1 --- /dev/null +++ b/src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx @@ -0,0 +1,88 @@ +import Box from "@mui/material/Box"; +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp"; +import { Typography, useMediaQuery, useTheme } from "@mui/material"; +import React, { FC, useState } from "react"; + +type InstructionsBlockProps = { + headerText: string; + subHeaderText: string; + instructionTitle: string; + instructionsText: string; +}; + +export const InstructionsBlock: FC = ({ + headerText, + instructionsText, + subHeaderText, + instructionTitle, +}) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down(600)); + const [isInstructionOpen, setIsInstructionOpen] = useState(false); + return ( + + setIsInstructionOpen(!isInstructionOpen)} + sx={{ + cursor: "pointer", + backgroundColor: theme.palette.background.default, + borderRadius: isInstructionOpen ? "12px 12px 0 0" : "12px", + padding: "20px", + border: "1px solid #E5E5E5", + borderBottom: isInstructionOpen ? "none" : "1px solid #E5E5E5", + position: "relative", + }} + > + {isMobile && ( + + )} + + {headerText} + + + {subHeaderText} + + + {isInstructionOpen && ( + + + {instructionTitle} + + + {instructionsText} + + + )} + + ); +};