frontAnswerer/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx

415 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useRef, useState, } from "react";
import { Box, Button, Link, Typography, useTheme, } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox.tsx";
import { DESIGN_LIST } from "@utils/designList.ts";
import { sendFC, SendFCParams } from "@api/quizRelase.ts";
import { useQuizData } from "@contexts/QuizDataContext.ts";
import { NameplateLogo } from "@icons/NameplateLogo.tsx";
import { QuizQuestionResult } from "@model/questionTypes/result.ts";
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared.ts";
import { quizThemes } from "@utils/themes/Publication/themePublication.ts";
import { enqueueSnackbar } from "notistack";
import { useRootContainerSize } from "@contexts/RootContainerWidthContext.ts";
import {
FormContactFieldData,
FormContactFieldName,
} from "@model/settingsData.ts";
import {
Inputs
} from "@/components/ViewPublicationPage/ContactForm/Inputs/Inputs.tsx";
import { EMAIL_REGEXP } from "@utils/emailRegexp.tsx";
type Props = {
currentQuestion: AnyTypedQuizQuestion;
onShowResult: () => void;
};
export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
const theme = useTheme();
const { settings, questions, quizId, show_badge, preview } = useQuizData();
const [ready, setReady] = useState(false);
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [phone, setPhone] = useState("");
const [text, setText] = useState("");
const [adress, setAdress] = useState("");
const [screenHeight, setScreenHeight] = useState<number>(window.innerHeight);
const fireOnce = useRef(true);
const [fire, setFire] = useState(false);
const isMobile = useRootContainerSize() < 850;
const isTablet = useRootContainerSize() < 1000;
useEffect(() => {
function handleResize() {
setScreenHeight(window.innerHeight);
}
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
const resultQuestion =
currentQuestion.type === "result"
? currentQuestion
: questions.find((question): question is QuizQuestionResult => {
if (settings?.cfg.haveRoot) {
return (
question.type === "result" &&
question.content.rule.parentId === currentQuestion.content.id
);
} else {
return (
question.type === "result" &&
question.content.rule.parentId === "line"
);
}
});
if (!resultQuestion) throw new Error("Result question not found");
const inputHC = async () => {
const FC = settings.cfg.formContact.fields || settings.cfg.formContact;
const body: SendFCParams["body"] = {};
if (name.length > 0) body.name = name;
if (email.length > 0) body.email = email;
if (phone.length > 0) body.phone = phone;
if (adress.length > 0) body.address = adress;
if (text.length > 0) body.customs = { [FC.text.text || "Фамилия"]: text };
if (Object.keys(body).length > 0) {
try {
await sendFC({
questionId: currentQuestion.id,
body: body,
qid: quizId,
preview,
});
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
localStorage.setItem(
"sessions",
JSON.stringify({ ...sessions, [quizId]: new Date().getTime() })
);
} catch (e) {
enqueueSnackbar("ответ не был засчитан");
}
}
};
const FCcopy: Record<FormContactFieldName, FormContactFieldData> =
settings.cfg.formContact.fields || settings.cfg.formContact;
const filteredFC: Partial<
Record<FormContactFieldName, FormContactFieldData>
> = {};
for (const i in FCcopy) {
const field = FCcopy[i as keyof typeof FCcopy];
if (field.used) {
filteredFC[i as FormContactFieldName] = field;
}
}
async function handleShowResultsClick() {
const FC = settings.cfg.formContact.fields;
if (FC["email"].used !== EMAIL_REGEXP.test(email)) {
return enqueueSnackbar("введена некорректная почта");
}
if (fireOnce.current) {
if (
name.length === 0 &&
email.length === 0 &&
phone.length === 0 &&
text.length === 0 &&
adress.length === 0
)
return enqueueSnackbar("Пожалуйста, заполните поля");
//почта валидна, хоть одно поле заполнено
setFire(true);
try {
await inputHC();
fireOnce.current = false;
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
sessions[quizId] = Date.now();
localStorage.setItem("sessions", JSON.stringify(sessions));
//@ts-ignore
let YM = window?.ym;
//@ts-ignore
let VP = window?._tmr;
if (YM !== undefined && settings.cfg.yandexMetricNumber !== undefined) {
YM(
settings.cfg.yandexMetricNumber,
"reachGoal",
"penaquiz-contacts"
);
};
if (VP !== undefined && settings.cfg.vkMetricNumber !== undefined) {
VP.push({
type: "reachGoal",
id: settings.cfg.vkMetricNumber,
goal: "penaquiz-contacts"
});
};
} catch (e) {
enqueueSnackbar("повторите попытку позже");
}
if (settings.cfg.resultInfo.showResultForm === "after") {
onShowResult();
}
}
setFire(false);
}
useEffect(() => {
//@ts-ignore
let YM = window?.ym;
//@ts-ignore
let VP = window?._tmr;
if (YM !== undefined && settings.cfg.yandexMetricNumber !== undefined) {
YM(
settings.cfg.yandexMetricNumber,
"reachGoal",
"penaquiz-form"
);
};
if (VP !== undefined && settings.cfg.vkMetricNumber !== undefined) {
VP.push({
type: "reachGoal",
id: settings.cfg.vkMetricNumber,
goal: "penaquiz-form"
});
};
}, [])
return (
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.palette.background.default,
height: screenHeight > 500 ? "100%" : "auto",
overflow: "auto",
"&::-webkit-scrollbar": {
width: "0",
display: "none",
msOverflowStyle: "none",
},
scrollbarWidth: "none",
msOverflowStyle: "none",
backgroundPosition: "center",
backgroundSize: "cover",
backgroundImage:
settings.cfg.design && !isMobile
? quizThemes[settings.cfg.theme].isLight
? `url(${DESIGN_LIST[settings.cfg.theme]})`
: `linear-gradient(90deg, #272626, transparent), url(${DESIGN_LIST[settings.cfg.theme]
})`
: null,
}}
>
<Box
sx={{
width: !isMobile ? "100%" : isMobile ? undefined : "530px",
borderRadius: "4px",
height: isMobile ? "100%" : "auto",
minHeight: "100%",
display: isMobile ? undefined : "flex",
background:
settings.cfg.design && !isMobile
? undefined
: theme.palette.background.default,
}}
>
<Box
sx={{
width: isMobile ? undefined : "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
borderRight: isMobile ? undefined : "1px solid #9A9AAF80",
margin: isMobile ? 0 : "40px 0",
padding: isMobile ? "0" : "0 40px"
}}
>
<Box
sx={{
maxWidth: "630px",
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "center",
padding: isMobile ? "40px 20px 0 20px" : "0",
mt: isMobile ? 0 : isTablet ? "-180px" : "-47px",
}}
>
<Typography
sx={{
textAlign: isTablet ? undefined : "center",
fontSize: "24px",
lineHeight: "normal",
fontWeight: 501,
color: theme.palette.text.primary,
wordBreak: "break-word",
}}
>
{settings.cfg.formContact.title ||
"Заполните форму, чтобы получить результаты теста"}
</Typography>
{settings.cfg.formContact.desc && (
<Typography
sx={{
color: theme.palette.text.primary,
m: "20px 0",
fontSize: "18px",
wordBreak: "break-word",
}}
>
{settings.cfg.formContact.desc}
</Typography>
)}
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: isMobile ? undefined : "center",
justifyContent: "center",
flexDirection: "column",
backgroundColor: theme.palette.background.default,
p: isMobile ? "0 20px" : isTablet ? "0px 40px 30px 60px" : "125px 60px 30px 60px",
}}
>
<Box
sx={{
display: "flex",
flexDirection: "column",
mt: isMobile ? "10px" : "20px",
mb: "20px"
}}
>
<Inputs
name={name}
setName={setName}
email={email}
setEmail={setEmail}
phone={phone}
setPhone={setPhone}
text={text}
setText={setText}
adress={adress}
setAdress={setAdress}
/>
</Box>
<Box
sx={{
display: "flex",
width: isMobile ? "300px" : "390px",
}}
>
<CustomCheckbox
label=""
handleChange={({ target }) => {
setReady(target.checked);
}}
checked={ready}
colorIcon={theme.palette.primary.main}
sx={{ marginRight: "0" }}
/>
<Typography sx={{ color: theme.palette.text.primary, lineHeight: "18.96px" }} fontSize={"16px"} >
С&ensp;
<Link href={"https://shub.pena.digital/ppdd"} target="_blank">
Положением об обработке персональных данных{" "}
</Link>
&ensp;и&ensp;
<Link
href={"https://shub.pena.digital/docs/privacy"}
target="_blank"
>
{" "}
Политикой конфиденциальности{" "}
</Link>
&ensp;ознакомлен
</Typography>
</Box>
{
// resultQuestion &&
// settings.cfg.resultInfo.when === "after" &&
<Button
disabled={!(ready && !fire)}
variant="contained"
onClick={handleShowResultsClick}
sx={{
border: `1px solid ${theme.palette.primary.main}`,
margin: isMobile ? "auto" : undefined,
mt: "20px",
p: "10px 20px",
"&:disabled": {
border: "1px solid #9A9AAF",
color: "#9A9AAF",
},
}}
>
{settings.cfg.formContact?.button || "Получить результаты"}
</Button>
}
{show_badge && (
<Box
component={Link}
target={"_blank"}
href={`https://${window.location.hostname.includes("s") ? "s" : ""
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
sx={{
display: "flex",
alignItems: "center",
mt: "55px",
mb: "40px",
gap: "10px",
textDecoration: "none",
position: "absolute",
bottom: 0,
left: isMobile ? "28%" : undefined
}}
>
<NameplateLogo
style={{
fontSize: "20px",
color: quizThemes[settings.cfg.theme].isLight
? "#151515"
: "#FFFFFF",
}}
/>
{/*<Typography*/}
{/* sx={{*/}
{/* fontSize: "14px",*/}
{/* color: quizThemes[settings.cfg.theme].isLight*/}
{/* ? "#4D4D4D"*/}
{/* : "#F5F7FF",*/}
{/* whiteSpace: "nowrap",*/}
{/* }}*/}
{/*>*/}
{/* Сделано на PenaQuiz*/}
{/*</Typography>*/}
</Box>
)}
</Box>
</Box>
</Box>
);
};