diff --git a/package.json b/package.json index f95c8746..e3b42b47 100755 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "notistack": "^3.0.1", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", + "react-colorful": "^5.6.1", "react-cytoscapejs": "^2.0.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", diff --git a/src/api/integration.ts b/src/api/integration.ts index 6a253808..775e6979 100644 --- a/src/api/integration.ts +++ b/src/api/integration.ts @@ -256,7 +256,7 @@ export const getIntegrationRules = async ( method: "GET", url: `${API_URL}/rules/${quizID}`, }); - return [settingsResponse]; + return [settingsResponse || null]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); return [null, `Не удалось получить настройки интеграции. ${error}`]; @@ -331,3 +331,18 @@ export const getCustomFields = async ( return [null, `Не удалось получить список кастомных полей. ${error}`]; } }; + +//Отвязать аккаунт амо от публикации + +export const removeAmoAccount = async (): Promise<[void | null, string?]> => { + try { + await makeRequest({ + method: "DELETE", + url: `${API_URL}/delete`, + }); + return [null, ""]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + return [null, `Не удалось отвязать аккаунт. ${error}`]; + } +}; \ No newline at end of file diff --git a/src/model/questionTypes/shared.ts b/src/model/questionTypes/shared.ts index 7cdd8a28..163d7ee7 100644 --- a/src/model/questionTypes/shared.ts +++ b/src/model/questionTypes/shared.ts @@ -96,6 +96,10 @@ export type AnyTypedQuizQuestion = | QuizQuestionRating | QuizQuestionResult; + export type AllTypesQuestion = + | AnyTypedQuizQuestion + | UntypedQuizQuestion; + type FilterQuestionsWithVariants = T extends { content: { variants: QuestionVariant[] }; } diff --git a/src/model/questionTypes/text.ts b/src/model/questionTypes/text.ts index c38101aa..b8b47909 100644 --- a/src/model/questionTypes/text.ts +++ b/src/model/questionTypes/text.ts @@ -1,4 +1,4 @@ -import type { QuizQuestionBase, QuestionHint, PreviewRule } from "./shared"; +import type { PreviewRule, QuestionHint, QuizQuestionBase } from "./shared"; export interface QuizQuestionText extends QuizQuestionBase { type: "text"; @@ -13,7 +13,7 @@ export interface QuizQuestionText extends QuizQuestionBase { required: boolean; /** Чекбокс "Автозаполнение адреса" */ autofill: boolean; - answerType: "single" | "multi"; + answerType: "single" | "multi" | "numberOnly"; hint: QuestionHint; rule: PreviewRule; back: string; diff --git a/src/pages/InstallQuiz/QuizInstallationCard/WidgetSetupByType/BannerWidgetSetup/BannerWidgetSetup.tsx b/src/pages/InstallQuiz/QuizInstallationCard/WidgetSetupByType/BannerWidgetSetup/BannerWidgetSetup.tsx index a0ed5250..6e790cf1 100644 --- a/src/pages/InstallQuiz/QuizInstallationCard/WidgetSetupByType/BannerWidgetSetup/BannerWidgetSetup.tsx +++ b/src/pages/InstallQuiz/QuizInstallationCard/WidgetSetupByType/BannerWidgetSetup/BannerWidgetSetup.tsx @@ -37,21 +37,17 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { const quiz = useCurrentQuiz(); const [widgetWidth, setWidgetWidth] = useState(""); const [widgetHeight, setWidgetHeight] = useState(""); - const [isAutoopenQuizSettingsOpen, setIsAutoopenQuizSettingsOpen] = - useState(false); + const [isAutoopenQuizSettingsOpen, setIsAutoopenQuizSettingsOpen] = useState(false); const [hideOnMobile, setHideOnMobile] = useState(false); const [rounded, setRounded] = useState(false); const [withShadow, setWithShadow] = useState(false); const [buttonFlash, setButtonFlash] = useState(false); - const [buttonBackgroundColor, setButtonBackgroundColor] = useState( - theme.palette.brightPurple.main, - ); + const [buttonBackgroundColor, setButtonBackgroundColor] = useState(theme.palette.brightPurple.main); const [buttonTextColor, setButtonTextColor] = useState("#FFFFFF"); const [autoShowQuiz, setAutoShowQuiz] = useState(false); const [autoShowQuizTime, setAutoShowQuizTime] = useState(10); const [openOnLeaveAttempt, setOpenOnLeaveAttempt] = useState(false); - const [position, setPosition] = - useState("bottomleft"); + const [position, setPosition] = useState("bottomleft"); const [bannerFullWidth, setBannerFullWidth] = useState(false); const [autoShowWidgetTime, setAutoShowWidgetTime] = useState(10); const [appealText, setAppealText] = useState(""); @@ -88,12 +84,7 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { : undefined, }); - return ( - - ); + return ; } return ( @@ -129,17 +120,39 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { sx={[ { position: "absolute", - top: "calc(12.5 / 262 * 100%)", - left: "calc(50.6 / 520 * 100%)", width: "calc(196 / 520 * 100%)", height: "calc(30 / 262 * 100%)", }, - bannerFullWidth && { - top: "calc(7 / 262 * 100%)", - left: "calc(45 / 520 * 100%)", - width: "calc(348 / 520 * 100%)", - height: "calc(30 / 262 * 100%)", + position === "topleft" && { + top: "calc(12.5 / 262 * 100%)", + left: "calc(50.6 / 520 * 100%)", }, + position === "topright" && { + top: "calc(12.5 / 262 * 100%)", + left: "calc(190 / 520 * 100%)", + }, + position === "bottomleft" && { + top: "calc(178 / 262 * 100%)", + left: "calc(50.6 / 520 * 100%)", + }, + position === "bottomright" && { + top: "calc(178 / 262 * 100%)", + left: "calc(190 / 520 * 100%)", + }, + bannerFullWidth && + position.startsWith("top") && { + top: "calc(7 / 262 * 100%)", + left: "calc(45 / 520 * 100%)", + width: "calc(348 / 520 * 100%)", + height: "calc(30 / 262 * 100%)", + }, + bannerFullWidth && + position.startsWith("bottom") && { + top: "calc(185 / 262 * 100%)", + left: "calc(45 / 520 * 100%)", + width: "calc(348 / 520 * 100%)", + height: "calc(30 / 262 * 100%)", + }, pulsation && { ":before": { content: "''", @@ -196,16 +209,10 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { color: "white", }} > - + {appealText || "Пройти тест"} - + {quizHeaderText || "Заголовок теста"} @@ -220,8 +227,7 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { height: "calc(10 / 29.5 * 100%)", width: "auto", aspectRatio: 1, - backgroundColor: - rounded || bannerFullWidth ? "#581CA7" : undefined, + backgroundColor: rounded || bannerFullWidth ? "#581CA7" : undefined, borderRadius: "50%", }} /> @@ -255,9 +261,7 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { gap: "20px", }} > - - Ширина окна (px) - + Ширина окна (px) - - Высота окна (px) - + Высота окна (px) - - Текст-призыв - + Текст-призыв setAppealText(e.target.value)} FormControlSx={{ maxWidth: "360px" }} /> - - Заголовок quiz - + Заголовок quiz - - Показывать через - + Показывать через - - секунд - + секунд - - Цвет кнопки - - setButtonBackgroundColor(color)} - /> - - Цвет текста кнопки - - setButtonTextColor(color)} - /> + Цвет кнопки + setButtonBackgroundColor(color)} /> + Цвет текста кнопки + setButtonTextColor(color)} /> - - Расположение - + Расположение } icon={} /> - } + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> } icon={} /> - } + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> @@ -409,23 +387,13 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { } - icon={} - /> - } + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> } - icon={} - /> - } + label="Слева снизу" + value="bottomleft" + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> @@ -436,25 +404,15 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { }} > } - icon={} - /> - } + label="Справа сверху" + value="topright" + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> } - icon={} - /> - } + control={} icon={} />} sx={{ color: theme.palette.grey2.main }} /> @@ -462,26 +420,12 @@ export default function BannerWidgetSetup({ step, nextButton }: Props) { )} - - Параметры - + Параметры {!bannerFullWidth && ( - setRounded(e.target.checked)} - /> + setRounded(e.target.checked)} /> )} - setWithShadow(e.target.checked)} - /> - setButtonFlash(e.target.checked)} - /> + setWithShadow(e.target.checked)} /> + setButtonFlash(e.target.checked)} /> - - Показывать через - + Показывать через - setAutoShowQuizTime(parseInt(e.target.value)) - } + onChange={(e) => setAutoShowQuizTime(parseInt(e.target.value))} FormControlSx={{ width: "90px", }} /> - - секунд - + секунд diff --git a/src/pages/IntegrationsPage/IntegrationsModal/AmoCRMModal.tsx b/src/pages/IntegrationsPage/IntegrationsModal/AmoCRMModal.tsx index 25ab5f08..3d5da094 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/AmoCRMModal.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/AmoCRMModal.tsx @@ -8,24 +8,29 @@ import { import React, { FC, useEffect, useMemo, useState } from "react"; import Box from "@mui/material/Box"; import CloseIcon from "@mui/icons-material/Close"; +import { AmoRemoveAccount } from "./AmoRemoveAccount/AmoRemoveAccount"; import { AmoLogin } from "./AmoLogin/AmoLogin"; import { AmoStep2 } from "./AmoStep2/AmoStep2"; import { AmoStep3 } from "./AmoStep3/AmoStep3"; import { AmoStep4 } from "./AmoStep4/AmoStep4"; import { AmoStep6 } from "./IntegrationStep6/AmoStep6"; +import { AmoStep7 } from "./IntegrationStep7/AmoStep7"; import { AmoModalTitle } from "./AmoModalTitle/AmoModalTitle"; import { AmoSettingsBlock } from "./SettingsBlock/AmoSettingsBlock"; -import { AmoStep7 } from "./IntegrationStep7/AmoStep7"; import { AmoAccountInfo } from "./AmoAccountInfo/AmoAccountInfo"; -import { AccountResponse, getAccount } from "@api/integration"; +import { AccountResponse, IntegrationRules, getAccount, getIntegrationRules } from "@api/integration"; +import { useQuestions } from "@/stores/questions/hooks"; +import { redirect } from "react-router-dom"; +import { enqueueSnackbar } from "notistack"; -export type TitleKeys = "contacts" | "company" | "deal" | "users" | "buyers"; +export type TitleKeys = "contacts" | "company" | "deal" | "buyers"; export type TQuestionEntity = Record; type IntegrationsModalProps = { isModalOpen: boolean; handleCloseModal: () => void; companyName: string | null; + quizID: number | undefined; }; export type TagKeys = "contact" | "company" | "deal" | "buyer"; @@ -35,15 +40,20 @@ export const AmoCRMModal: FC = ({ isModalOpen, handleCloseModal, companyName, + quizID, }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(600)); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); + const { questions } = useQuestions(); + const [step, setStep] = useState(0); const [isSettingsBlock, setIsSettingsBlock] = useState(false); + const [isRemoveAccount, setIsRemoveAccount] = useState(false); const [accountInfo, setAccountInfo] = useState(null); + const [integrationRules, setIntegrationRules] = useState(null); const [selectedPipelinePerformer, setSelectedPipelinePerformer] = useState< string | null >(null); @@ -56,10 +66,9 @@ export const AmoCRMModal: FC = ({ string | null >(null); const [questionEntity, setQuestionEntity] = useState({ + deal: [], contacts: [], company: [], - deal: [], - users: [], buyers: [], }); const [tags, setTags] = useState({ @@ -68,21 +77,38 @@ export const AmoCRMModal: FC = ({ company: [], buyer: [], }); - console.log(accountInfo) + console.log(questionEntity) + console.log(tags) useEffect(() => { - if (isModalOpen) { + if (isModalOpen && quizID !== undefined && !isRemoveAccount) { const fetchAccount = async () => { const [account, error] = await getAccount(); - if (account && !error) { - setAccountInfo(account); - } else { + + if (error) { + enqueueSnackbar(error) setAccountInfo(null); } + if (account) { + setAccountInfo(account); + } }; + const fetchRules = async () => { + const [settingsResponse, error] = await getIntegrationRules(quizID.toString()); + + if (error) { + enqueueSnackbar(error) + setIntegrationRules(null); + } + if (settingsResponse) { + setIntegrationRules(settingsResponse); + } + }; + fetchAccount(); + fetchRules(); } - }, [isModalOpen]); + }, [isModalOpen, isRemoveAccount]); const handleNextStep = () => { setStep((prevState) => prevState + 1); @@ -152,26 +178,27 @@ export const AmoCRMModal: FC = ({ ), }, { - title: "Соотнесение вопросов и сущностей", + title: "Добавление тегов", isSettingsAvailable: true, component: ( ), }, { - title: "Добавление тегов", + title: "Соотнесение вопросов и сущностей", isSettingsAvailable: true, component: ( ), }, @@ -190,6 +217,9 @@ export const AmoCRMModal: FC = ({ const stepTitles = steps.map((step) => step.title); + //Если нет контекста квиза, то и делать на этой страничке нечего + if (quizID === undefined) redirect("/list") + return ( = ({ isSettingsBlock={isSettingsBlock} setIsSettingsBlock={setIsSettingsBlock} setStep={setStep} + startRemoveAccount={() => setIsRemoveAccount(true)} /> - {isSettingsBlock ? ( + {isRemoveAccount && ( + setIsRemoveAccount(false)} + /> + )} + {isSettingsBlock && ( = ({ tags={tags} /> - ) : ( + )} + {!isSettingsBlock && !isRemoveAccount && ( {steps[step].component} )} diff --git a/src/pages/IntegrationsPage/IntegrationsModal/AmoModalTitle/AmoModalTitle.tsx b/src/pages/IntegrationsPage/IntegrationsModal/AmoModalTitle/AmoModalTitle.tsx index 39e297fb..d155e105 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/AmoModalTitle/AmoModalTitle.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/AmoModalTitle/AmoModalTitle.tsx @@ -10,6 +10,7 @@ type AmoModalTitleProps = { isSettingsBlock?: boolean; setIsSettingsBlock: (value: boolean) => void; setStep: (value: number) => void; + startRemoveAccount: () => void; }; export const AmoModalTitle: FC = ({ @@ -18,13 +19,16 @@ export const AmoModalTitle: FC = ({ setIsSettingsBlock, isSettingsBlock, setStep, + startRemoveAccount }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(600)); - const handleClick = useCallback(() => { + console.log(isSettingsBlock) + const handleClick = useCallback(async () => { if (isSettingsBlock) { - setIsSettingsBlock(false); + startRemoveAccount(); + setIsSettingsBlock(false) setStep(0); return; } diff --git a/src/pages/IntegrationsPage/IntegrationsModal/AmoRemoveAccount/AmoRemoveAccount.tsx b/src/pages/IntegrationsPage/IntegrationsModal/AmoRemoveAccount/AmoRemoveAccount.tsx new file mode 100644 index 00000000..032ed4c2 --- /dev/null +++ b/src/pages/IntegrationsPage/IntegrationsModal/AmoRemoveAccount/AmoRemoveAccount.tsx @@ -0,0 +1,61 @@ +import { FC } from "react" +import { Button, Typography, useTheme, Box } from "@mui/material" +import { removeAmoAccount } from "@/api/integration"; +import { enqueueSnackbar } from "notistack"; + + +interface Props { + stopThisPage: () => void; + +} + +export const AmoRemoveAccount: FC = ({ + stopThisPage, + +}: Props) => { + const theme = useTheme(); + const removeAccount = async () => { + const [, error] = await removeAmoAccount() + + if (error) { + enqueueSnackbar(error) + } else { + stopThisPage() + } + }; + + return ( + + + Вы хотите сменить аккаунт? + + + + + + + ) +} \ No newline at end of file diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/AmoStep6.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/AmoStep6.tsx index 4c7d6645..c65cfae6 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/AmoStep6.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/AmoStep6.tsx @@ -7,23 +7,24 @@ import { useMemo, useState, } from "react"; -import { ItemsSelectionView } from "./ItemsSelectionView/ItemsSelectionView"; -import { ItemDetailsView } from "./ItemDetailsView/ItemDetailsView"; -import { TitleKeys, TQuestionEntity } from "../AmoCRMModal"; -import Box from "@mui/material/Box"; -type AmoStep6Props = { - handlePrevStep: () => void; +import { TagKeys, TTags } from "../AmoCRMModal"; +import Box from "@mui/material/Box"; +import { ItemsSelectionView } from "../IntegrationStep7/ItemsSelectionView/ItemsSelectionView"; +import { TagsDetailsView } from "./TagsDetailsView/TagsDetailsView"; + +type Props = { handleNextStep: () => void; - questionEntity: TQuestionEntity; - setQuestionEntity: Dispatch>; + handlePrevStep: () => void; + tags: TTags; + setTags: Dispatch>; }; -export const AmoStep6: FC = ({ - handlePrevStep, +export const AmoStep6: FC = ({ handleNextStep, - questionEntity, - setQuestionEntity, + handlePrevStep, + tags, + setTags, }) => { const theme = useTheme(); const [isSelection, setIsSelection] = useState(false); @@ -33,14 +34,14 @@ export const AmoStep6: FC = ({ const handleAdd = useCallback(() => { if (!activeItem || !selectedValue) return; - setQuestionEntity((prevState) => ({ + setTags((prevState) => ({ ...prevState, - [activeItem]: [...prevState[activeItem as TitleKeys], selectedValue], + [activeItem]: [...prevState[activeItem as TagKeys], selectedValue], })); - }, [activeItem, setQuestionEntity, selectedValue]); + }, [activeItem, setTags, selectedValue]); const items = useMemo( - () => ["Город", "Имя", "Фамилия", "Отчество", "Контрагент"], + () => ["#тег с результатом 1", "#еще один тег с результатом 2", "#тег"], [], ); @@ -58,6 +59,7 @@ export const AmoStep6: FC = ({ items={items} selectedValue={selectedValue} setSelectedValue={setSelectedValue} + type={"typeTags"} onSmallBtnClick={() => { setActiveItem(null); setIsSelection(false); @@ -69,11 +71,11 @@ export const AmoStep6: FC = ({ }} /> ) : ( - )} diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/TagsDetailsView/TagsDetailsView.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/TagsDetailsView/TagsDetailsView.tsx similarity index 88% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/TagsDetailsView/TagsDetailsView.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/TagsDetailsView/TagsDetailsView.tsx index f2091b71..785bbd3b 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/TagsDetailsView/TagsDetailsView.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/TagsDetailsView/TagsDetailsView.tsx @@ -2,19 +2,19 @@ import { Box, Typography, useTheme } from "@mui/material"; import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock"; import { FC } from "react"; import { TagKeys, TTags } from "../../AmoCRMModal"; -import { Item } from "../../IntegrationStep6/Item/Item"; +import { Item } from "../../IntegrationStep7/Item/Item"; type TagsDetailsViewProps = { setIsSelection: (value: boolean) => void; - handleSmallBtn: () => void; - handleLargeBtn: () => void; + handlePrevStep: () => void; + handleNextStep: () => void; tags: TTags; setActiveItem: (value: string | null) => void; }; export const TagsDetailsView: FC = ({ - handleSmallBtn, - handleLargeBtn, + handlePrevStep, + handleNextStep, tags, setActiveItem, setIsSelection, @@ -89,9 +89,8 @@ export const TagsDetailsView: FC = ({ }} > diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/AmoStep7.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/AmoStep7.tsx index ca18f1a8..e32e6926 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/AmoStep7.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/AmoStep7.tsx @@ -7,24 +7,26 @@ import { useMemo, useState, } from "react"; - -import { TagKeys, TTags } from "../AmoCRMModal"; +import { ItemsSelectionView } from "./ItemsSelectionView/ItemsSelectionView"; +import { ItemDetailsView } from "./ItemDetailsView/ItemDetailsView"; +import { TitleKeys, TQuestionEntity } from "../AmoCRMModal"; import Box from "@mui/material/Box"; -import { ItemsSelectionView } from "../IntegrationStep6/ItemsSelectionView/ItemsSelectionView"; -import { TagsDetailsView } from "./TagsDetailsView/TagsDetailsView"; +import type { AllTypesQuestion } from "@model/questionTypes/shared" -type AmoStep7Props = { - handleSmallBtn: () => void; - handleLargeBtn: () => void; - tags: TTags; - setTags: Dispatch>; +type Props = { + handlePrevStep: () => void; + handleNextStep: () => void; + questionEntity: TQuestionEntity; + setQuestionEntity: Dispatch>; + questions: AllTypesQuestion[]; }; -export const AmoStep7: FC = ({ - handleSmallBtn, - handleLargeBtn, - tags, - setTags, +export const AmoStep7: FC = ({ + handlePrevStep, + handleNextStep, + questionEntity, + setQuestionEntity, + questions, }) => { const theme = useTheme(); const [isSelection, setIsSelection] = useState(false); @@ -34,14 +36,14 @@ export const AmoStep7: FC = ({ const handleAdd = useCallback(() => { if (!activeItem || !selectedValue) return; - setTags((prevState) => ({ + setQuestionEntity((prevState) => ({ ...prevState, - [activeItem]: [...prevState[activeItem as TagKeys], selectedValue], + [activeItem]: [...prevState[activeItem as TitleKeys], selectedValue], })); - }, [activeItem, setTags, selectedValue]); + }, [activeItem, setQuestionEntity, selectedValue]); const items = useMemo( - () => ["#тег с результатом 1", "#еще один тег с результатом 2", "#тег"], + () => ["Город", "Имя", "Фамилия", "Отчество", "Контрагент"], [], ); @@ -59,7 +61,6 @@ export const AmoStep7: FC = ({ items={items} selectedValue={selectedValue} setSelectedValue={setSelectedValue} - type={"typeTags"} onSmallBtnClick={() => { setActiveItem(null); setIsSelection(false); @@ -69,13 +70,14 @@ export const AmoStep7: FC = ({ setActiveItem(null); setIsSelection(false); }} + questions={questions} /> ) : ( - )} diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/AnswerItem/AnswerItem.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/AnswerItem/AnswerItem.tsx similarity index 100% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/AnswerItem/AnswerItem.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/AnswerItem/AnswerItem.tsx diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/IconBtnAdd/IconBtnAdd.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/IconBtnAdd/IconBtnAdd.tsx similarity index 100% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/IconBtnAdd/IconBtnAdd.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/IconBtnAdd/IconBtnAdd.tsx diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/Item.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/Item.tsx similarity index 100% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/Item/Item.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/Item/Item.tsx diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemDetailsView/ItemDetailsView.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemDetailsView/ItemDetailsView.tsx similarity index 85% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemDetailsView/ItemDetailsView.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemDetailsView/ItemDetailsView.tsx index e468013d..3efb878b 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemDetailsView/ItemDetailsView.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemDetailsView/ItemDetailsView.tsx @@ -4,19 +4,19 @@ import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock"; import { FC } from "react"; import { TQuestionEntity } from "../../AmoCRMModal"; -type TitleKeys = "contacts" | "company" | "deal" | "users" | "buyers"; +type TitleKeys = "contacts" | "company" | "deal" | "buyers"; type ItemDetailsViewProps = { setIsSelection: (value: boolean) => void; - handlePrevStep: () => void; - handleNextStep: () => void; + handleSmallBtn: () => void; + handleLargeBtn: () => void; questionEntity: TQuestionEntity; setActiveItem: (value: string | null) => void; }; export const ItemDetailsView: FC = ({ - handlePrevStep, - handleNextStep, + handleSmallBtn, + handleLargeBtn, questionEntity, setActiveItem, setIsSelection, @@ -69,8 +69,9 @@ export const ItemDetailsView: FC = ({ }} > diff --git a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemsSelectionView/ItemsSelectionView.tsx b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemsSelectionView/ItemsSelectionView.tsx similarity index 95% rename from src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemsSelectionView/ItemsSelectionView.tsx rename to src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemsSelectionView/ItemsSelectionView.tsx index ee2a12f6..d3aa0c45 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep6/ItemsSelectionView/ItemsSelectionView.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/IntegrationStep7/ItemsSelectionView/ItemsSelectionView.tsx @@ -2,6 +2,7 @@ import { Box } from "@mui/material"; import { CustomRadioGroup } from "../../../../../components/CustomRadioGroup/CustomRadioGroup"; import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock"; import { FC } from "react"; +import { AllTypesQuestion } from "@/model/questionTypes/shared"; type ItemsSelectionViewProps = { type?: string; diff --git a/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx b/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx index 5510eb08..dc086bf1 100644 --- a/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx +++ b/src/pages/IntegrationsPage/PartnersBoard/PartnersBoard.tsx @@ -6,6 +6,7 @@ import { YandexMetricaLogo } from "../mocks/YandexMetricaLogo"; import { VKPixelLogo } from "../mocks/VKPixelLogo"; import { QuizMetricType } from "@model/quizSettings"; import { AmoCRMLogo } from "../mocks/AmoCRMLogo"; +import { useCurrentQuiz } from "@/stores/quizes/hooks"; const AnalyticsModal = lazy(() => import("./AnalyticsModal/AnalyticsModal").then((module) => ({ @@ -43,6 +44,8 @@ export const PartnersBoard: FC = ({ const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(600)); + const quiz = useCurrentQuiz(); + return ( = ({ isModalOpen={isAmoCrmModalOpen} handleCloseModal={handleCloseAmoSRMModal} companyName={companyName} + quizID={quiz?.backendId} /> )} diff --git a/src/pages/Questions/DataOptions/settingData.tsx b/src/pages/Questions/DataOptions/settingData.tsx index 59044ab4..9b9f290a 100644 --- a/src/pages/Questions/DataOptions/settingData.tsx +++ b/src/pages/Questions/DataOptions/settingData.tsx @@ -4,13 +4,17 @@ import CustomCheckbox from "@ui_kit/CustomCheckbox"; import type { QuizQuestionDate } from "../../../model/questionTypes/date"; type SettingsDataProps = { - question: QuizQuestionDate; + questionId: string; + isRequired: boolean; + isDateRange: boolean; + isTime: boolean; }; -export default function SettingsData({ question }: SettingsDataProps) { +export default function SettingsData({ questionId, isRequired, isDateRange, isTime }: SettingsDataProps) { const theme = useTheme(); const isWrappColumn = useMediaQuery(theme.breakpoints.down(980)); const isMobile = useMediaQuery(theme.breakpoints.down(790)); + const isTablet = useMediaQuery(theme.breakpoints.down(900)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); return ( @@ -18,19 +22,66 @@ export default function SettingsData({ question }: SettingsDataProps) { sx={{ display: "flex", justifyContent: "space-between", - flexDirection: isWrappColumn ? "column" : null, + flexDirection: isTablet ? "column" : "row", + marginRight: isFigmaTablte ? (isMobile ? "0" : "0px") : "30px", + pb: "20px", + pl: "20px", + pt: isTablet ? "5px" : "0px", }} > + + Настройки ответов + + { + updateQuestion(questionId, (question) => { + question.content.dateRange = target.checked; + }); + }} + /> + { + updateQuestion(questionId, (question) => { + question.content.time = target.checked; + }); + }} + /> + + { - updateQuestion(question.id, (question) => { + updateQuestion(questionId, (question) => { question.content.required = !target.checked; }); }} diff --git a/src/pages/Questions/DataOptions/switchData.tsx b/src/pages/Questions/DataOptions/switchData.tsx index 805eecd6..18c2997b 100644 --- a/src/pages/Questions/DataOptions/switchData.tsx +++ b/src/pages/Questions/DataOptions/switchData.tsx @@ -7,13 +7,17 @@ interface Props { question: QuizQuestionDate; } -export default function SwitchData({ - switchState = "setting", - question, -}: Props) { +export default function SwitchData({ switchState = "setting", question }: Props) { switch (switchState) { case "setting": - return ; + return ( + + ); case "help": return ( (function ({ - questionId, - isRequired, -}) { +const SettingEmoji = memo(function ({ questionId, isRequired, isMulti, isOwn }) { const theme = useTheme(); const isWrappColumn = useMediaQuery(theme.breakpoints.down(980)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); + const isTablet = useMediaQuery(theme.breakpoints.down(985)); const isMobile = useMediaQuery(theme.breakpoints.down(790)); return ( @@ -24,13 +25,58 @@ const SettingEmoji = memo(function ({ display: "flex", justifyContent: "space-between", flexDirection: isWrappColumn ? "column" : "none", + pb: "20px", + pl: "20px", + pt: isTablet ? "5px" : "0px", }} > + + + Настройки ответов + + { + updateQuestion(questionId, (question) => { + question.content.multi = target.checked; + }); + }} + /> + { + updateQuestion(questionId, (question) => { + question.content.own = target.checked; + }); + }} + /> + ); case "help": diff --git a/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx b/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx index d910360f..5e0535b5 100644 --- a/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx +++ b/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx @@ -4,21 +4,20 @@ import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomTextField from "@ui_kit/CustomTextField"; import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg"; import { memo } from "react"; +import type { QuizQuestionVariant } from "@model/questionTypes/variant"; type SettingOptionsAndPictProps = { questionId: string; replText: string; isRequired: boolean; + isOwn: boolean; }; -const SettingOptionsAndPict = memo(function ({ - questionId, - replText, - isRequired, -}) { +const SettingOptionsAndPict = memo(function ({ questionId, replText, isRequired, isOwn }) { const theme = useTheme(); const isWrappColumn = useMediaQuery(theme.breakpoints.down(980)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); + const isTablet = useMediaQuery(theme.breakpoints.down(985)); const isMobile = useMediaQuery(theme.breakpoints.down(680)); const setReplText = (replText: string) => { @@ -36,13 +35,14 @@ const SettingOptionsAndPict = memo(function ({ display: "flex", justifyContent: "space-between", flexDirection: isWrappColumn ? "column" : "none", + pb: "20px", + pl: "20px", + pt: isTablet ? "5px" : "0px", }} > (function ({ > Настройки ответов + { + updateQuestion(questionId, (question) => { + question.content.own = target.checked; + }); + }} + /> {!isWrappColumn && ( (function ({ (function ({ } /> {isWrappColumn && ( - <> + (function ({ maxLength={60} onChange={({ target }) => setReplText(target.value)} /> - + )} diff --git a/src/pages/Questions/OptionsAndPicture/switchOptionsAndPict.tsx b/src/pages/Questions/OptionsAndPicture/switchOptionsAndPict.tsx index 018fb0a9..2243f045 100644 --- a/src/pages/Questions/OptionsAndPicture/switchOptionsAndPict.tsx +++ b/src/pages/Questions/OptionsAndPicture/switchOptionsAndPict.tsx @@ -8,10 +8,7 @@ interface Props { question: QuizQuestionVarImg; } -export default function SwitchOptionsAndPict({ - switchState = "setting", - question, -}: Props) { +export default function SwitchOptionsAndPict({ switchState = "setting", question }: Props) { switch (switchState) { case "setting": return ( @@ -19,6 +16,7 @@ export default function SwitchOptionsAndPict({ questionId={question.id} replText={question.content.replText} isRequired={question.content.required} + isOwn={question.content.own} /> ); case "help": @@ -30,12 +28,7 @@ export default function SwitchOptionsAndPict({ /> ); case "image": - return ( - - ); + return ; default: return null; } diff --git a/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx b/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx index ee1b061a..770327db 100644 --- a/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx +++ b/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx @@ -1,10 +1,4 @@ -import { - Box, - Button, - Typography, - useMediaQuery, - useTheme, -} from "@mui/material"; +import { Box, Button, Typography, useMediaQuery, useTheme } from "@mui/material"; import { updateQuestion } from "@root/questions/actions"; import CustomCheckbox from "@ui_kit/CustomCheckbox"; import ProportionsIcon11 from "../../../assets/icons/questionsPage/ProportionsIcon11"; @@ -12,6 +6,9 @@ import ProportionsIcon12 from "../../../assets/icons/questionsPage/ProportionsIc import ProportionsIcon21 from "../../../assets/icons/questionsPage/ProportionsIcon21"; import type { QuizQuestionImages } from "../../../model/questionTypes/images"; import { memo } from "react"; +import type { QuizQuestionVariant } from "@model/questionTypes/variant"; +import FormatIcon1 from "../../../assets/icons/questionsPage/FormatIcon1"; +import FormatIcon2 from "../../../assets/icons/questionsPage/FormatIcon2"; type Proportion = "1:1" | "2:1" | "1:2"; @@ -26,14 +23,34 @@ const PROPORTIONS: ProportionItem[] = [ { value: "1:2", icon: ProportionsIcon12 }, ]; +type Format = "carousel" | "masonry"; + +type FormatItem = { + value: Format; + icon: (props: { color: string }) => JSX.Element; +}; + +const FORMATS: FormatItem[] = [ + { value: "masonry", icon: FormatIcon2 }, + { value: "carousel", icon: FormatIcon1 }, +]; + type SettingOpytionsPictProps = { questionId: string; isRequired: boolean; + isMulti: boolean; + isOwn: boolean; + proportions: Proportion; + format: Format; }; const SettingOptionsPict = memo(function ({ questionId, isRequired, + isMulti, + isOwn, + proportions, + format, }) { const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(985)); @@ -47,38 +64,167 @@ const SettingOptionsPict = memo(function ({ justifyContent: "space-between", flexDirection: isTablet ? "column" : null, marginRight: isFigmaTablte ? (isMobile ? "0" : "0px") : "30px", + pb: "20px", + pl: "20px", + pt: isTablet ? "5px" : "0px", }} > - - + - Настройки вопросов - - - updateQuestion(questionId, (question) => { - if (question.type !== "images") return; + + Пропорции + + + {PROPORTIONS.map((proportionItem, index) => ( + { + updateQuestion(questionId, (question) => { + if (question.type !== "images") return; + question.content.xy = proportionItem.value; + }); + }} + /> + ))} + + + + + Настройки ответов + + { + updateQuestion(questionId, (question) => { + question.content.multi = target.checked; + }); + }} + /> + { + updateQuestion(questionId, (question) => { + question.content.own = target.checked; + }); + }} + /> + + + + + + Формат + + + {FORMATS.map((formatItem, index) => ( + { + updateQuestion(questionId, (question) => { + if (question.type !== "images") return; + question.content.format = formatItem.value; + }); + }} + /> + ))} + + + + Настройки вопросов + + updateQuestion(questionId, (question) => { + if (question.type !== "images") return; - question.content.required = !target.checked; - }) - } - /> + question.content.required = !target.checked; + }) + } + /> + ); @@ -101,23 +247,13 @@ export function SelectIconButton({ Icon, isActive = false, onClick }: Props) {