Merge branch 'add-vk-into-integrations' into 'dev'
Add vk into integrations See merge request frontend/squiz!294
This commit is contained in:
commit
246a090d10
@ -118,6 +118,11 @@ export interface QuizConfig {
|
||||
vkMetricNumber: number | undefined;
|
||||
}
|
||||
|
||||
export enum QuizMetricType {
|
||||
yandex = "yandexMetricNumber",
|
||||
vk = "vkMetricNumber",
|
||||
}
|
||||
|
||||
export type FormContactFieldName =
|
||||
| "name"
|
||||
| "email"
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
import { Box, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { YandexMetricaLogo } from "../mocks/YandexMetricaLogo";
|
||||
|
||||
type PartnerItemProps = {
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
setCompanyName?: (value: string) => void;
|
||||
};
|
||||
|
||||
export const YandexButton: FC<PartnerItemProps> = ({
|
||||
setIsModalOpen,
|
||||
setCompanyName,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const handleClick = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
width: 250,
|
||||
height: 60,
|
||||
backgroundColor: "white",
|
||||
borderRadius: "8px",
|
||||
padding: "0 20px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginBottom: "2%",
|
||||
marginRight: "2%",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => setIsModalOpen(true)}
|
||||
>
|
||||
<YandexMetricaLogo />
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -1,197 +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, { 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";
|
||||
|
||||
interface Props {
|
||||
isModalOpen: boolean;
|
||||
handleCloseModal: () => void;
|
||||
}
|
||||
|
||||
export default function YandexModal({ isModalOpen, handleCloseModal }: 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<boolean>(!!yandexNumber);
|
||||
const [currentValue, setCurrentValue] = useState<string>(
|
||||
yandexNumber ? yandexNumber.toString() : "",
|
||||
);
|
||||
const handleClose = () => {
|
||||
handleCloseModal();
|
||||
if (!yandexNumber) {
|
||||
setIsSave(false);
|
||||
setCurrentValue("");
|
||||
return;
|
||||
}
|
||||
setIsSave(true);
|
||||
setCurrentValue(yandexNumber.toString());
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
handleCloseModal();
|
||||
updateQuiz(quiz?.id, (quiz) => {
|
||||
quiz.config.yandexMetricNumber = currentValue
|
||||
? Number(currentValue)
|
||||
: undefined;
|
||||
});
|
||||
if (!currentValue) {
|
||||
setIsSave(false);
|
||||
return;
|
||||
}
|
||||
setIsSave(true);
|
||||
};
|
||||
const handleEdit = () => {
|
||||
setIsSave(false);
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
setCurrentValue("");
|
||||
setIsSave(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={handleClose}
|
||||
fullWidth
|
||||
PaperProps={{
|
||||
sx: {
|
||||
maxWidth: isTablet ? "100%" : "580px",
|
||||
maxHeight: isTablet ? "100%" : "251px",
|
||||
borderRadius: "12px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "68px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: isMobile ? "20px" : "24px",
|
||||
fontWeight: "500",
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
Аналитика с Яндекс.Метрикой
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={handleClose}
|
||||
sx={{
|
||||
width: "12px",
|
||||
height: "12px",
|
||||
position: "absolute",
|
||||
right: "15px",
|
||||
top: "15px",
|
||||
}}
|
||||
>
|
||||
<CloseIcon
|
||||
sx={{ width: "12px", height: "12px", transform: "scale(1.5)" }}
|
||||
/>
|
||||
</IconButton>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
padding: "15px 20px 15px",
|
||||
flexGrow: 1,
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Typography fontWeight={500}>
|
||||
{isSave ? "Ваш номер счетчика" : "Введите номер счетчика"}
|
||||
</Typography>
|
||||
{isSave && (
|
||||
<Box>
|
||||
<IconButton onClick={handleEdit}>
|
||||
<EditPencil
|
||||
color={theme.palette.brightPurple.main}
|
||||
width={"18px"}
|
||||
height={"18px"}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton onClick={handleClear}>
|
||||
<Trash
|
||||
sx={{
|
||||
width: "24px",
|
||||
"& path": {
|
||||
stroke: theme.palette.brightPurple.main,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<CustomTextField
|
||||
placeholder={isSave ? currentValue : "в формате ХХХХХХХХ"}
|
||||
type={"number"}
|
||||
value={currentValue}
|
||||
disabled={isSave}
|
||||
onChange={(e) => {
|
||||
const onlyNums = e.target.value.replace(/[^0-9]/g, "");
|
||||
setCurrentValue(onlyNums);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
{!isSave && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: isMobile ? "space-between" : "end",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
sx={{ width: isMobile ? "100%" : "130px" }}
|
||||
onClick={handleClose}
|
||||
variant={"outlined"}
|
||||
>
|
||||
Отмена
|
||||
</Button>
|
||||
<Button
|
||||
sx={{ width: isMobile ? "100%" : "130px" }}
|
||||
variant={"contained"}
|
||||
onClick={handleSave}
|
||||
>
|
||||
Сохранить
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@ -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<boolean>(false);
|
||||
const [companyName, setCompanyName] = useState<string | null>(null);
|
||||
const [companyName, setCompanyName] = useState<
|
||||
keyof typeof QuizMetricType | null
|
||||
>(null);
|
||||
useEffect(() => {
|
||||
if (editQuizId === null) navigate("/list");
|
||||
}, [navigate, editQuizId]);
|
||||
@ -62,6 +65,7 @@ export const IntegrationsPage = ({
|
||||
<PartnersBoard
|
||||
partners={partnersMock}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
companyName={companyName}
|
||||
setCompanyName={setCompanyName}
|
||||
isModalOpen={isModalOpen}
|
||||
handleCloseModal={handleCloseModal}
|
||||
|
||||
@ -0,0 +1,263 @@
|
||||
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 { InstructionsBlock } from "./IntsructionsBlock/InstructionsBlock";
|
||||
|
||||
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<boolean>(!!meterNumber);
|
||||
const [currentValue, setCurrentValue] = useState<string>(
|
||||
meterNumber ? meterNumber.toString() : "",
|
||||
);
|
||||
const analyticTexts = useMemo(() => {
|
||||
return {
|
||||
yandex: {
|
||||
header: "Яндекс.Метрикой",
|
||||
counterName: "счетчика",
|
||||
instructionTitle: "Как установить Яндекс Метрику в квиз?",
|
||||
instructionSubTitle: "Инструкция по настройке Яндекс Метрики",
|
||||
instructionHeader: "Настройка счётчика и интеграции",
|
||||
instructionText:
|
||||
"Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.",
|
||||
},
|
||||
vk: {
|
||||
header: "VK Пиксель",
|
||||
counterName: "пикселя",
|
||||
instructionTitle: "Как установить VK Пиксель в квиз?",
|
||||
instructionSubTitle: "Инструкция по настройке VK Пиксель",
|
||||
instructionHeader: "Настройка счётчика и интеграции",
|
||||
instructionText:
|
||||
"Повседневная практика показывает, что дальнейшее развитие различных форм деятельности требуют определения и уточнения соответствующий условий активизации.",
|
||||
},
|
||||
};
|
||||
}, []);
|
||||
|
||||
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 (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={handleClose}
|
||||
fullWidth
|
||||
PaperProps={{
|
||||
sx: {
|
||||
maxWidth: isTablet ? "100%" : "920px",
|
||||
borderRadius: "12px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "68px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: isMobile ? "20px" : "24px",
|
||||
fontWeight: "500",
|
||||
padding: "20px",
|
||||
color: theme.palette.grey2.main,
|
||||
}}
|
||||
>
|
||||
Аналитика с {analyticTexts[companyName]?.header}
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={handleClose}
|
||||
sx={{
|
||||
width: "12px",
|
||||
height: "12px",
|
||||
position: "absolute",
|
||||
right: "15px",
|
||||
top: "15px",
|
||||
}}
|
||||
>
|
||||
<CloseIcon
|
||||
sx={{ width: "12px", height: "12px", transform: "scale(1.5)" }}
|
||||
/>
|
||||
</IconButton>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
padding: "20px 20px",
|
||||
flexGrow: 1,
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
maxWidth: isMobile ? "100%" : "590px",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Typography fontWeight={500}>
|
||||
{isSave
|
||||
? `Ваш номер ${analyticTexts[companyName]?.counterName}`
|
||||
: `Введите номер ${analyticTexts[companyName]?.counterName}`}
|
||||
</Typography>
|
||||
{isSave && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
position: "absolute",
|
||||
right: "0",
|
||||
top: "0",
|
||||
}}
|
||||
>
|
||||
<IconButton onClick={handleEdit} sx={{ padding: "0" }}>
|
||||
<EditPencil
|
||||
color={theme.palette.brightPurple.main}
|
||||
width={"24px"}
|
||||
height={"24px"}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton onClick={handleClear} sx={{ padding: "0" }}>
|
||||
<Trash
|
||||
sx={{
|
||||
width: "24px",
|
||||
"& path": {
|
||||
stroke: theme.palette.brightPurple.main,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: isMobile ? "column" : "row",
|
||||
gap: "20px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<CustomTextField
|
||||
sxForm={{ maxWidth: isMobile ? "100%" : "590px" }}
|
||||
placeholder={isSave ? currentValue : "в формате ХХХХХХХХ"}
|
||||
type={"number"}
|
||||
value={currentValue}
|
||||
disabled={isSave}
|
||||
onChange={(e) => {
|
||||
const onlyNums = e.target.value.replace(/[^0-9]/g, "");
|
||||
setCurrentValue(onlyNums);
|
||||
}}
|
||||
/>
|
||||
{!isSave && (
|
||||
<Box
|
||||
sx={{
|
||||
width: isMobile ? "100%" : "auto",
|
||||
display: "flex",
|
||||
justifyContent: isMobile ? "space-between" : "end",
|
||||
gap: "10px",
|
||||
}}
|
||||
>
|
||||
{meterNumber && !isSave && (
|
||||
<Button
|
||||
sx={{ width: isMobile ? "100%" : "130px", height: "44px" }}
|
||||
onClick={handleClose}
|
||||
variant={"outlined"}
|
||||
>
|
||||
Отмена
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
sx={{ width: isMobile ? "100%" : "130px", height: "44px" }}
|
||||
variant={"contained"}
|
||||
onClick={handleSave}
|
||||
>
|
||||
Сохранить
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<InstructionsBlock
|
||||
headerText={analyticTexts[companyName]?.instructionTitle}
|
||||
subHeaderText={analyticTexts[companyName]?.instructionSubTitle}
|
||||
instructionTitle={analyticTexts[companyName]?.instructionHeader}
|
||||
instructionsText={analyticTexts[companyName]?.instructionText}
|
||||
/>
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
88
src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx
Normal file
88
src/pages/IntegrationsPage/PartnersBoard/AnalyticsModal/IntsructionsBlock/InstructionsBlock.tsx
Normal file
@ -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<InstructionsBlockProps> = ({
|
||||
headerText,
|
||||
instructionsText,
|
||||
subHeaderText,
|
||||
instructionTitle,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const [isInstructionOpen, setIsInstructionOpen] = useState(false);
|
||||
return (
|
||||
<Box>
|
||||
<Box
|
||||
onClick={() => 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 && (
|
||||
<KeyboardArrowUpIcon
|
||||
fontSize="medium"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "20px",
|
||||
right: "20px",
|
||||
transition: "transform 0.3s",
|
||||
transform: isInstructionOpen ? "rotate(0deg" : "rotate(180deg)",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Typography
|
||||
sx={{
|
||||
marginBottom: "4px",
|
||||
fontWeight: "500",
|
||||
width: isMobile ? "90%" : "100%",
|
||||
}}
|
||||
>
|
||||
{headerText}
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "16px", color: theme.palette.grey2.main }}>
|
||||
{subHeaderText}
|
||||
</Typography>
|
||||
</Box>
|
||||
{isInstructionOpen && (
|
||||
<Box
|
||||
sx={{
|
||||
borderRadius: " 0 0 12px 12px",
|
||||
padding: "20px",
|
||||
border: "1px solid #E5E5E5",
|
||||
borderTop: isInstructionOpen ? "none" : "1px solid #E5E5E5",
|
||||
maxHeight: isMobile ? "240px" : "300px",
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontWeight: "500",
|
||||
color: theme.palette.grey3.main,
|
||||
marginBottom: "15px",
|
||||
}}
|
||||
>
|
||||
{instructionTitle}
|
||||
</Typography>
|
||||
<Typography sx={{ color: theme.palette.grey3.main }}>
|
||||
{instructionsText}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -1,7 +1,10 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { YandexButton } from "../IntegrationYandex/YandexButton";
|
||||
import YandexModal from "../IntegrationYandex/YandexModal";
|
||||
import { ServiceButton } from "./ServiceButton/ServiceButton";
|
||||
import { YandexMetricaLogo } from "../mocks/YandexMetricaLogo";
|
||||
import AnalyticsModal from "./AnalyticsModal/AnalyticsModal";
|
||||
import { VKPixelLogo } from "../mocks/VKPixelLogo";
|
||||
import { QuizMetricType } from "@model/quizSettings";
|
||||
|
||||
export type Partner = {
|
||||
name: string;
|
||||
@ -12,7 +15,8 @@ export type Partner = {
|
||||
type PartnersBoardProps = {
|
||||
partners: Partner[];
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
setCompanyName: (value: string) => void;
|
||||
companyName: keyof typeof QuizMetricType | null;
|
||||
setCompanyName: (value: keyof typeof QuizMetricType) => void;
|
||||
isModalOpen: boolean;
|
||||
handleCloseModal: () => void;
|
||||
};
|
||||
@ -22,17 +26,18 @@ export const PartnersBoard: FC<PartnersBoardProps> = ({
|
||||
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<string, Partner[]>,
|
||||
);
|
||||
// const partnersByCategory = partners.reduce(
|
||||
// (acc, partner) => {
|
||||
// (acc[partner.category] = acc[partner.category] || []).push(partner);
|
||||
// return acc;
|
||||
// },
|
||||
// {} as Record<string, Partner[]>,
|
||||
// );
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -74,21 +79,47 @@ export const PartnersBoard: FC<PartnersBoardProps> = ({
|
||||
{/* </Box>*/}
|
||||
{/* </Box>*/}
|
||||
{/*))}*/}
|
||||
|
||||
<Box>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{
|
||||
textAlign: { xs: "center", sm: "start", md: "start" },
|
||||
textAlign: { xs: "start", sm: "start", md: "start" },
|
||||
lineHeight: "1",
|
||||
marginBottom: "12px",
|
||||
}}
|
||||
>
|
||||
Аналитика
|
||||
</Typography>
|
||||
<YandexButton setIsModalOpen={setIsModalOpen} />
|
||||
<YandexModal
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
justifyContent: { xs: "start", sm: "start", md: "start" },
|
||||
}}
|
||||
>
|
||||
<ServiceButton
|
||||
logo={<YandexMetricaLogo />}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
name={"yandex"}
|
||||
setCompanyName={setCompanyName}
|
||||
/>
|
||||
<ServiceButton
|
||||
logo={<VKPixelLogo />}
|
||||
title={"VK Пиксель"}
|
||||
name={"vk"}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
setCompanyName={setCompanyName}
|
||||
></ServiceButton>
|
||||
</Box>
|
||||
</Box>
|
||||
{companyName && (
|
||||
<AnalyticsModal
|
||||
isModalOpen={isModalOpen}
|
||||
handleCloseModal={handleCloseModal}
|
||||
companyName={companyName}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { QuizMetricType } from "@model/quizSettings";
|
||||
|
||||
type PartnerItemProps = {
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
setCompanyName: (value: keyof typeof QuizMetricType) => void;
|
||||
logo?: JSX.Element;
|
||||
title?: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const ServiceButton: FC<PartnerItemProps> = ({
|
||||
setIsModalOpen,
|
||||
logo,
|
||||
title,
|
||||
name,
|
||||
setCompanyName,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const handleClick = () => {
|
||||
setCompanyName(name as keyof typeof QuizMetricType);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
width: 250,
|
||||
height: 60,
|
||||
backgroundColor: "white",
|
||||
borderRadius: "8px",
|
||||
padding: "0 20px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginBottom: "2%",
|
||||
marginRight: "2%",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{logo && logo}
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
fontWeight: "400",
|
||||
marginLeft: "15px",
|
||||
}}
|
||||
>
|
||||
{title && title}
|
||||
</Typography>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
10
src/pages/IntegrationsPage/mocks/VKLogo.svg
Normal file
10
src/pages/IntegrationsPage/mocks/VKLogo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 65 KiB |
6
src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx
Normal file
6
src/pages/IntegrationsPage/mocks/VKPixelLogo.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import React from "react";
|
||||
import { ReactComponent as VKLogo } from "./VKLogo.svg";
|
||||
|
||||
export const VKPixelLogo = () => {
|
||||
return <VKLogo />;
|
||||
};
|
||||
@ -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 (
|
||||
<Box
|
||||
@ -82,12 +101,9 @@ export default function AvailablePrivilege() {
|
||||
<Typography variant={"body1"} sx={{ color: "#4D4D4D" }}>
|
||||
Безлимитные заявки:{" "}
|
||||
<strong>
|
||||
{
|
||||
quizUnlimDays > 0 && quizUnlimDays < 1 ?
|
||||
"последний день"
|
||||
:
|
||||
`${Math.trunc(quizUnlimDays)} ${declOfNum(Math.trunc(quizUnlimDays), DayForm)}`
|
||||
}
|
||||
{quizUnlimDays > 0 && quizUnlimDays < 1
|
||||
? "последний день"
|
||||
: `${Math.trunc(quizUnlimDays)} ${declOfNum(Math.trunc(quizUnlimDays), DayForm)}`}
|
||||
</strong>
|
||||
</Typography>
|
||||
{quizCnt !== 0 && (
|
||||
@ -99,12 +115,9 @@ export default function AvailablePrivilege() {
|
||||
<Typography variant={"body1"} sx={{ color: "#4D4D4D" }}>
|
||||
Скрытие логотипа PenaQuiz:{" "}
|
||||
<strong>
|
||||
{
|
||||
squizBadgeDays > 0 && squizBadgeDays < 1 ?
|
||||
"последний день"
|
||||
:
|
||||
`${Math.trunc(squizBadgeDays)} ${declOfNum(Math.trunc(squizBadgeDays), DayForm)}`
|
||||
}
|
||||
{squizBadgeDays > 0 && squizBadgeDays < 1
|
||||
? "последний день"
|
||||
: `${Math.trunc(squizBadgeDays)} ${declOfNum(Math.trunc(squizBadgeDays), DayForm)}`}
|
||||
</strong>
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@ -72,7 +72,6 @@ export const SidebarMobile: FC<Iprops> = ({
|
||||
};
|
||||
|
||||
const clickInput = (event: MouseEvent) => {
|
||||
debugger;
|
||||
if (ref.current && !ref.current?.contains(event.target as Node))
|
||||
setInputOpen(false);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user