tasks 20,21,22,23,24,25,26
This commit is contained in:
parent
a66a4764cf
commit
f8f22e1397
@ -6,6 +6,81 @@ export type PaginationRequest = {
|
|||||||
size: number;
|
size: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/amocrm`;
|
||||||
|
|
||||||
|
// получение информации об аккаунте
|
||||||
|
|
||||||
|
export type AccountResponse = {
|
||||||
|
ID: number;
|
||||||
|
AccountID: string;
|
||||||
|
AmoID: number;
|
||||||
|
Name: string;
|
||||||
|
Email: string;
|
||||||
|
Role: string;
|
||||||
|
Group: number;
|
||||||
|
Deleted: boolean;
|
||||||
|
CreatedAt: number;
|
||||||
|
Subdomain: string;
|
||||||
|
Amoiserid: number;
|
||||||
|
Country: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAccount = async (): Promise<
|
||||||
|
[AccountResponse | null, string?]
|
||||||
|
> => {
|
||||||
|
try {
|
||||||
|
const response = await makeRequest<void, AccountResponse>({
|
||||||
|
method: "GET",
|
||||||
|
url: `${API_URL}/account`,
|
||||||
|
useToken: true,
|
||||||
|
});
|
||||||
|
return [response];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Не удалось получить информацию об аккаунте. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// подключить Amo
|
||||||
|
|
||||||
|
export const connectAmo = async (): Promise<[string | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const response = await makeRequest<void, { link: string }>({
|
||||||
|
method: "POST",
|
||||||
|
url: `${API_URL}/account`,
|
||||||
|
useToken: true,
|
||||||
|
withCredentials: true,
|
||||||
|
});
|
||||||
|
return [response.link];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Не удалось подключить аккаунт. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// получение токена
|
||||||
|
|
||||||
|
export type TokenPair = {
|
||||||
|
accessToken: string;
|
||||||
|
refreshToken: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getTokens = async (): Promise<[TokenPair | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const response = await makeRequest<void, TokenPair>({
|
||||||
|
method: "GET",
|
||||||
|
url: `${API_URL}/webhook/create`,
|
||||||
|
useToken: true,
|
||||||
|
});
|
||||||
|
return [response];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Failed to get tokens. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//получение списка тегов
|
||||||
|
|
||||||
export type Tag = {
|
export type Tag = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
AmoID: number;
|
||||||
@ -21,7 +96,6 @@ export type TagsResponse = {
|
|||||||
count: number;
|
count: number;
|
||||||
items: Tag[];
|
items: Tag[];
|
||||||
};
|
};
|
||||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/amocrm`;
|
|
||||||
|
|
||||||
export const getTags = async ({
|
export const getTags = async ({
|
||||||
page,
|
page,
|
||||||
@ -39,6 +113,8 @@ export const getTags = async ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//получение списка пользователей
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AccountID: string;
|
AccountID: string;
|
||||||
@ -75,6 +151,8 @@ export const getUsers = async ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//получение списка шагов
|
||||||
|
|
||||||
export type Step = {
|
export type Step = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
AmoID: number;
|
||||||
@ -113,6 +191,8 @@ export const getSteps = async ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//получение списка воронок
|
||||||
|
|
||||||
export type Pipeline = {
|
export type Pipeline = {
|
||||||
ID: number;
|
ID: number;
|
||||||
AmoID: number;
|
AmoID: number;
|
||||||
@ -146,3 +226,107 @@ export const getPipelines = async ({
|
|||||||
return [null, `Не удалось получить список воронок. ${error}`];
|
return [null, `Не удалось получить список воронок. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//получение настроек интеграции
|
||||||
|
|
||||||
|
export type IntegrationRules = {
|
||||||
|
ID: number;
|
||||||
|
AccountID: number;
|
||||||
|
QuizID: number;
|
||||||
|
PerformerID: number;
|
||||||
|
PipelineID: number;
|
||||||
|
StepID: number;
|
||||||
|
UTMs: number[];
|
||||||
|
FieldsRule: {
|
||||||
|
lead: { QuestionID: number }[];
|
||||||
|
contact: { ContactRuleMap: string }[];
|
||||||
|
company: { QuestionID: number }[];
|
||||||
|
customer: { QuestionID: number }[];
|
||||||
|
};
|
||||||
|
Deleted: boolean;
|
||||||
|
CreatedAt: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getIntegrationRules = async (
|
||||||
|
quizID: string,
|
||||||
|
): Promise<[IntegrationRules | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const settingsResponse = await makeRequest<void, IntegrationRules>({
|
||||||
|
method: "GET",
|
||||||
|
url: `${API_URL}/rules/${quizID}`,
|
||||||
|
});
|
||||||
|
return [settingsResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Не удалось получить настройки интеграции. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//обновление настроек интеграции
|
||||||
|
|
||||||
|
export type IntegrationRulesUpdate = {
|
||||||
|
PerformerID: number;
|
||||||
|
PipelineID: number;
|
||||||
|
StepID: number;
|
||||||
|
Utms: number[];
|
||||||
|
Fieldsrule: {
|
||||||
|
Lead: { QuestionID: number }[];
|
||||||
|
Contact: { ContactRuleMap: string }[];
|
||||||
|
Company: { QuestionID: number }[];
|
||||||
|
Customer: { QuestionID: number }[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateIntegrationRules = async (
|
||||||
|
quizID: string,
|
||||||
|
settings: IntegrationRulesUpdate,
|
||||||
|
): Promise<[string | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const updateResponse = await makeRequest<IntegrationRulesUpdate, string>({
|
||||||
|
method: "PATCH",
|
||||||
|
url: `${API_URL}/rules/${quizID}`,
|
||||||
|
body: settings,
|
||||||
|
});
|
||||||
|
return [updateResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Failed to update integration settings. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Получение кастомных полей
|
||||||
|
|
||||||
|
export type CustomField = {
|
||||||
|
ID: number;
|
||||||
|
AmoID: number;
|
||||||
|
Code: string;
|
||||||
|
AccountID: number;
|
||||||
|
Name: string;
|
||||||
|
EntityType: string;
|
||||||
|
Type: string;
|
||||||
|
Deleted: boolean;
|
||||||
|
CreatedAt: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CustomFieldsResponse = {
|
||||||
|
count: number;
|
||||||
|
items: CustomField[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCustomFields = async (
|
||||||
|
pagination: PaginationRequest,
|
||||||
|
): Promise<[CustomFieldsResponse | null, string?]> => {
|
||||||
|
try {
|
||||||
|
const fieldsResponse = await makeRequest<
|
||||||
|
PaginationRequest,
|
||||||
|
CustomFieldsResponse
|
||||||
|
>({
|
||||||
|
method: "GET",
|
||||||
|
url: `${API_URL}/fields?page=${pagination.page}&size=${pagination.size}`,
|
||||||
|
});
|
||||||
|
return [fieldsResponse];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
return [null, `Не удалось получить список кастомных полей. ${error}`];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
BIN
src/assets/icons/Amologo.png
Normal file
BIN
src/assets/icons/Amologo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
51
src/components/AmoButton/AmoButton.tsx
Normal file
51
src/components/AmoButton/AmoButton.tsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { Button, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
|
import AmoLogo from "../../assets/icons/Amologo.png";
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
type AmoButtonProps = {
|
||||||
|
onClick?: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AmoButton: FC<AmoButtonProps> = ({ onClick }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#329dc9",
|
||||||
|
width: isMobile ? "270px" : "310px",
|
||||||
|
height: "47px",
|
||||||
|
display: "inline-flex",
|
||||||
|
justifyContent: "start",
|
||||||
|
border: "#316a88 1px solid",
|
||||||
|
color: "white",
|
||||||
|
textDecoration: "none",
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={AmoLogo}
|
||||||
|
style={{
|
||||||
|
height: "100%",
|
||||||
|
maxWidth: "339px",
|
||||||
|
objectFit: "scale-down",
|
||||||
|
userSelect: "none",
|
||||||
|
pointerEvents: "none",
|
||||||
|
}}
|
||||||
|
alt={"AmoCRM"}
|
||||||
|
/>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
margin: "auto",
|
||||||
|
letterSpacing: "1px",
|
||||||
|
fontSize: "14px",
|
||||||
|
fontWeight: 600,
|
||||||
|
textTransform: "uppercase",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Подключить
|
||||||
|
</Typography>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
|
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||||
|
import { FC } from "react";
|
||||||
|
import { AccountResponse } from "@api/integration";
|
||||||
|
|
||||||
|
type AmoAccountInfoProps = {
|
||||||
|
handleNextStep: () => void;
|
||||||
|
accountInfo: AccountResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AmoAccountInfo: FC<AmoAccountInfoProps> = ({
|
||||||
|
handleNextStep,
|
||||||
|
accountInfo,
|
||||||
|
}) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
|
||||||
|
const infoItem = (title: string, value: string | number) => (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: isMobile ? "column" : "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box sx={{ width: isMobile ? "100%" : "45%" }}>
|
||||||
|
<Typography sx={{ color: theme.palette.grey2.main }}>
|
||||||
|
{title}:
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ width: isMobile ? "100%" : "45%" }}>
|
||||||
|
<Typography>{value}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
marginTop: isMobile ? "20px" : "60px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: isMobile ? "10px" : "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{infoItem("Amo ID", accountInfo.AmoID)}
|
||||||
|
{infoItem("Имя аккаунта", accountInfo.Name)}
|
||||||
|
{infoItem("Email аккаунта", accountInfo.Email)}
|
||||||
|
{infoItem("Роль", accountInfo.Role)}
|
||||||
|
{infoItem("Группа пользователя", accountInfo.Group)}
|
||||||
|
{infoItem("URL профиля пользователя в Amo", accountInfo.Subdomain)}
|
||||||
|
{infoItem("Страна пользователя", accountInfo.Country)}
|
||||||
|
</Box>
|
||||||
|
<StepButtonsBlock
|
||||||
|
isSmallBtnDisabled={true}
|
||||||
|
onLargeBtnClick={handleNextStep}
|
||||||
|
largeBtnText={"Далее"}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -5,18 +5,19 @@ import {
|
|||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import React, { FC, useMemo, useState } from "react";
|
import React, { FC, useEffect, useMemo, useState } from "react";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import { IntegrationStep1 } from "./IntegrationStep1/IntegrationStep1";
|
import { AmoLogin } from "./AmoLogin/AmoLogin";
|
||||||
import { IntegrationStep2 } from "./IntegrationStep2/IntegrationStep2";
|
import { AmoStep2 } from "./AmoStep2/AmoStep2";
|
||||||
import { IntegrationStep3 } from "./IntegrationStep3/IntegrationStep3";
|
import { AmoStep3 } from "./AmoStep3/AmoStep3";
|
||||||
import { IntegrationStep4 } from "./IntegrationStep4/IntegrationStep4";
|
import { AmoStep4 } from "./AmoStep4/AmoStep4";
|
||||||
import { IntegrationStep6 } from "./IntegrationStep6/IntegrationStep6";
|
import { AmoStep6 } from "./IntegrationStep6/AmoStep6";
|
||||||
import { performersMock } from "../mocks/MockData";
|
import { AmoModalTitle } from "./AmoModalTitle/AmoModalTitle";
|
||||||
import { IntegrationsModalTitle } from "./IntegrationsModalTitle/IntegrationsModalTitle";
|
import { AmoSettingsBlock } from "./SettingsBlock/AmoSettingsBlock";
|
||||||
import { SettingsBlock } from "./SettingsBlock/SettingsBlock";
|
import { AmoStep7 } from "./IntegrationStep7/AmoStep7";
|
||||||
import { IntegrationStep7 } from "./IntegrationStep7/IntegrationStep7";
|
import { AmoAccountInfo } from "./AmoAccountInfo/AmoAccountInfo";
|
||||||
|
import { AccountResponse, getAccount } from "@api/integration";
|
||||||
|
|
||||||
export type TitleKeys = "contacts" | "company" | "deal" | "users" | "buyers";
|
export type TitleKeys = "contacts" | "company" | "deal" | "users" | "buyers";
|
||||||
|
|
||||||
@ -41,6 +42,8 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
|
|
||||||
const [step, setStep] = useState<number>(0);
|
const [step, setStep] = useState<number>(0);
|
||||||
const [isSettingsBlock, setIsSettingsBlock] = useState<boolean>(false);
|
const [isSettingsBlock, setIsSettingsBlock] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const [accountInfo, setAccountInfo] = useState<AccountResponse | null>(null);
|
||||||
const [selectedPipelinePerformer, setSelectedPipelinePerformer] = useState<
|
const [selectedPipelinePerformer, setSelectedPipelinePerformer] = useState<
|
||||||
string | null
|
string | null
|
||||||
>(null);
|
>(null);
|
||||||
@ -66,6 +69,20 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
buyer: [],
|
buyer: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isModalOpen) {
|
||||||
|
const fetchAccount = async () => {
|
||||||
|
const [account, error] = await getAccount();
|
||||||
|
if (account && !error) {
|
||||||
|
setAccountInfo(account);
|
||||||
|
} else {
|
||||||
|
setAccountInfo(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchAccount();
|
||||||
|
}
|
||||||
|
}, [isModalOpen]);
|
||||||
|
|
||||||
const handleNextStep = () => {
|
const handleNextStep = () => {
|
||||||
setStep((prevState) => prevState + 1);
|
setStep((prevState) => prevState + 1);
|
||||||
};
|
};
|
||||||
@ -76,19 +93,27 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
handleCloseModal();
|
handleCloseModal();
|
||||||
setStep(1);
|
setStep(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const steps = useMemo(
|
const steps = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
title: "Авторизация в аккаунте",
|
title: accountInfo
|
||||||
|
? "Информация об аккаунте"
|
||||||
|
: "Авторизация в аккаунте",
|
||||||
isSettingsAvailable: false,
|
isSettingsAvailable: false,
|
||||||
component: <IntegrationStep1 handleNextStep={handleNextStep} />,
|
component: accountInfo ? (
|
||||||
|
<AmoAccountInfo
|
||||||
|
handleNextStep={handleNextStep}
|
||||||
|
accountInfo={accountInfo}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<AmoLogin handleNextStep={handleNextStep} />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Выбор воронки",
|
title: "Выбор воронки",
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<IntegrationStep2
|
<AmoStep2
|
||||||
handlePrevStep={handlePrevStep}
|
handlePrevStep={handlePrevStep}
|
||||||
handleNextStep={handleNextStep}
|
handleNextStep={handleNextStep}
|
||||||
selectedPipelinePerformer={selectedPipelinePerformer}
|
selectedPipelinePerformer={selectedPipelinePerformer}
|
||||||
@ -102,7 +127,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
title: "Выбор этапа воронки",
|
title: "Выбор этапа воронки",
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<IntegrationStep3
|
<AmoStep3
|
||||||
handlePrevStep={handlePrevStep}
|
handlePrevStep={handlePrevStep}
|
||||||
handleNextStep={handleNextStep}
|
handleNextStep={handleNextStep}
|
||||||
selectedStepsPerformer={selectedStepsPerformer}
|
selectedStepsPerformer={selectedStepsPerformer}
|
||||||
@ -117,12 +142,11 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
title: "Сделка",
|
title: "Сделка",
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<IntegrationStep4
|
<AmoStep4
|
||||||
handlePrevStep={handlePrevStep}
|
handlePrevStep={handlePrevStep}
|
||||||
handleNextStep={handleNextStep}
|
handleNextStep={handleNextStep}
|
||||||
selectedDealPerformer={selectedDealPerformer}
|
selectedDealPerformer={selectedDealPerformer}
|
||||||
setSelectedDealPerformer={setSelectedDealPerformer}
|
setSelectedDealPerformer={setSelectedDealPerformer}
|
||||||
performers={performersMock}
|
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -130,7 +154,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
title: "Соотнесение вопросов и сущностей",
|
title: "Соотнесение вопросов и сущностей",
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<IntegrationStep6
|
<AmoStep6
|
||||||
questionEntity={questionEntity}
|
questionEntity={questionEntity}
|
||||||
setQuestionEntity={setQuestionEntity}
|
setQuestionEntity={setQuestionEntity}
|
||||||
handlePrevStep={handlePrevStep}
|
handlePrevStep={handlePrevStep}
|
||||||
@ -142,7 +166,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
title: "Добавление тегов",
|
title: "Добавление тегов",
|
||||||
isSettingsAvailable: true,
|
isSettingsAvailable: true,
|
||||||
component: (
|
component: (
|
||||||
<IntegrationStep7
|
<AmoStep7
|
||||||
handleSmallBtn={handlePrevStep}
|
handleSmallBtn={handlePrevStep}
|
||||||
handleLargeBtn={handleSave}
|
handleLargeBtn={handleSave}
|
||||||
tags={tags}
|
tags={tags}
|
||||||
@ -153,7 +177,6 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
questionEntity,
|
questionEntity,
|
||||||
// utmFile,
|
|
||||||
selectedPipelinePerformer,
|
selectedPipelinePerformer,
|
||||||
selectedPipeline,
|
selectedPipeline,
|
||||||
selectedStepsPerformer,
|
selectedStepsPerformer,
|
||||||
@ -221,7 +244,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<IntegrationsModalTitle
|
<AmoModalTitle
|
||||||
step={step}
|
step={step}
|
||||||
steps={steps}
|
steps={steps}
|
||||||
isSettingsBlock={isSettingsBlock}
|
isSettingsBlock={isSettingsBlock}
|
||||||
@ -230,7 +253,7 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({
|
|||||||
/>
|
/>
|
||||||
{isSettingsBlock ? (
|
{isSettingsBlock ? (
|
||||||
<Box sx={{ flexGrow: 1, width: "100%" }}>
|
<Box sx={{ flexGrow: 1, width: "100%" }}>
|
||||||
<SettingsBlock
|
<AmoSettingsBlock
|
||||||
stepTitles={stepTitles}
|
stepTitles={stepTitles}
|
||||||
setIsSettingsBlock={setIsSettingsBlock}
|
setIsSettingsBlock={setIsSettingsBlock}
|
||||||
setStep={setStep}
|
setStep={setStep}
|
||||||
|
|||||||
@ -0,0 +1,150 @@
|
|||||||
|
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
|
import { FC } from "react";
|
||||||
|
import { AmoButton } from "../../../../components/AmoButton/AmoButton";
|
||||||
|
import { connectAmo } from "@api/integration";
|
||||||
|
|
||||||
|
type IntegrationStep1Props = {
|
||||||
|
handleNextStep: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
// interface Values {
|
||||||
|
// login: string;
|
||||||
|
// password: string;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const initialValues: Values = {
|
||||||
|
// login: "",
|
||||||
|
// password: "",
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const validationSchema = object({
|
||||||
|
// login: string().required("Поле обязательно"),
|
||||||
|
// password: string().required("Поле обязательно").min(8, "Минимум 8 символов"),
|
||||||
|
// });
|
||||||
|
|
||||||
|
export const AmoLogin: FC<IntegrationStep1Props> = ({ handleNextStep }) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
|
|
||||||
|
const onAmoClick = async () => {
|
||||||
|
console.log("Amo click");
|
||||||
|
const [url, error] = await connectAmo();
|
||||||
|
if (url && !error) {
|
||||||
|
window.open(url, "_blank");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// const formik = useFormik<Values>({
|
||||||
|
// initialValues,
|
||||||
|
// validationSchema,
|
||||||
|
// onSubmit: async (values, formikHelpers) => {
|
||||||
|
// const loginTrimmed = values.login.trim();
|
||||||
|
// const passwordTrimmed = values.password.trim();
|
||||||
|
// try {
|
||||||
|
// // Simulate a network request
|
||||||
|
// await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||||
|
// handleNextStep();
|
||||||
|
// } catch (error) {
|
||||||
|
// formikHelpers.setSubmitting(false);
|
||||||
|
// if (error instanceof Error) {
|
||||||
|
// formikHelpers.setErrors({
|
||||||
|
// login: error.message,
|
||||||
|
// password: error.message,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
// component="form"
|
||||||
|
// onSubmit={formik.handleSubmit}
|
||||||
|
// noValidate
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/*<Box*/}
|
||||||
|
{/* sx={{*/}
|
||||||
|
{/* marginTop: "68px",*/}
|
||||||
|
{/* width: isMobile ? "100%" : "500px",*/}
|
||||||
|
{/* display: "flex",*/}
|
||||||
|
{/* flexDirection: "column",*/}
|
||||||
|
{/* alignItems: "center",*/}
|
||||||
|
{/* gap: "15px",*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/*>*/}
|
||||||
|
{/* <InputTextfield*/}
|
||||||
|
{/* TextfieldProps={{*/}
|
||||||
|
{/* value: formik.values.login,*/}
|
||||||
|
{/* placeholder: "+7 900 000 00 00 или username@penahaub.com",*/}
|
||||||
|
{/* onBlur: formik.handleBlur,*/}
|
||||||
|
{/* error: formik.touched.login && Boolean(formik.errors.login),*/}
|
||||||
|
{/* helperText: formik.touched.login && formik.errors.login,*/}
|
||||||
|
{/* "data-cy": "login",*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/* onChange={formik.handleChange}*/}
|
||||||
|
{/* color={theme.palette.background.default}*/}
|
||||||
|
{/* id="login"*/}
|
||||||
|
{/* label="Телефон или E-mail"*/}
|
||||||
|
{/* gap="10px"*/}
|
||||||
|
{/* />*/}
|
||||||
|
{/* <PasswordInput*/}
|
||||||
|
{/* TextfieldProps={{*/}
|
||||||
|
{/* value: formik.values.password,*/}
|
||||||
|
{/* placeholder: "Не менее 8 символов",*/}
|
||||||
|
{/* onBlur: formik.handleBlur,*/}
|
||||||
|
{/* error: formik.touched.password && Boolean(formik.errors.password),*/}
|
||||||
|
{/* helperText: formik.touched.password && formik.errors.password,*/}
|
||||||
|
{/* type: "password",*/}
|
||||||
|
{/* "data-cy": "password",*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/* onChange={formik.handleChange}*/}
|
||||||
|
{/* color={theme.palette.background.default}*/}
|
||||||
|
{/* id="password"*/}
|
||||||
|
{/* label="Пароль"*/}
|
||||||
|
{/* gap="10px"*/}
|
||||||
|
{/* />*/}
|
||||||
|
{/*</Box>*/}
|
||||||
|
<Box sx={{ marginTop: "70px", width: isMobile ? "100%" : "500px" }}>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: "400",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
lineHeight: "1",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Инструкция
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
marginTop: "12px",
|
||||||
|
fontSize: "18px",
|
||||||
|
fontWeight: "400",
|
||||||
|
color: theme.palette.grey3.main,
|
||||||
|
lineHeight: "1",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
После нажатия на кнопку - "Подключить", вас переадресует на страницу
|
||||||
|
подключения интеграции в ваш аккаунт AmoCRM. Пожалуйста, согласитесь
|
||||||
|
на всё, что мы предлагаем, иначе чуда не случится.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ marginTop: "50px" }}>
|
||||||
|
<AmoButton onClick={onAmoClick} />
|
||||||
|
</Box>
|
||||||
|
{/*<StepButtonsBlock*/}
|
||||||
|
{/* isSmallBtnDisabled={true}*/}
|
||||||
|
{/* largeBtnType={"submit"}*/}
|
||||||
|
{/* // isLargeBtnDisabled={formik.isSubmitting}*/}
|
||||||
|
{/* largeBtnText={"Войти"}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -4,7 +4,7 @@ import GearIcon from "@icons/GearIcon";
|
|||||||
import React, { FC, useCallback, useMemo } from "react";
|
import React, { FC, useCallback, useMemo } from "react";
|
||||||
import AccountSetting from "@icons/AccountSetting";
|
import AccountSetting from "@icons/AccountSetting";
|
||||||
|
|
||||||
type IntegrationsModalTitleProps = {
|
type AmoModalTitleProps = {
|
||||||
step: number;
|
step: number;
|
||||||
steps: { title: string; isSettingsAvailable: boolean }[];
|
steps: { title: string; isSettingsAvailable: boolean }[];
|
||||||
isSettingsBlock?: boolean;
|
isSettingsBlock?: boolean;
|
||||||
@ -12,7 +12,7 @@ type IntegrationsModalTitleProps = {
|
|||||||
setStep: (value: number) => void;
|
setStep: (value: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationsModalTitle: FC<IntegrationsModalTitleProps> = ({
|
export const AmoModalTitle: FC<AmoModalTitleProps> = ({
|
||||||
step,
|
step,
|
||||||
steps,
|
steps,
|
||||||
setIsSettingsBlock,
|
setIsSettingsBlock,
|
||||||
@ -4,7 +4,7 @@ import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
|||||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||||
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||||
|
|
||||||
type IntegrationStep2Props = {
|
type AmoStep2Props = {
|
||||||
handlePrevStep: () => void;
|
handlePrevStep: () => void;
|
||||||
handleNextStep: () => void;
|
handleNextStep: () => void;
|
||||||
selectedPipelinePerformer: string | null;
|
selectedPipelinePerformer: string | null;
|
||||||
@ -13,7 +13,7 @@ type IntegrationStep2Props = {
|
|||||||
setSelectedPipeline: (value: string | null) => void;
|
setSelectedPipeline: (value: string | null) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationStep2: FC<IntegrationStep2Props> = ({
|
export const AmoStep2: FC<AmoStep2Props> = ({
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
selectedPipelinePerformer,
|
selectedPipelinePerformer,
|
||||||
@ -4,7 +4,7 @@ import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
|||||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||||
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
import { CustomRadioGroup } from "../../../../components/CustomRadioGroup/CustomRadioGroup";
|
||||||
|
|
||||||
type IntegrationStep3Props = {
|
type AmoStep3Props = {
|
||||||
handlePrevStep: () => void;
|
handlePrevStep: () => void;
|
||||||
handleNextStep: () => void;
|
handleNextStep: () => void;
|
||||||
selectedStepsPerformer: string | null;
|
selectedStepsPerformer: string | null;
|
||||||
@ -14,7 +14,7 @@ type IntegrationStep3Props = {
|
|||||||
pipelineId: string | null;
|
pipelineId: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationStep3: FC<IntegrationStep3Props> = ({
|
export const AmoStep3: FC<AmoStep3Props> = ({
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
selectedStepsPerformer,
|
selectedStepsPerformer,
|
||||||
@ -53,6 +53,7 @@ export const IntegrationStep3: FC<IntegrationStep3Props> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomRadioGroup
|
<CustomRadioGroup
|
||||||
|
// @ts-ignore
|
||||||
pipelineId={pipelineId}
|
pipelineId={pipelineId}
|
||||||
type={"typeSteps"}
|
type={"typeSteps"}
|
||||||
selectedValue={selectedStep}
|
selectedValue={selectedStep}
|
||||||
@ -3,20 +3,18 @@ import { FC } from "react";
|
|||||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||||
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
import { CustomSelect } from "../../../../components/CustomSelect/CustomSelect";
|
||||||
|
|
||||||
type IntegrationStep4Props = {
|
type AmoStep4Props = {
|
||||||
handlePrevStep: () => void;
|
handlePrevStep: () => void;
|
||||||
handleNextStep: () => void;
|
handleNextStep: () => void;
|
||||||
selectedDealPerformer: string | null;
|
selectedDealPerformer: string | null;
|
||||||
setSelectedDealPerformer: (value: string | null) => void;
|
setSelectedDealPerformer: (value: string | null) => void;
|
||||||
performers: string[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationStep4: FC<IntegrationStep4Props> = ({
|
export const AmoStep4: FC<AmoStep4Props> = ({
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
selectedDealPerformer,
|
selectedDealPerformer,
|
||||||
setSelectedDealPerformer,
|
setSelectedDealPerformer,
|
||||||
performers,
|
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
@ -1,144 +0,0 @@
|
|||||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
||||||
import { FC } from "react";
|
|
||||||
import { object, string } from "yup";
|
|
||||||
import InputTextfield from "@ui_kit/InputTextfield";
|
|
||||||
import PasswordInput from "@ui_kit/passwordInput";
|
|
||||||
import { useFormik } from "formik";
|
|
||||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
|
||||||
|
|
||||||
type IntegrationStep1Props = {
|
|
||||||
handleNextStep: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface Values {
|
|
||||||
login: string;
|
|
||||||
password: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialValues: Values = {
|
|
||||||
login: "",
|
|
||||||
password: "",
|
|
||||||
};
|
|
||||||
|
|
||||||
const validationSchema = object({
|
|
||||||
login: string().required("Поле обязательно"),
|
|
||||||
password: string().required("Поле обязательно").min(8, "Минимум 8 символов"),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const IntegrationStep1: FC<IntegrationStep1Props> = ({
|
|
||||||
handleNextStep,
|
|
||||||
}) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
|
||||||
|
|
||||||
const formik = useFormik<Values>({
|
|
||||||
initialValues,
|
|
||||||
validationSchema,
|
|
||||||
onSubmit: async (values, formikHelpers) => {
|
|
||||||
const loginTrimmed = values.login.trim();
|
|
||||||
const passwordTrimmed = values.password.trim();
|
|
||||||
try {
|
|
||||||
// Simulate a network request
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
||||||
handleNextStep();
|
|
||||||
} catch (error) {
|
|
||||||
formikHelpers.setSubmitting(false);
|
|
||||||
if (error instanceof Error) {
|
|
||||||
formikHelpers.setErrors({
|
|
||||||
login: error.message,
|
|
||||||
password: error.message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
component="form"
|
|
||||||
onSubmit={formik.handleSubmit}
|
|
||||||
noValidate
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: isMobile ? "start" : "center",
|
|
||||||
height: "100%",
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
marginTop: "68px",
|
|
||||||
width: isMobile ? "100%" : "500px",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "15px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InputTextfield
|
|
||||||
TextfieldProps={{
|
|
||||||
value: formik.values.login,
|
|
||||||
placeholder: "+7 900 000 00 00 или username@penahaub.com",
|
|
||||||
onBlur: formik.handleBlur,
|
|
||||||
error: formik.touched.login && Boolean(formik.errors.login),
|
|
||||||
helperText: formik.touched.login && formik.errors.login,
|
|
||||||
"data-cy": "login",
|
|
||||||
}}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
color={theme.palette.background.default}
|
|
||||||
id="login"
|
|
||||||
label="Телефон или E-mail"
|
|
||||||
gap="10px"
|
|
||||||
/>
|
|
||||||
<PasswordInput
|
|
||||||
TextfieldProps={{
|
|
||||||
value: formik.values.password,
|
|
||||||
placeholder: "Не менее 8 символов",
|
|
||||||
onBlur: formik.handleBlur,
|
|
||||||
error: formik.touched.password && Boolean(formik.errors.password),
|
|
||||||
helperText: formik.touched.password && formik.errors.password,
|
|
||||||
type: "password",
|
|
||||||
"data-cy": "password",
|
|
||||||
}}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
color={theme.palette.background.default}
|
|
||||||
id="password"
|
|
||||||
label="Пароль"
|
|
||||||
gap="10px"
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ marginTop: "30px", width: isMobile ? "100%" : "500px" }}>
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
fontSize: "16px",
|
|
||||||
fontWeight: "400",
|
|
||||||
color: theme.palette.grey2.main,
|
|
||||||
lineHeight: "1",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Инструкция
|
|
||||||
</Typography>
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
marginTop: "12px",
|
|
||||||
fontSize: "18px",
|
|
||||||
fontWeight: "400",
|
|
||||||
color: theme.palette.grey3.main,
|
|
||||||
lineHeight: "1",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Повседневная практика показывает, что постоянный количественный рост и
|
|
||||||
сфера нашей активности способствует подготовки и реализации систем
|
|
||||||
массового участия
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<StepButtonsBlock
|
|
||||||
isSmallBtnDisabled={true}
|
|
||||||
largeBtnType={"submit"}
|
|
||||||
isLargeBtnDisabled={formik.isSubmitting}
|
|
||||||
largeBtnText={"Войти"}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -12,14 +12,14 @@ import { ItemDetailsView } from "./ItemDetailsView/ItemDetailsView";
|
|||||||
import { TitleKeys, TQuestionEntity } from "../AmoCRMModal";
|
import { TitleKeys, TQuestionEntity } from "../AmoCRMModal";
|
||||||
import Box from "@mui/material/Box";
|
import Box from "@mui/material/Box";
|
||||||
|
|
||||||
type IntegrationStep6Props = {
|
type AmoStep6Props = {
|
||||||
handlePrevStep: () => void;
|
handlePrevStep: () => void;
|
||||||
handleNextStep: () => void;
|
handleNextStep: () => void;
|
||||||
questionEntity: TQuestionEntity;
|
questionEntity: TQuestionEntity;
|
||||||
setQuestionEntity: Dispatch<SetStateAction<TQuestionEntity>>;
|
setQuestionEntity: Dispatch<SetStateAction<TQuestionEntity>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationStep6: FC<IntegrationStep6Props> = ({
|
export const AmoStep6: FC<AmoStep6Props> = ({
|
||||||
handlePrevStep,
|
handlePrevStep,
|
||||||
handleNextStep,
|
handleNextStep,
|
||||||
questionEntity,
|
questionEntity,
|
||||||
@ -13,14 +13,14 @@ import Box from "@mui/material/Box";
|
|||||||
import { ItemsSelectionView } from "../IntegrationStep6/ItemsSelectionView/ItemsSelectionView";
|
import { ItemsSelectionView } from "../IntegrationStep6/ItemsSelectionView/ItemsSelectionView";
|
||||||
import { TagsDetailsView } from "./TagsDetailsView/TagsDetailsView";
|
import { TagsDetailsView } from "./TagsDetailsView/TagsDetailsView";
|
||||||
|
|
||||||
type IntegrationStep7Props = {
|
type AmoStep7Props = {
|
||||||
handleSmallBtn: () => void;
|
handleSmallBtn: () => void;
|
||||||
handleLargeBtn: () => void;
|
handleLargeBtn: () => void;
|
||||||
tags: TTags;
|
tags: TTags;
|
||||||
setTags: Dispatch<SetStateAction<TTags>>;
|
setTags: Dispatch<SetStateAction<TTags>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IntegrationStep7: FC<IntegrationStep7Props> = ({
|
export const AmoStep7: FC<AmoStep7Props> = ({
|
||||||
handleSmallBtn,
|
handleSmallBtn,
|
||||||
handleLargeBtn,
|
handleLargeBtn,
|
||||||
tags,
|
tags,
|
||||||
@ -4,7 +4,7 @@ import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
|||||||
import { SettingItem } from "./SettingItem/SettingItem";
|
import { SettingItem } from "./SettingItem/SettingItem";
|
||||||
import { TQuestionEntity, TTags } from "../AmoCRMModal";
|
import { TQuestionEntity, TTags } from "../AmoCRMModal";
|
||||||
|
|
||||||
type SettingsBlockProps = {
|
type AmoSettingsBlockProps = {
|
||||||
stepTitles: string[];
|
stepTitles: string[];
|
||||||
setStep: (value: number) => void;
|
setStep: (value: number) => void;
|
||||||
setIsSettingsBlock: (value: boolean) => void;
|
setIsSettingsBlock: (value: boolean) => void;
|
||||||
@ -17,7 +17,7 @@ type SettingsBlockProps = {
|
|||||||
tags: TTags;
|
tags: TTags;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SettingsBlock: FC<SettingsBlockProps> = ({
|
export const AmoSettingsBlock: FC<AmoSettingsBlockProps> = ({
|
||||||
stepTitles,
|
stepTitles,
|
||||||
setStep,
|
setStep,
|
||||||
setIsSettingsBlock,
|
setIsSettingsBlock,
|
||||||
Loading…
Reference in New Issue
Block a user