WIP 1step integrations, integrations modal
This commit is contained in:
parent
5434d0cafc
commit
137fa317da
@ -0,0 +1,164 @@
|
||||
import { Box, Button, Typography, 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 ArrowLeft from "@icons/questionsPage/arrowLeft";
|
||||
|
||||
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 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));
|
||||
console.log("Simulated network request completed");
|
||||
handleNextStep();
|
||||
} catch (error) {
|
||||
console.error("Errr");
|
||||
formikHelpers.setSubmitting(false);
|
||||
formikHelpers.setErrors({ submit: 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: "500px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<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="#F2F3F7"
|
||||
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="#F2F3F7"
|
||||
id="password"
|
||||
label="Пароль"
|
||||
gap="10px"
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ marginTop: "30px", width: "500px" }}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "16px",
|
||||
fontWeight: "400",
|
||||
color: "#9A9AAF",
|
||||
lineHeight: "1",
|
||||
}}
|
||||
>
|
||||
Инструкция
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
marginTop: "12px",
|
||||
fontSize: "18px",
|
||||
fontWeight: "400",
|
||||
color: "#4D4D4D",
|
||||
lineHeight: "1",
|
||||
}}
|
||||
>
|
||||
Повседневная практика показывает, что постоянный количественный рост и
|
||||
сфера нашей активности способствует подготовки и реализации систем
|
||||
массового участия
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
marginTop: "auto",
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}
|
||||
data-cy="back-button"
|
||||
disabled
|
||||
>
|
||||
<ArrowLeft color={theme.palette.grey2.main} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
type="submit"
|
||||
disabled={formik.isSubmitting}
|
||||
sx={{
|
||||
height: "44px",
|
||||
padding: "10px 20px",
|
||||
borderRadius: "8px",
|
||||
background: theme.palette.brightPurple.main,
|
||||
fontSize: "18px",
|
||||
}}
|
||||
data-cy="signin"
|
||||
>
|
||||
Войти
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
|
||||
type IntegrationStep2Props = {
|
||||
handlePrevStep: () => void;
|
||||
handleNextStep: () => void;
|
||||
};
|
||||
|
||||
export const IntegrationStep2: FC<IntegrationStep2Props> = ({
|
||||
handlePrevStep,
|
||||
handleNextStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ color: "#4D4D4D", mt: "5px", mb: upMd ? "10px" : "33px" }}
|
||||
>
|
||||
step 2
|
||||
</Typography>
|
||||
<StepButtonsBlock
|
||||
handleNextStep={handleNextStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
|
||||
type IntegrationStep3Props = {
|
||||
handlePrevStep: () => void;
|
||||
handleNextStep: () => void;
|
||||
};
|
||||
|
||||
export const IntegrationStep3: FC<IntegrationStep3Props> = ({
|
||||
handlePrevStep,
|
||||
handleNextStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ color: "#4D4D4D", mt: "5px", mb: upMd ? "10px" : "33px" }}
|
||||
>
|
||||
step 3
|
||||
</Typography>
|
||||
<StepButtonsBlock
|
||||
handleNextStep={handleNextStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
|
||||
type IntegrationStep4Props = {
|
||||
handlePrevStep: () => void;
|
||||
handleNextStep: () => void;
|
||||
};
|
||||
|
||||
export const IntegrationStep4: FC<IntegrationStep4Props> = ({
|
||||
handlePrevStep,
|
||||
handleNextStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ color: "#4D4D4D", mt: "5px", mb: upMd ? "10px" : "33px" }}
|
||||
>
|
||||
step 4
|
||||
</Typography>
|
||||
<StepButtonsBlock
|
||||
handleNextStep={handleNextStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { StepButtonsBlock } from "../StepButtonsBlock/StepButtonsBlock";
|
||||
|
||||
type IntegrationStep5Props = {
|
||||
handlePrevStep: () => void;
|
||||
handleNextStep: () => void;
|
||||
};
|
||||
|
||||
export const IntegrationStep5: FC<IntegrationStep5Props> = ({
|
||||
handlePrevStep,
|
||||
handleNextStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ color: "#4D4D4D", mt: "5px", mb: upMd ? "10px" : "33px" }}
|
||||
>
|
||||
step 5
|
||||
</Typography>
|
||||
<StepButtonsBlock
|
||||
handleNextStep={handleNextStep}
|
||||
handlePrevStep={handlePrevStep}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,31 @@
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
|
||||
type IntegrationStep6Props = {
|
||||
handlePrevStep: () => void;
|
||||
};
|
||||
|
||||
export const IntegrationStep6: FC<IntegrationStep6Props> = ({
|
||||
handlePrevStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
flexGrow: 1,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ color: "#4D4D4D", mt: "5px", mb: upMd ? "10px" : "33px" }}
|
||||
>
|
||||
step 6
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -1,38 +1,121 @@
|
||||
import { Dialog, IconButton, useTheme } from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import {
|
||||
Dialog,
|
||||
IconButton,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { FC, useMemo, useState } from "react";
|
||||
import Box from "@mui/material/Box";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import { IntegrationStep1 } from "./IntegrationStep1/IntegrationStep1";
|
||||
import { IntegrationStep2 } from "./IntegrationStep2/IntegrationStep2";
|
||||
import { IntegrationStep3 } from "./IntegrationStep3/IntegrationStep3";
|
||||
import { IntegrationStep4 } from "./IntegrationStep4/IntegrationStep4";
|
||||
import { IntegrationStep5 } from "./IntegrationStep5/IntegrationStep5";
|
||||
import { IntegrationStep6 } from "./IntegrationStep6/IntegrationStep6";
|
||||
|
||||
type IntegrationsModalProps = {
|
||||
isModalOpen: boolean;
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
handleCloseModal: () => void;
|
||||
companyName: string | null;
|
||||
};
|
||||
|
||||
export const IntegrationsModal: FC<IntegrationsModalProps> = ({
|
||||
isModalOpen,
|
||||
setIsModalOpen,
|
||||
handleCloseModal,
|
||||
companyName,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const [step, setStep] = useState<number>(0);
|
||||
|
||||
function handleClose() {
|
||||
setIsModalOpen(false);
|
||||
}
|
||||
const handleNextStep = () => {
|
||||
setStep((prevState) => prevState + 1);
|
||||
};
|
||||
const handlePrevStep = () => {
|
||||
setStep((prevState) => prevState - 1);
|
||||
};
|
||||
|
||||
const steps = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: "Авторизация в аккаунте",
|
||||
component: <IntegrationStep1 handleNextStep={handleNextStep} />,
|
||||
},
|
||||
{
|
||||
title: "Выбор воронки",
|
||||
component: (
|
||||
<IntegrationStep2
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Выбор этапа воронки",
|
||||
component: (
|
||||
<IntegrationStep3
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Сделка",
|
||||
component: (
|
||||
<IntegrationStep4
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Название шага",
|
||||
component: (
|
||||
<IntegrationStep5
|
||||
handlePrevStep={handlePrevStep}
|
||||
handleNextStep={handleNextStep}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Добавление тегов",
|
||||
component: <IntegrationStep6 handlePrevStep={handlePrevStep} />,
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={isModalOpen}
|
||||
onClose={handleClose}
|
||||
onClose={handleCloseModal}
|
||||
fullWidth
|
||||
fullScreen={isMobile}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
maxWidth: "920px",
|
||||
maxHeight: "660px",
|
||||
maxWidth: isTablet ? "100%" : "920px",
|
||||
maxHeight: isTablet ? "100%" : "660px",
|
||||
borderRadius: "12px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
height: "68px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ fontSize: "24px", fontWeight: "500", padding: "20px" }}
|
||||
>
|
||||
Интеграция с {companyName ? companyName : "партнером"}
|
||||
</Typography>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={handleClose}
|
||||
onClick={handleCloseModal}
|
||||
sx={{
|
||||
width: "12px",
|
||||
height: "12px",
|
||||
@ -47,10 +130,37 @@ export const IntegrationsModal: FC<IntegrationsModalProps> = ({
|
||||
</IconButton>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "920px",
|
||||
height: "660px",
|
||||
height: "600px",
|
||||
padding: "15px 20px 15px",
|
||||
flexGrow: 1, // Add this line
|
||||
}}
|
||||
></Box>
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "24px",
|
||||
color: "#4D4D4D",
|
||||
fontWeight: "500",
|
||||
lineHeight: "1",
|
||||
}}
|
||||
>
|
||||
{steps[step].title}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#9A9AAF",
|
||||
fontWeight: "400",
|
||||
marginTop: "4px",
|
||||
fontSize: "14px",
|
||||
lineHeight: "1",
|
||||
}}
|
||||
>
|
||||
Шаг {step + 1}
|
||||
</Typography>
|
||||
<Box sx={{ flexGrow: 1 }}>{steps[step].component}</Box>
|
||||
</Box>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
import { Box, Button, useTheme } from "@mui/material";
|
||||
import ArrowLeft from "@icons/questionsPage/arrowLeft";
|
||||
import { FC } from "react";
|
||||
|
||||
type StepButtonsBlockProps = {
|
||||
handlePrevStep: () => void;
|
||||
handleNextStep: () => void;
|
||||
};
|
||||
|
||||
export const StepButtonsBlock: FC<StepButtonsBlockProps> = ({
|
||||
handlePrevStep,
|
||||
handleNextStep,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
marginTop: "auto",
|
||||
marginLeft: "auto",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}
|
||||
data-cy="back-button"
|
||||
onClick={handlePrevStep}
|
||||
>
|
||||
<ArrowLeft color={theme.palette.brightPurple.main} />
|
||||
</Button>
|
||||
<Button
|
||||
data-cy="next-step"
|
||||
variant="contained"
|
||||
sx={{
|
||||
height: "44px",
|
||||
padding: "10px 20px",
|
||||
borderRadius: "8px",
|
||||
background: theme.palette.brightPurple.main,
|
||||
fontSize: "18px",
|
||||
}}
|
||||
onClick={handleNextStep}
|
||||
>
|
||||
Далее
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@ -22,8 +22,8 @@ export const IntegrationsPage = ({
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(660));
|
||||
const [step, setStep] = useState<number>(0);
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
const [companyName, setCompanyName] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (editQuizId === null) navigate("/list");
|
||||
@ -47,6 +47,14 @@ export const IntegrationsPage = ({
|
||||
return (
|
||||
<Skeleton sx={{ width: "100vw", height: "100vh", transform: "none" }} />
|
||||
);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setIsModalOpen(false);
|
||||
setTimeout(() => {
|
||||
setCompanyName(null);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
@ -69,10 +77,12 @@ export const IntegrationsPage = ({
|
||||
<PartnersBoard
|
||||
partners={partnersMock}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
setCompanyName={setCompanyName}
|
||||
/>
|
||||
<IntegrationsModal
|
||||
isModalOpen={isModalOpen}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
handleCloseModal={handleCloseModal}
|
||||
companyName={companyName}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
@ -5,15 +5,18 @@ import { Partner } from "../PartnersBoard";
|
||||
type PartnerItemProps = {
|
||||
partner: Partner;
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
setCompanyName: (value: string) => void;
|
||||
};
|
||||
|
||||
export const PartnerItem: FC<PartnerItemProps> = ({
|
||||
partner,
|
||||
setIsModalOpen,
|
||||
setCompanyName,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const handleClick = () => {
|
||||
setCompanyName(partner.name);
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
|
||||
@ -11,11 +11,13 @@ export type Partner = {
|
||||
type PartnersBoardProps = {
|
||||
partners: Partner[];
|
||||
setIsModalOpen: (value: boolean) => void;
|
||||
setCompanyName: (value: string) => void;
|
||||
};
|
||||
|
||||
export const PartnersBoard: FC<PartnersBoardProps> = ({
|
||||
partners,
|
||||
setIsModalOpen,
|
||||
setCompanyName,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@ -60,6 +62,7 @@ export const PartnersBoard: FC<PartnersBoardProps> = ({
|
||||
key={partner.name}
|
||||
partner={partner}
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
setCompanyName={setCompanyName}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user