перевод имён вопросов в амо модалке
This commit is contained in:
parent
d717322f87
commit
4fa98f644f
@ -1,5 +1,5 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
import { StepButtonsBlock } from "./StepButtonsBlock";
|
||||
import { FC } from "react";
|
||||
import { AccountResponse } from "@api/integration";
|
||||
|
||||
@ -8,7 +8,7 @@ type AmoAccountInfoProps = {
|
||||
accountInfo: AccountResponse;
|
||||
};
|
||||
|
||||
export const AmoAccountInfo: FC<AmoAccountInfoProps> = ({ handleNextStep, accountInfo }) => {
|
||||
export const AccountInfo: FC<AmoAccountInfoProps> = ({ handleNextStep, accountInfo }) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
@ -1,464 +0,0 @@
|
||||
import React, { FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Dialog, IconButton, Typography, useMediaQuery, useTheme, Box, Skeleton } from "@mui/material";
|
||||
import { useQuestions } from "@/stores/questions/hooks";
|
||||
import { redirect } from "react-router-dom";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
|
||||
import { AmoRemoveAccount } from "./AmoRemoveAccount/AmoRemoveAccount";
|
||||
import { AmoDeleteTagQuestion } from "./AmoRemoveAccount/AmoDeleteTagQuestion";
|
||||
import { AmoLogin } from "./AmoLogin/AmoLogin";
|
||||
import { Pipelines } from "./Pipelines/Pipelines";
|
||||
import { PipelineSteps } from "./PipelineSteps/PipelineSteps";
|
||||
import { DealPerformers } from "./DealPerformers/DealPerformers";
|
||||
import { AmoTags } from "./AmoTags/AmoTags";
|
||||
import { AmoQuestions } from "./AmoQuestions/AmoQuestions";
|
||||
import { AmoModalTitle } from "./AmoModalTitle/AmoModalTitle";
|
||||
import { AmoSettingsBlock } from "./SettingsBlock/AmoSettingsBlock";
|
||||
import { AmoAccountInfo } from "./AmoAccountInfo/AmoAccountInfo";
|
||||
import { useAmoIntegration } from "./useAmoIntegration";
|
||||
import { MinifiedData, QuestionKeys, TagKeys, TagQuestionHC } from "./types";
|
||||
import { Quiz } from "@/model/quiz/quiz";
|
||||
import { setIntegrationRules, updateIntegrationRules } from "@/api/integration";
|
||||
|
||||
type IntegrationsModalProps = {
|
||||
isModalOpen: boolean;
|
||||
handleCloseModal: () => void;
|
||||
companyName: string | null;
|
||||
quiz: Quiz;
|
||||
};
|
||||
|
||||
const FCTranslate = {
|
||||
"name": "имя",
|
||||
"email": "почта",
|
||||
"phone": "телефон",
|
||||
"text": "номер",
|
||||
"address": "адрес",
|
||||
}
|
||||
|
||||
export const AmoCRMModal: FC<IntegrationsModalProps> = ({ isModalOpen, handleCloseModal, companyName, quiz }) => {
|
||||
//Если нет контекста квиза, то и делать на этой страничке нечего
|
||||
if (quiz?.backendId === undefined) {
|
||||
redirect("/list");
|
||||
return null;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
|
||||
const { questions } = useQuestions();
|
||||
const minifiedQuestions = useMemo(
|
||||
() =>
|
||||
questions
|
||||
.filter((q) => q.type !== "result" && q.type !== null)
|
||||
.map(({ backendId, title }) => ({
|
||||
id: backendId.toString() as string,
|
||||
title,
|
||||
})),
|
||||
[questions]
|
||||
);
|
||||
const FieldsAllowedFC = useMemo(
|
||||
() => {
|
||||
const list: MinifiedData[] = []
|
||||
if (quiz.config.showfc) {
|
||||
const fields = quiz.config.formContact.fields
|
||||
for (let key in fields) {
|
||||
if (fields[key].used) list.push({
|
||||
id: key,
|
||||
title: FCTranslate[key],
|
||||
entity: "Contact",
|
||||
})
|
||||
}
|
||||
}
|
||||
return list;
|
||||
},
|
||||
[quiz]
|
||||
);
|
||||
|
||||
const [step, setStep] = useState<number>(0);
|
||||
const [isSettingsBlock, setIsSettingsBlock] = useState<boolean>(false);
|
||||
const [isTryRemoveAccount, setIsTryRemoveAccount] = useState<boolean>(false);
|
||||
const [openDelete, setOpenDelete] = useState<TagQuestionHC | null>(null);
|
||||
|
||||
|
||||
const {
|
||||
isLoadingPage,
|
||||
firstRules,
|
||||
accountInfo,
|
||||
arrayOfPipelines,
|
||||
arrayOfPipelinesSteps,
|
||||
arrayOfUsers,
|
||||
arrayOfTags,
|
||||
arrayOfFields,
|
||||
selectedPipeline,
|
||||
setSelectedPipeline,
|
||||
selectedCurrentFields,
|
||||
selectedPipelineStep,
|
||||
setSelectedPipelineStep,
|
||||
selectedDealUser,
|
||||
setSelectedDealPerformer,
|
||||
questionsBackend,
|
||||
selectedTags,
|
||||
setSelectedTags,
|
||||
selectedQuestions,
|
||||
setSelectedQuestions,
|
||||
setPageOfPipelines,
|
||||
setPageOfPipelinesSteps,
|
||||
setPageOfUsers,
|
||||
setPageOfTags,
|
||||
setSelectedCurrentFields,
|
||||
} = useAmoIntegration({
|
||||
quizID: quiz.backendId,
|
||||
isModalOpen,
|
||||
isTryRemoveAccount,
|
||||
questions,
|
||||
});
|
||||
|
||||
|
||||
const handleAddTagQuestion = useCallback(
|
||||
(scope: QuestionKeys | TagKeys, id: string, type: "question" | "tag") => {
|
||||
if (!scope || !id) return;
|
||||
|
||||
if (type === "tag") {
|
||||
setSelectedTags((prevState) => ({
|
||||
...prevState,
|
||||
[scope]: [...prevState[scope as TagKeys], id],
|
||||
}));
|
||||
}
|
||||
|
||||
if (type === "question") {
|
||||
const q = questions.find(e => e.backendId === Number(id))
|
||||
setSelectedQuestions((prevState) => ({
|
||||
...prevState,
|
||||
[scope]: [...prevState[scope as QuestionKeys], {
|
||||
id,
|
||||
title: q?.title || "вопрос",
|
||||
entity: scope,
|
||||
}],
|
||||
}));
|
||||
}
|
||||
},
|
||||
[setSelectedQuestions, setSelectedTags, questions]
|
||||
);
|
||||
const handleDeleteTagQuestion = useCallback(() => {
|
||||
if (openDelete === null || !openDelete.scope || !openDelete.id || !openDelete.type) return;
|
||||
if (openDelete.type === "tag") {
|
||||
let newArray = selectedTags[openDelete.scope];
|
||||
const index = newArray.indexOf(openDelete.id);
|
||||
if (index !== -1) newArray.splice(index, 1);
|
||||
|
||||
setSelectedTags((prevState) => ({
|
||||
...prevState,
|
||||
[openDelete.scope]: newArray,
|
||||
}));
|
||||
}
|
||||
|
||||
if (openDelete.type === "question") {
|
||||
let newArray = selectedQuestions
|
||||
newArray[openDelete.scope as QuestionKeys] = newArray[openDelete.scope as QuestionKeys].filter(e => e.id !== openDelete.id)
|
||||
// let index = -1
|
||||
// selectedQuestions[openDelete.scope].forEach((e, i) => {
|
||||
// if (e.subTitle === openDelete.id) index = i
|
||||
// })
|
||||
// if (index !== -1) newArray.splice(index, 1);
|
||||
// setSelectedQuestions((prevState) => ({
|
||||
// ...prevState,
|
||||
// [openDelete.scope]: newArray,
|
||||
// }));
|
||||
setSelectedQuestions(newArray);
|
||||
setSelectedCurrentFields(selectedCurrentFields.filter(e => e.id !== openDelete.id));
|
||||
|
||||
}
|
||||
setOpenDelete(null);
|
||||
}, [openDelete]);
|
||||
|
||||
const handleNextStep = () => {
|
||||
setStep((prevState) => prevState + 1);
|
||||
};
|
||||
const handlePrevStep = () => {
|
||||
setStep((prevState) => prevState - 1);
|
||||
};
|
||||
const handleSave = () => {
|
||||
if (quiz?.backendId === undefined) return;
|
||||
if (selectedPipeline === null) return enqueueSnackbar("Выберите воронку");
|
||||
if (selectedPipeline === null) return enqueueSnackbar("Выберите этап воронки");
|
||||
|
||||
const body = {
|
||||
PipelineID: Number(selectedPipeline),
|
||||
StepID: Number(selectedPipelineStep),
|
||||
PerformerID: Number(selectedDealUser),
|
||||
// FieldsRule: questionsBackend,
|
||||
TagsToAdd: selectedTags,
|
||||
};
|
||||
|
||||
const FieldsRule = {
|
||||
Company: { QuestionID: {} },
|
||||
Lead: { QuestionID: {} },
|
||||
Customer: { QuestionID: {} },
|
||||
Contact: {
|
||||
QuestionID: {},
|
||||
ContactRuleMap: {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
for (let key in FieldsRule) {
|
||||
selectedQuestions[key as QuestionKeys].forEach((data) => {
|
||||
FieldsRule[key as QuestionKeys].QuestionID[data.id] = 0;
|
||||
});
|
||||
}
|
||||
|
||||
selectedCurrentFields.forEach((data) => {
|
||||
if (data.entity === "Contact") {
|
||||
FieldsRule.Contact.ContactRuleMap[data.id] = Number(data.amoId)
|
||||
} else {
|
||||
FieldsRule[data.entity].QuestionID[data.id] = Number(data.amoId) || 0
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
for (let key in body.TagsToAdd) {
|
||||
body.TagsToAdd[key as TagKeys] = body.TagsToAdd[key as TagKeys].map((id) => Number(id));
|
||||
}
|
||||
body.FieldsRule = FieldsRule;
|
||||
|
||||
if (firstRules) {
|
||||
setIntegrationRules(quiz.backendId.toString(), body);
|
||||
} else {
|
||||
updateIntegrationRules(quiz.backendId.toString(), body);
|
||||
}
|
||||
|
||||
handleCloseModal();
|
||||
setStep(1);
|
||||
};
|
||||
const steps = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: accountInfo ? "Информация об аккаунте" : "Авторизация в аккаунте",
|
||||
isSettingsAvailable: false,
|
||||
component: accountInfo ? (
|
||||
<AmoAccountInfo
|
||||
handleNextStep={handleNextStep}
|
||||
accountInfo={accountInfo}
|
||||
/>
|
||||
) : (
|
||||
<AmoLogin handleNextStep={handleNextStep} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Выбор воронки",
|
||||
desc: "На этом этапе вы можете выбрать нужную воронку и ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<Pipelines
|
||||
users={arrayOfUsers}
|
||||
pipelines={arrayOfPipelines}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
selectedDealUser={selectedDealUser}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
selectedPipeline={selectedPipeline}
|
||||
setSelectedPipeline={setSelectedPipeline}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Выбор этапа воронки",
|
||||
desc: "На этом этапе вы можете выбрать нужный этап и ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<PipelineSteps
|
||||
users={arrayOfUsers}
|
||||
selectedDealUser={selectedDealUser}
|
||||
selectedStep={selectedPipelineStep}
|
||||
steps={arrayOfPipelinesSteps}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
setSelectedStep={setSelectedPipelineStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Сделка",
|
||||
desc: "На этом этапе вы можете выбрать ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<DealPerformers
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
users={arrayOfUsers}
|
||||
selectedDealUser={selectedDealUser}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Добавление тегов",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<AmoTags
|
||||
tagsItems={arrayOfTags}
|
||||
selectedTags={selectedTags}
|
||||
openDelete={setOpenDelete}
|
||||
handleScroll={() => { }}
|
||||
handleAddTag={handleAddTagQuestion}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Соотнесение вопросов и сущностей",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<AmoQuestions
|
||||
setSelectedCurrentFields={setSelectedCurrentFields}
|
||||
fieldsItems={arrayOfFields}
|
||||
selectedCurrentFields={selectedCurrentFields}
|
||||
questionsItems={minifiedQuestions}
|
||||
selectedQuestions={selectedQuestions}
|
||||
openDelete={setOpenDelete}
|
||||
handleAddQuestion={handleAddTagQuestion}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleSave}
|
||||
FieldsAllowedFC={FieldsAllowedFC}
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
[
|
||||
arrayOfPipelines,
|
||||
arrayOfPipelinesSteps,
|
||||
arrayOfUsers,
|
||||
arrayOfTags,
|
||||
arrayOfFields,
|
||||
selectedPipeline,
|
||||
selectedPipelineStep,
|
||||
selectedDealUser,
|
||||
selectedQuestions,
|
||||
selectedTags,
|
||||
arrayOfPipelines,
|
||||
arrayOfPipelinesSteps,
|
||||
arrayOfUsers,
|
||||
minifiedQuestions,
|
||||
selectedCurrentFields,
|
||||
]
|
||||
);
|
||||
|
||||
const stepTitles = steps.map((step) => step.title);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
fullWidth
|
||||
// fullScreen={isMobile}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
maxWidth: isTablet ? "100%" : "920px",
|
||||
maxHeight: isTablet ? "100%" : "680px",
|
||||
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,
|
||||
}}
|
||||
>
|
||||
Интеграция с {companyName ? companyName : "партнером"}
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={handleCloseModal}
|
||||
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",
|
||||
width: isTablet ? "100%" : "920px",
|
||||
height: "600px",
|
||||
padding: "15px 20px 15px",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
{isLoadingPage ?
|
||||
<Skeleton
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
transform: "none",
|
||||
}}
|
||||
/> :
|
||||
<>
|
||||
<AmoModalTitle
|
||||
step={step}
|
||||
steps={steps}
|
||||
isSettingsBlock={isSettingsBlock}
|
||||
setIsSettingsBlock={setIsSettingsBlock}
|
||||
setStep={setStep}
|
||||
startRemoveAccount={() => setIsTryRemoveAccount(true)}
|
||||
/>
|
||||
{openDelete !== null ? (
|
||||
<AmoDeleteTagQuestion
|
||||
close={() => setOpenDelete(null)}
|
||||
deleteItem={handleDeleteTagQuestion}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{isTryRemoveAccount && <AmoRemoveAccount handleCloseModal={handleCloseModal} stopThisPage={() => setIsTryRemoveAccount(false)} />}
|
||||
{isSettingsBlock && (
|
||||
<Box sx={{ flexGrow: 1, width: "100%" }}>
|
||||
<AmoSettingsBlock
|
||||
stepTitles={stepTitles}
|
||||
setIsSettingsBlock={setIsSettingsBlock}
|
||||
setStep={setStep}
|
||||
selectedDealUser={arrayOfUsers.find((u) => u.id === selectedDealUser)?.title || "не указан"}
|
||||
selectedFunnel={arrayOfPipelines.find((p) => p.id === selectedPipeline)?.title || "нет данных"}
|
||||
selectedStage={
|
||||
arrayOfPipelinesSteps.find((s) => s.id === selectedPipelineStep)?.title || "нет данных"
|
||||
}
|
||||
selectedQuestions={selectedQuestions}
|
||||
selectedTags={selectedTags}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{!isSettingsBlock && !isTryRemoveAccount && (
|
||||
<Box sx={{ flexGrow: 1, width: "100%" }}>{steps[step].component}</Box>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export const diffArr = (arr_A: MinifiedData[], arr_B: MinifiedData[]) => {
|
||||
return arr_A.filter(person_A => !arr_B.some(person_B => person_A.id === person_B.id));
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { AmoButton } from "../../../../../components/AmoButton/AmoButton";
|
||||
import { AmoButton } from "../../../../components/AmoButton/AmoButton";
|
||||
import { connectAmo } from "@api/integration";
|
||||
|
||||
type IntegrationStep1Props = {
|
||||
@ -1,8 +1,8 @@
|
||||
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../../components/CustomSelect/CustomSelect";
|
||||
import { MinifiedData } from "../types";
|
||||
import { StepButtonsBlock } from "./StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||
import { MinifiedData } from "./types";
|
||||
|
||||
type Props = {
|
||||
users: MinifiedData[];
|
||||
@ -6,7 +6,7 @@ interface Props {
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
export const AmoDeleteTagQuestion: FC<Props> = ({ close, deleteItem }) => {
|
||||
export const DeleteTagQuestion: FC<Props> = ({ close, deleteItem }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
@ -13,7 +13,7 @@ type AmoModalTitleProps = {
|
||||
startRemoveAccount: () => void;
|
||||
};
|
||||
|
||||
export const AmoModalTitle: FC<AmoModalTitleProps> = ({
|
||||
export const ModalTitle: FC<AmoModalTitleProps> = ({
|
||||
step,
|
||||
steps,
|
||||
setIsSettingsBlock,
|
||||
@ -1,9 +1,9 @@
|
||||
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../../components/CustomSelect/CustomSelect";
|
||||
import { CustomRadioGroup } from "../../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||
import { MinifiedData } from "../types";
|
||||
import { StepButtonsBlock } from "./StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||
import { MinifiedData } from "./types";
|
||||
|
||||
type Props = {
|
||||
users: MinifiedData[];
|
||||
@ -1,9 +1,9 @@
|
||||
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../../components/CustomSelect/CustomSelect";
|
||||
import { CustomRadioGroup } from "../../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||
import { MinifiedData } from "../types";
|
||||
import { StepButtonsBlock } from "./StepButtonsBlock";
|
||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||
import { MinifiedData } from "./types";
|
||||
|
||||
type Props = {
|
||||
pipelines: MinifiedData[];
|
||||
@ -4,7 +4,7 @@ import { ItemDetailsView } from "./ItemDetailsView/ItemDetailsView";
|
||||
import { Box } from "@mui/material";
|
||||
import { MinifiedData, QuestionKeys, SelectedQuestions, TagKeys, TagQuestionHC } from "../types";
|
||||
import { EntitiesQuestions } from "./EntitiesQuestions";
|
||||
import { diffArr } from "../AmoCRMModal";
|
||||
import { diffArr } from "..";
|
||||
import { DataConstrictor } from "../Components/DataConstrictor";
|
||||
|
||||
type Props = {
|
||||
@ -2,7 +2,7 @@ import { CustomRadioGroup } from "@/components/CustomRadioGroup/CustomRadioGroup
|
||||
import {Box, Typography, useMediaQuery, useTheme} from "@mui/material"
|
||||
import { MinifiedData } from "../types";
|
||||
import {CustomSelect} from "@/components/CustomSelect/CustomSelect";
|
||||
import {CurrentFieldSelect} from "@/pages/IntegrationsPage/IntegrationsModal/Amo/AmoQuestions/CurrentFieldSelectMobile";
|
||||
import {CurrentFieldSelect} from "@/pages/IntegrationsPage/IntegrationsModal/Amo/Questions/CurrentFieldSelectMobile";
|
||||
|
||||
interface Props {
|
||||
items: MinifiedData[];
|
||||
@ -1,11 +1,11 @@
|
||||
import {Box, Button, useMediaQuery, useTheme} from "@mui/material"
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock"
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock"
|
||||
import { FC, useState } from "react";
|
||||
import { MinifiedData, TagKeys } from "../types";
|
||||
import { CurrentFields } from "./CurrentFields";
|
||||
import { NewFields } from "./NewFields";
|
||||
import { QuestionPair } from "./AmoQuestions";
|
||||
import { diffArr } from "../AmoCRMModal";
|
||||
import { diffArr } from "..";
|
||||
|
||||
type ItemsSelectionViewProps = {
|
||||
items: MinifiedData[] | [];
|
||||
@ -1,6 +1,6 @@
|
||||
import { Box, useTheme } from "@mui/material";
|
||||
import { ItemForQuestions } from "../ItemForQuestions";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock";
|
||||
import { FC } from "react";
|
||||
import { MinifiedData, QuestionKeys, SelectedQuestions } from "../../types";
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Box } from "@mui/material";
|
||||
import { CustomRadioGroup } from "../../../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock";
|
||||
import { FC } from "react";
|
||||
import { MinifiedData, TagKeys } from "../../types";
|
||||
|
||||
@ -10,7 +10,7 @@ interface Props {
|
||||
|
||||
}
|
||||
|
||||
export const AmoRemoveAccount: FC<Props> = ({
|
||||
export const RemoveAccount: FC<Props> = ({
|
||||
stopThisPage,
|
||||
handleCloseModal,
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
import { FC } from "react";
|
||||
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
import { SettingItem } from "./SettingItem/SettingItem";
|
||||
import { SelectedQuestions, SelectedTags } from "../types";
|
||||
|
||||
type AmoSettingsBlockProps = {
|
||||
stepTitles: string[];
|
||||
setStep: (value: number) => void;
|
||||
setIsSettingsBlock: (value: boolean) => void;
|
||||
selectedFunnel: string | null;
|
||||
selectedStage: string | null;
|
||||
selectedDealUser: string | null;
|
||||
selectedQuestions: SelectedQuestions;
|
||||
selectedTags: SelectedTags;
|
||||
};
|
||||
|
||||
export const AmoSettingsBlock: FC<AmoSettingsBlockProps> = ({
|
||||
stepTitles,
|
||||
setStep,
|
||||
setIsSettingsBlock,
|
||||
selectedFunnel,
|
||||
selectedDealUser,
|
||||
selectedStage,
|
||||
selectedQuestions,
|
||||
selectedTags,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "10px",
|
||||
width: "100%",
|
||||
height: "443px",
|
||||
borderRadius: "10px",
|
||||
padding: " 0 20px",
|
||||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||||
overflowY: "auto",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
{stepTitles &&
|
||||
stepTitles.map((title, index) => (
|
||||
<SettingItem
|
||||
step={index}
|
||||
title={title}
|
||||
setIsSettingsBlock={setIsSettingsBlock}
|
||||
setStep={setStep}
|
||||
selectedDealUser={selectedDealUser}
|
||||
selectedFunnel={selectedFunnel}
|
||||
selectedStage={selectedStage}
|
||||
selectedQuestions={selectedQuestions}
|
||||
selectedTags={selectedTags}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "20px",
|
||||
alignSelf: "end",
|
||||
}}
|
||||
>
|
||||
<StepButtonsBlock
|
||||
onSmallBtnClick={() => setIsSettingsBlock(false)}
|
||||
isLargeBtnMissing={true}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,83 @@
|
||||
import { FC } from "react";
|
||||
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock";
|
||||
import { SettingItem } from "./SettingItem/SettingItem";
|
||||
import { SelectedQuestions, SelectedTags } from "../types";
|
||||
|
||||
type AmoSettingsBlockProps = {
|
||||
stepTitles: string[];
|
||||
setStep: (value: number) => void;
|
||||
setIsSettingsBlock: (value: boolean) => void;
|
||||
selectedFunnel: string | null;
|
||||
selectedStage: string | null;
|
||||
selectedDealUser: string | null;
|
||||
selectedQuestions: SelectedQuestions;
|
||||
selectedTags: SelectedTags;
|
||||
};
|
||||
|
||||
export const SettingsBlock: FC<AmoSettingsBlockProps> = ({
|
||||
stepTitles,
|
||||
setStep,
|
||||
setIsSettingsBlock,
|
||||
selectedFunnel,
|
||||
selectedDealUser,
|
||||
selectedStage,
|
||||
selectedQuestions,
|
||||
selectedTags,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
return (
|
||||
<Box sx={{ flexGrow: 1, width: "100%" }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "10px",
|
||||
width: "100%",
|
||||
height: "443px",
|
||||
borderRadius: "10px",
|
||||
padding: " 0 20px",
|
||||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||||
overflowY: "auto",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
{stepTitles &&
|
||||
stepTitles.map((title, index) => (
|
||||
<SettingItem
|
||||
step={index}
|
||||
title={title}
|
||||
setIsSettingsBlock={setIsSettingsBlock}
|
||||
setStep={setStep}
|
||||
selectedDealUser={selectedDealUser}
|
||||
selectedFunnel={selectedFunnel}
|
||||
selectedStage={selectedStage}
|
||||
selectedQuestions={selectedQuestions}
|
||||
selectedTags={selectedTags}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: "20px",
|
||||
alignSelf: "end",
|
||||
}}
|
||||
>
|
||||
<StepButtonsBlock
|
||||
onSmallBtnClick={() => setIsSettingsBlock(false)}
|
||||
isLargeBtnMissing={true}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
383
src/pages/IntegrationsPage/IntegrationsModal/Amo/SwitchPages.tsx
Normal file
383
src/pages/IntegrationsPage/IntegrationsModal/Amo/SwitchPages.tsx
Normal file
@ -0,0 +1,383 @@
|
||||
import { useMemo, useState } from "react"
|
||||
import { Dialog, IconButton, Typography, useMediaQuery, useTheme, Box, Skeleton } from "@mui/material";
|
||||
import { useQuestions } from "@/stores/questions/hooks";
|
||||
import { redirect } from "react-router-dom";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
|
||||
import { RemoveAccount } from "./RemoveAccount";
|
||||
import { DeleteTagQuestion } from "./DeleteTagQuestion";
|
||||
import { AmoLogin } from "./AmoLogin";
|
||||
import { Pipelines } from "./Pipelines";
|
||||
import { PipelineSteps } from "./PipelineSteps";
|
||||
import { DealPerformers } from "./DealPerformers";
|
||||
import { AmoTags } from "./Tags/AmoTags";
|
||||
import { AmoQuestions } from "./Questions/AmoQuestions";
|
||||
import { ModalTitle } from "./ModalTitle";
|
||||
import { SettingsBlock } from "./SettingsBlock/SettingsBlock";
|
||||
import { AccountInfo } from "./AccountInfo";
|
||||
import { useAmoIntegration } from "./useAmoIntegration";
|
||||
import { MinifiedData, QuestionKeys, TagKeys, TagQuestionHC } from "./types";
|
||||
import { Quiz } from "@/model/quiz/quiz";
|
||||
import { AccountResponse, setIntegrationRules, updateIntegrationRules } from "@/api/integration";
|
||||
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||||
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
||||
|
||||
const FCTranslate = {
|
||||
"name": "имя",
|
||||
"email": "почта",
|
||||
"phone": "телефон",
|
||||
"text": "номер",
|
||||
"address": "адрес",
|
||||
}
|
||||
|
||||
interface Props {
|
||||
quiz: Quiz;
|
||||
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[];
|
||||
firstRules: boolean;
|
||||
accountInfo: AccountResponse | null;
|
||||
arrayOfPipelines: MinifiedData[];
|
||||
arrayOfPipelinesSteps: MinifiedData[];
|
||||
arrayOfUsers: MinifiedData[];
|
||||
arrayOfTags: MinifiedData[];
|
||||
arrayOfFields: MinifiedData[];
|
||||
selectedPipeline: string | null;
|
||||
selectedCurrentFields: MinifiedData[];
|
||||
selectedPipelineStep: string | null;
|
||||
selectedDealUser: string | null;
|
||||
setSelectedPipeline:any;
|
||||
setSelectedPipelineStep:any;
|
||||
setSelectedDealPerformer:any;
|
||||
selectedTags:any;
|
||||
setSelectedTags:any;
|
||||
selectedQuestions:any;
|
||||
setSelectedQuestions:any;
|
||||
setPageOfPipelines:any;
|
||||
setPageOfPipelinesSteps:any;
|
||||
setPageOfUsers:any;
|
||||
setPageOfTags:any;
|
||||
setSelectedCurrentFields:any;
|
||||
handleCloseModal:any;
|
||||
}
|
||||
|
||||
export const SwitchPages = ({
|
||||
quiz,
|
||||
questions,
|
||||
firstRules,
|
||||
accountInfo,
|
||||
arrayOfPipelines,
|
||||
arrayOfPipelinesSteps,
|
||||
arrayOfUsers,
|
||||
arrayOfTags,
|
||||
arrayOfFields,
|
||||
selectedPipeline,
|
||||
setSelectedPipeline,
|
||||
selectedCurrentFields,
|
||||
selectedPipelineStep,
|
||||
setSelectedPipelineStep,
|
||||
selectedDealUser,
|
||||
setSelectedDealPerformer,
|
||||
selectedTags,
|
||||
setSelectedTags,
|
||||
selectedQuestions,
|
||||
setSelectedQuestions,
|
||||
setPageOfPipelines,
|
||||
setPageOfPipelinesSteps,
|
||||
setPageOfUsers,
|
||||
setPageOfTags,
|
||||
setSelectedCurrentFields,
|
||||
handleCloseModal,
|
||||
|
||||
}: Props) => {
|
||||
const [step, setStep] = useState(0)
|
||||
const [specialPage, setSpecialPage] = useState<"deleteCell" | "removeAccount" | "settingsBlock" | "accountInfo" | "amoLogin" | "">("")
|
||||
const [openDelete, setOpenDelete] = useState<TagQuestionHC | null>(null);
|
||||
|
||||
|
||||
const minifiedQuestions = useMemo(
|
||||
() =>
|
||||
questions
|
||||
.filter((q) => q.type !== "result" && q.type !== null)
|
||||
.map(({ backendId, title }) => ({
|
||||
id: backendId.toString() as string,
|
||||
title,
|
||||
})),
|
||||
[questions]
|
||||
);
|
||||
const FieldsAllowedFC = useMemo(
|
||||
() => {
|
||||
const list: MinifiedData[] = []
|
||||
if (quiz.config.showfc) {
|
||||
const fields = quiz.config.formContact.fields
|
||||
for (let key in fields) {
|
||||
if (fields[key].used) list.push({
|
||||
id: key,
|
||||
title: FCTranslate[key],
|
||||
entity: "Contact",
|
||||
})
|
||||
}
|
||||
}
|
||||
return list;
|
||||
},
|
||||
[quiz]
|
||||
);
|
||||
const handleAddTagQuestion = (scope: QuestionKeys | TagKeys, id: string, type: "question" | "tag") => {
|
||||
if (!scope || !id) return;
|
||||
|
||||
if (type === "tag") {
|
||||
setSelectedTags((prevState) => ({
|
||||
...prevState,
|
||||
[scope]: [...prevState[scope as TagKeys], id],
|
||||
}));
|
||||
}
|
||||
|
||||
if (type === "question") {
|
||||
const q = questions.find(e => e.backendId === Number(id))
|
||||
setSelectedQuestions((prevState) => ({
|
||||
...prevState,
|
||||
[scope]: [...prevState[scope as QuestionKeys], {
|
||||
id,
|
||||
title: q?.title || "вопрос",
|
||||
entity: scope,
|
||||
}],
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const handleDeleteTagQuestion = () => {
|
||||
if (openDelete === null || !openDelete.scope || !openDelete.id || !openDelete.type) return;
|
||||
if (openDelete.type === "tag") {
|
||||
let newArray = selectedTags[openDelete.scope];
|
||||
const index = newArray.indexOf(openDelete.id);
|
||||
if (index !== -1) newArray.splice(index, 1);
|
||||
|
||||
setSelectedTags((prevState) => ({
|
||||
...prevState,
|
||||
[openDelete.scope]: newArray,
|
||||
}));
|
||||
}
|
||||
|
||||
if (openDelete.type === "question") {
|
||||
let newArray = selectedQuestions
|
||||
newArray[openDelete.scope as QuestionKeys] = newArray[openDelete.scope as QuestionKeys].filter(e => e.id !== openDelete.id)
|
||||
// let index = -1
|
||||
// selectedQuestions[openDelete.scope].forEach((e, i) => {
|
||||
// if (e.subTitle === openDelete.id) index = i
|
||||
// })
|
||||
// if (index !== -1) newArray.splice(index, 1);
|
||||
// setSelectedQuestions((prevState) => ({
|
||||
// ...prevState,
|
||||
// [openDelete.scope]: newArray,
|
||||
// }));
|
||||
setSelectedQuestions(newArray);
|
||||
setSelectedCurrentFields(selectedCurrentFields.filter(e => e.id !== openDelete.id));
|
||||
|
||||
}
|
||||
setOpenDelete(null);
|
||||
}
|
||||
|
||||
const handleNextStep = () => {
|
||||
setStep((prevState) => prevState + 1);
|
||||
};
|
||||
const handlePrevStep = () => {
|
||||
setStep((prevState) => prevState - 1);
|
||||
};
|
||||
const handleSave = () => {
|
||||
if (quiz?.backendId === undefined) return;
|
||||
if (selectedPipeline === null) return enqueueSnackbar("Выберите воронку");
|
||||
if (selectedPipeline === null) return enqueueSnackbar("Выберите этап воронки");
|
||||
|
||||
const body = {
|
||||
PipelineID: Number(selectedPipeline),
|
||||
StepID: Number(selectedPipelineStep),
|
||||
PerformerID: Number(selectedDealUser),
|
||||
// FieldsRule: questionsBackend,
|
||||
TagsToAdd: selectedTags,
|
||||
};
|
||||
|
||||
const FieldsRule = {
|
||||
Company: { QuestionID: {} },
|
||||
Lead: { QuestionID: {} },
|
||||
Customer: { QuestionID: {} },
|
||||
Contact: {
|
||||
QuestionID: {},
|
||||
ContactRuleMap: {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
for (let key in FieldsRule) {
|
||||
selectedQuestions[key as QuestionKeys].forEach((data) => {
|
||||
FieldsRule[key as QuestionKeys].QuestionID[data.id] = 0;
|
||||
});
|
||||
}
|
||||
|
||||
selectedCurrentFields.forEach((data) => {
|
||||
if (data.entity === "Contact") {
|
||||
FieldsRule.Contact.ContactRuleMap[data.id] = Number(data.amoId)
|
||||
} else {
|
||||
FieldsRule[data.entity].QuestionID[data.id] = Number(data.amoId) || 0
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
for (let key in body.TagsToAdd) {
|
||||
body.TagsToAdd[key as TagKeys] = body.TagsToAdd[key as TagKeys].map((id) => Number(id));
|
||||
}
|
||||
body.FieldsRule = FieldsRule;
|
||||
|
||||
// if (firstRules) {
|
||||
// setIntegrationRules(quiz.backendId.toString(), body);
|
||||
// } else {
|
||||
// updateIntegrationRules(quiz.backendId.toString(), body);
|
||||
// }
|
||||
|
||||
handleCloseModal();
|
||||
};
|
||||
|
||||
|
||||
const closeSpecialPage = () => setSpecialPage("")
|
||||
|
||||
const steps = [
|
||||
{
|
||||
title: "Выбор воронки",
|
||||
desc: "На этом этапе вы можете выбрать нужную воронку и ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<Pipelines
|
||||
users={arrayOfUsers}
|
||||
pipelines={arrayOfPipelines}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
selectedDealUser={selectedDealUser}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
selectedPipeline={selectedPipeline}
|
||||
setSelectedPipeline={setSelectedPipeline}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Выбор этапа воронки",
|
||||
desc: "На этом этапе вы можете выбрать нужный этап и ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<PipelineSteps
|
||||
users={arrayOfUsers}
|
||||
selectedDealUser={selectedDealUser}
|
||||
selectedStep={selectedPipelineStep}
|
||||
steps={arrayOfPipelinesSteps}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
setSelectedStep={setSelectedPipelineStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Сделка",
|
||||
desc: "На этом этапе вы можете выбрать ответственного за сделку",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<DealPerformers
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
users={arrayOfUsers}
|
||||
selectedDealUser={selectedDealUser}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Добавление тегов",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<AmoTags
|
||||
tagsItems={arrayOfTags}
|
||||
selectedTags={selectedTags}
|
||||
openDelete={setOpenDelete}
|
||||
handleScroll={() => { }}
|
||||
handleAddTag={handleAddTagQuestion}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Соотнесение вопросов и сущностей",
|
||||
isSettingsAvailable: true,
|
||||
component: (
|
||||
<AmoQuestions
|
||||
setSelectedCurrentFields={setSelectedCurrentFields}
|
||||
fieldsItems={arrayOfFields}
|
||||
selectedCurrentFields={selectedCurrentFields}
|
||||
questionsItems={minifiedQuestions}
|
||||
selectedQuestions={selectedQuestions}
|
||||
openDelete={setOpenDelete}
|
||||
handleAddQuestion={handleAddTagQuestion}
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleSave}
|
||||
FieldsAllowedFC={FieldsAllowedFC}
|
||||
/>
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
const stepTitles = steps.map((step) => step.title);
|
||||
|
||||
switch (specialPage) {
|
||||
case "deleteCell":
|
||||
return <DeleteTagQuestion
|
||||
close={closeSpecialPage}
|
||||
deleteItem={handleDeleteTagQuestion}
|
||||
/>
|
||||
case "removeAccount":
|
||||
return <RemoveAccount
|
||||
handleCloseModal={closeSpecialPage}
|
||||
stopThisPage={closeSpecialPage}
|
||||
/>
|
||||
case "settingsBlock":
|
||||
return <SettingsBlock
|
||||
stepTitles={stepTitles}
|
||||
setIsSettingsBlock={setIsSettingsBlock}
|
||||
setStep={setStep}
|
||||
selectedDealUser={arrayOfUsers.find((u) => u.id === selectedDealUser)?.title || "не указан"}
|
||||
selectedFunnel={arrayOfPipelines.find((p) => p.id === selectedPipeline)?.title || "нет данных"}
|
||||
selectedStage={
|
||||
arrayOfPipelinesSteps.find((s) => s.id === selectedPipelineStep)?.title || "нет данных"
|
||||
}
|
||||
selectedQuestions={selectedQuestions}
|
||||
selectedTags={selectedTags}
|
||||
/>
|
||||
case "amoLogin": return <AmoLogin handleNextStep={handleNextStep} />
|
||||
case "accountInfo": return <AmoAccountInfo
|
||||
handleNextStep={handleNextStep}
|
||||
accountInfo={accountInfo}
|
||||
/>
|
||||
|
||||
|
||||
default: <Box sx={{ flexGrow: 1, width: "100%" }}>{steps[step].component}</Box>
|
||||
}
|
||||
}
|
||||
|
||||
// const S = <ModalTitle
|
||||
// step={1}
|
||||
// steps={2}
|
||||
// isSettingsBlock={true}
|
||||
// setIsSettingsBlock={setIsSettingsBlock}
|
||||
// setStep={setStep}
|
||||
// startRemoveAccount={() => setSpecialPage("removeAccount")}
|
||||
// />
|
||||
|
||||
|
||||
// title: accountInfo ? "Информация об аккаунте" : "Авторизация в аккаунте",
|
||||
// isSettingsAvailable: false,
|
||||
// component: accountInfo ? (
|
||||
// <AmoAccountInfo
|
||||
// handleNextStep={handleNextStep}
|
||||
// accountInfo={accountInfo}
|
||||
// />
|
||||
// ) : (
|
||||
// <AmoLogin handleNextStep={handleNextStep} />
|
||||
// ),
|
||||
// },
|
||||
@ -1,6 +1,6 @@
|
||||
import { FC, useState } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import { ItemsSelectionView } from "../AmoQuestions/ItemsSelectionView/ItemsSelectionView";
|
||||
import { ItemsSelectionView } from "../Questions/ItemsSelectionView/ItemsSelectionView";
|
||||
import { TagsDetailsView } from "./TagsDetailsView/TagsDetailsView";
|
||||
import { MinifiedData, QuestionKeys, SelectedTags, TagKeys, TagQuestionHC } from "../types";
|
||||
import { DataConstrictor } from "../Components/DataConstrictor";
|
||||
@ -1,7 +1,7 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock/StepButtonsBlock";
|
||||
import { StepButtonsBlock } from "../../StepButtonsBlock";
|
||||
import { FC } from "react";
|
||||
import { Item } from "../../AmoQuestions/Item/Item";
|
||||
import { Item } from "../../Questions/Item/Item";
|
||||
import { MinifiedData, SelectedTags, TagKeys } from "../../types";
|
||||
|
||||
type TagsDetailsViewProps = {
|
||||
166
src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx
Normal file
166
src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx
Normal file
@ -0,0 +1,166 @@
|
||||
import { FC, useState } from "react";
|
||||
import { Dialog, IconButton, Typography, useMediaQuery, useTheme, Box, Skeleton } from "@mui/material";
|
||||
import { useQuestions } from "@/stores/questions/hooks";
|
||||
import { redirect, useNavigate } from "react-router-dom";
|
||||
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
|
||||
import { useAmoIntegration } from "./useAmoIntegration";
|
||||
import { MinifiedData } from "./types";
|
||||
import { Quiz } from "@/model/quiz/quiz";
|
||||
import { SwitchPages } from "./SwitchPages";
|
||||
|
||||
type IntegrationsModalProps = {
|
||||
isModalOpen: boolean;
|
||||
handleCloseModal: () => void;
|
||||
companyName: string | null;
|
||||
quiz: Quiz;
|
||||
};
|
||||
|
||||
export const AmoCRMModal: FC<IntegrationsModalProps> = ({ isModalOpen, handleCloseModal, companyName, quiz }) => {
|
||||
//Если нет контекста квиза, то и делать на этой страничке нечего
|
||||
if (quiz.backendId === undefined) {
|
||||
redirect("/list");
|
||||
return null;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
|
||||
const { questions } = useQuestions();
|
||||
|
||||
const [isTryRemoveAccount, setIsTryRemoveAccount] = useState<boolean>(false);
|
||||
|
||||
const {
|
||||
isLoadingPage,
|
||||
firstRules,
|
||||
accountInfo,
|
||||
arrayOfPipelines,
|
||||
arrayOfPipelinesSteps,
|
||||
arrayOfUsers,
|
||||
arrayOfTags,
|
||||
arrayOfFields,
|
||||
selectedPipeline,
|
||||
setSelectedPipeline,
|
||||
selectedCurrentFields,
|
||||
selectedPipelineStep,
|
||||
setSelectedPipelineStep,
|
||||
selectedDealUser,
|
||||
setSelectedDealPerformer,
|
||||
questionsBackend,
|
||||
selectedTags,
|
||||
setSelectedTags,
|
||||
selectedQuestions,
|
||||
setSelectedQuestions,
|
||||
setPageOfPipelines,
|
||||
setPageOfPipelinesSteps,
|
||||
setPageOfUsers,
|
||||
setPageOfTags,
|
||||
setSelectedCurrentFields,
|
||||
} = useAmoIntegration({
|
||||
quizID: quiz.backendId,
|
||||
isModalOpen,
|
||||
isTryRemoveAccount,
|
||||
questions,
|
||||
});
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
fullWidth
|
||||
// fullScreen={isMobile}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
maxWidth: isTablet ? "100%" : "920px",
|
||||
maxHeight: isTablet ? "100%" : "680px",
|
||||
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,
|
||||
}}
|
||||
>
|
||||
Интеграция с {companyName ? companyName : "партнером"}
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={handleCloseModal}
|
||||
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",
|
||||
width: isTablet ? "100%" : "920px",
|
||||
height: "600px",
|
||||
padding: "15px 20px 15px",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
{isLoadingPage ?
|
||||
<Skeleton
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
transform: "none",
|
||||
}}
|
||||
/> :
|
||||
<SwitchPages
|
||||
quiz={quiz}
|
||||
questions={questions}
|
||||
firstRules={firstRules}
|
||||
accountInfo={accountInfo}
|
||||
arrayOfPipelines={arrayOfPipelines}
|
||||
arrayOfPipelinesSteps={arrayOfPipelinesSteps}
|
||||
arrayOfUsers={arrayOfUsers}
|
||||
arrayOfTags={arrayOfTags}
|
||||
arrayOfFields={arrayOfFields}
|
||||
selectedPipeline={selectedPipeline}
|
||||
setSelectedPipeline={setSelectedPipeline}
|
||||
selectedCurrentFields={selectedCurrentFields}
|
||||
selectedPipelineStep={selectedPipelineStep}
|
||||
setSelectedPipelineStep={setSelectedPipelineStep}
|
||||
selectedDealUser={selectedDealUser}
|
||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||
selectedTags={selectedTags}
|
||||
setSelectedTags={setSelectedTags}
|
||||
selectedQuestions={selectedQuestions}
|
||||
setSelectedQuestions={setSelectedQuestions}
|
||||
setPageOfPipelines={setPageOfPipelines}
|
||||
setPageOfPipelinesSteps={setPageOfPipelinesSteps}
|
||||
setPageOfUsers={setPageOfUsers}
|
||||
setPageOfTags={setPageOfTags}
|
||||
setSelectedCurrentFields={setSelectedCurrentFields}
|
||||
handleCloseModal={handleCloseModal}
|
||||
/>
|
||||
}
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export const diffArr = (arr_A: MinifiedData[], arr_B: MinifiedData[]) => {
|
||||
return arr_A.filter(person_A => !arr_B.some(person_B => person_A.id === person_B.id));
|
||||
}
|
||||
@ -13,6 +13,7 @@ import {
|
||||
getFields,
|
||||
} from "@/api/integration";
|
||||
import { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||||
import { UntypedQuizQuestion } from "@/model/questionTypes/shared";
|
||||
|
||||
const SIZE = 275;
|
||||
|
||||
@ -20,7 +21,7 @@ interface Props {
|
||||
isModalOpen: boolean;
|
||||
isTryRemoveAccount: boolean;
|
||||
quizID: number;
|
||||
questions: AnyTypedQuizQuestion
|
||||
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[]
|
||||
}
|
||||
|
||||
const FCTranslate = {
|
||||
@ -151,6 +152,22 @@ export const useAmoIntegration = ({ isModalOpen, isTryRemoveAccount, quizID, que
|
||||
|
||||
}, [isModalOpen, isTryRemoveAccount]);
|
||||
|
||||
useEffect(() => {
|
||||
const transletedQuestions = {}
|
||||
|
||||
Object.keys(selectedQuestions).forEach((column) => {
|
||||
selectedQuestions[column].forEach((minifiedData) => {
|
||||
const q = questions.find(e => e.backendId === Number(minifiedData.id)) || {}
|
||||
transletedQuestions[column] = {
|
||||
...minifiedData,
|
||||
title: q.title || transletedQuestions[column].title
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
setSelectedQuestions(transletedQuestions)
|
||||
}, [questions])
|
||||
|
||||
useEffect(() => {
|
||||
getPipelines({
|
||||
page: pageOfPipelines,
|
||||
|
||||
@ -16,7 +16,7 @@ const AnalyticsModal = lazy(() =>
|
||||
);
|
||||
|
||||
const AmoCRMModal = lazy(() =>
|
||||
import("../IntegrationsModal/Amo/AmoCRMModal").then((module) => ({
|
||||
import("../IntegrationsModal/Amo").then((module) => ({
|
||||
default: module.AmoCRMModal,
|
||||
}))
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user