396 lines
12 KiB
TypeScript
396 lines
12 KiB
TypeScript
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: () => void;
|
||
setPageOfPipelinesSteps: () => void;
|
||
setPageOfUsers: () => void;
|
||
setPageOfTags: () => void;
|
||
setPageOfFields: () => void;
|
||
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,
|
||
setPageOfFields,
|
||
setSelectedCurrentFields,
|
||
handleCloseModal,
|
||
}: Props) => {
|
||
const [step, setStep] = useState(0)
|
||
const [specialPage, setSpecialPage] = useState<"deleteCell" | "removeAccount" | "settingsBlock" | "accountInfo" | "amoLogin" | "">(accountInfo ? "accountInfo" : "amoLogin")
|
||
const [openDelete, setOpenDelete] = useState<TagQuestionHC | null>(null);
|
||
|
||
const startDeleteTagQuestion = (itemForDelete) => {
|
||
setOpenDelete(itemForDelete)
|
||
setSpecialPage("deleteCell")
|
||
}
|
||
|
||
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)
|
||
setSelectedQuestions(newArray);
|
||
setSelectedCurrentFields(selectedCurrentFields.filter(e => e.id !== openDelete.id));
|
||
|
||
}
|
||
setOpenDelete(null);
|
||
closeSpecialPage();
|
||
}
|
||
|
||
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;
|
||
|
||
console.log(body)
|
||
|
||
// if (firstRules) {
|
||
// setIntegrationRules(quiz.backendId.toString(), body);
|
||
// } else {
|
||
// updateIntegrationRules(quiz.backendId.toString(), body);
|
||
// }
|
||
|
||
handleCloseModal();
|
||
};
|
||
|
||
|
||
const closeSpecialPage = () => setSpecialPage("")
|
||
|
||
const steps = [
|
||
{
|
||
isSettingsAvailable: true,
|
||
component: (
|
||
<Pipelines
|
||
users={arrayOfUsers}
|
||
pipelines={arrayOfPipelines}
|
||
handlePrevStep={() => setSpecialPage("accountInfo")}
|
||
handleNextStep={handleNextStep}
|
||
selectedDealUser={selectedDealUser}
|
||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||
selectedPipeline={selectedPipeline}
|
||
setSelectedPipeline={setSelectedPipeline}
|
||
titleProps={{
|
||
step: step + 2,
|
||
title: "Выбор воронки",
|
||
desc: "На этом этапе вы можете выбрать нужную воронку и ответственного за сделку",
|
||
toSettings: () => setSpecialPage("settingsBlock")
|
||
}}
|
||
onScroll={setPageOfPipelines}
|
||
onScrollUsers={setPageOfUsers}
|
||
/>
|
||
),
|
||
},
|
||
{
|
||
isSettingsAvailable: true,
|
||
component: (
|
||
<PipelineSteps
|
||
users={arrayOfUsers}
|
||
selectedDealUser={selectedDealUser}
|
||
selectedStep={selectedPipelineStep}
|
||
steps={arrayOfPipelinesSteps}
|
||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||
setSelectedStep={setSelectedPipelineStep}
|
||
handlePrevStep={handlePrevStep}
|
||
handleNextStep={handleNextStep}
|
||
titleProps={{
|
||
step: step + 2,
|
||
title: "Выбор этапа воронки",
|
||
desc: "На этом этапе вы можете выбрать нужный этап и ответственного за сделку",
|
||
toSettings: () => setSpecialPage("settingsBlock")
|
||
}}
|
||
onScroll={setPageOfPipelinesSteps}
|
||
onScrollUsers={setPageOfUsers}
|
||
/>
|
||
),
|
||
},
|
||
{
|
||
isSettingsAvailable: true,
|
||
component: (
|
||
<DealPerformers
|
||
handlePrevStep={handlePrevStep}
|
||
handleNextStep={handleNextStep}
|
||
users={arrayOfUsers}
|
||
selectedDealUser={selectedDealUser}
|
||
setSelectedDealPerformer={setSelectedDealPerformer}
|
||
titleProps={{
|
||
step: step + 2,
|
||
title: "Сделка",
|
||
desc: "На этом этапе вы можете выбрать ответственного за сделку",
|
||
toSettings: () => setSpecialPage("settingsBlock")
|
||
}}
|
||
onScrollUsers={setPageOfUsers}
|
||
/>
|
||
),
|
||
},
|
||
{
|
||
isSettingsAvailable: true,
|
||
component: (
|
||
<AmoTags
|
||
tagsItems={arrayOfTags}
|
||
selectedTags={selectedTags}
|
||
openDelete={startDeleteTagQuestion}
|
||
handleAddTag={handleAddTagQuestion}
|
||
handlePrevStep={handlePrevStep}
|
||
handleNextStep={handleNextStep}
|
||
titleProps={{
|
||
step: step + 2,
|
||
title: "Добавление тегов",
|
||
desc: "На этом этапе вы можете добавить теги с результатами",
|
||
toSettings: () => setSpecialPage("settingsBlock")
|
||
}}
|
||
onScroll={setPageOfTags}
|
||
/>
|
||
),
|
||
},
|
||
{
|
||
isSettingsAvailable: true,
|
||
component: (
|
||
<AmoQuestions
|
||
setSelectedCurrentFields={setSelectedCurrentFields}
|
||
fieldsItems={arrayOfFields}
|
||
selectedCurrentFields={selectedCurrentFields}
|
||
questionsItems={minifiedQuestions}
|
||
selectedQuestions={selectedQuestions}
|
||
openDelete={startDeleteTagQuestion}
|
||
handleAddQuestion={handleAddTagQuestion}
|
||
handlePrevStep={handlePrevStep}
|
||
handleNextStep={handleSave}
|
||
FieldsAllowedFC={FieldsAllowedFC}
|
||
titleProps={{
|
||
step: step + 2,
|
||
title: "Соотнесение вопросов и сущностей",
|
||
toSettings: () => setSpecialPage("settingsBlock")
|
||
}}
|
||
onScroll={setPageOfFields}
|
||
/>
|
||
),
|
||
},
|
||
]
|
||
|
||
const stepTitles = steps.map((step) => step.title);
|
||
|
||
switch (specialPage) {
|
||
case "deleteCell":
|
||
return <DeleteTagQuestion
|
||
close={closeSpecialPage}
|
||
deleteItem={handleDeleteTagQuestion}
|
||
/>
|
||
case "removeAccount":
|
||
return <RemoveAccount
|
||
handleCloseModal={handleCloseModal}
|
||
stopThisPage={closeSpecialPage}
|
||
/>
|
||
case "settingsBlock":
|
||
return <SettingsBlock
|
||
stepTitles={stepTitles}
|
||
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}
|
||
toBack={() => closeSpecialPage()}
|
||
setStep={(step: number) => {
|
||
closeSpecialPage()
|
||
setStep(step-1)
|
||
}}
|
||
/>
|
||
case "amoLogin": return <AmoLogin handleNextStep={handleNextStep} />
|
||
case "accountInfo": return <AccountInfo
|
||
handleNextStep={() => closeSpecialPage()}
|
||
accountInfo={accountInfo}
|
||
toChangeAccount={() => setSpecialPage("removeAccount")}
|
||
/>
|
||
|
||
|
||
default: return <Box sx={{
|
||
flexGrow: 1,
|
||
width: "100%",
|
||
height: "100%",
|
||
overflow: "auto"
|
||
}}>{steps[step].component}</Box>
|
||
}
|
||
} |