frontPanel/src/pages/ResultPage/cards/ResultCard.tsx

551 lines
18 KiB
TypeScript
Raw Normal View History

2024-01-10 16:53:37 +00:00
import { useState, useEffect } from "react";
2023-12-26 13:46:54 +00:00
import {
getQuestionByContentId,
updateQuestion,
} from "@root/questions/actions";
2024-01-10 16:53:37 +00:00
import { useCurrentQuiz } from "@root/quizes/hooks";
import CustomTextField from "@ui_kit/CustomTextField";
import {
Box,
IconButton,
Paper,
Button,
Typography,
TextField,
useMediaQuery,
useTheme,
FormControl,
2023-12-20 20:25:58 +00:00
Popover,
} from "@mui/material";
import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
import ExpandLessIconBG from "@icons/ExpandLessIconBG";
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
import Trash from "@icons/trash";
import Info from "@icons/Info";
import SettingIcon from "@icons/questionsPage/settingIcon";
2023-12-20 20:25:58 +00:00
import { MediaSelectionAndDisplay } from "@ui_kit/MediaSelectionAndDisplay";
2024-01-10 16:53:37 +00:00
import type { MouseEvent } from "react";
import type { QuizQuestionResult } from "@model/questionTypes/result";
interface Props {
resultContract: boolean;
resultData: QuizQuestionResult;
}
2023-12-26 13:46:54 +00:00
export const checkEmptyData = ({
resultData,
}: {
resultData: QuizQuestionResult;
}) => {
2023-12-20 20:25:58 +00:00
let check = true;
if (
2023-12-29 14:06:53 +00:00
resultData.title?.length > 0 ||
resultData.description?.length > 0 ||
resultData.content.back?.length > 0 ||
resultData.content.originalBack?.length > 0 ||
resultData.content.innerName?.length > 0 ||
resultData.content.text?.length > 0 ||
resultData.content.video?.length > 0 ||
resultData.content.hint.text?.length > 0
2023-12-20 20:25:58 +00:00
)
check = false;
return check;
};
const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => {
2023-12-20 20:25:58 +00:00
const checkEmpty = checkEmptyData({ resultData });
const question = getQuestionByContentId(resultData.content.rule.parentId);
2024-01-10 16:53:37 +00:00
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
2024-01-10 16:53:37 +00:00
const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
2023-12-20 20:25:58 +00:00
const id = open ? "simple-popover" : undefined;
return (
<>
<Info
sx={{
"MuiIconButton-root": {
2023-12-20 20:25:58 +00:00
boxShadow: "0 0 10px 10px red",
},
}}
className={checkEmpty ? "blink" : ""}
onClick={handleClick}
/>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
2023-12-20 20:25:58 +00:00
vertical: "bottom",
horizontal: "left",
}}
>
<Paper
sx={{
2023-12-20 20:25:58 +00:00
p: "20px",
display: "flex",
justifyContent: "center",
alignItems: "center",
2023-12-20 20:25:58 +00:00
flexDirection: "column",
}}
>
<Typography>
2023-12-20 20:25:58 +00:00
{resultData?.content.rule.parentId === "line"
? "Единый результат в конце прохождения опроса без ветвления"
2023-12-26 13:46:54 +00:00
: `Заголовок вопроса, после которого появится результат: "${
question?.title || "нет заголовка"
}"`}
</Typography>
2023-12-26 13:46:54 +00:00
{checkEmpty && (
<Typography color="red">
Вы не заполнили этот результат никакими данными
</Typography>
)}
</Paper>
</Popover>
</>
2023-12-20 20:25:58 +00:00
);
};
export const ResultCard = ({ resultContract, resultData }: Props) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isTablet = useMediaQuery(theme.breakpoints.down(800));
2024-01-10 16:53:37 +00:00
const [expand, setExpand] = useState(true);
const [resultCardSettings, setResultCardSettings] = useState(false);
const [buttonPlus, setButtonPlus] = useState(true);
const [inputValue, setInputValue] = useState(resultData.content.text);
2023-12-26 13:46:54 +00:00
const question = getQuestionByContentId(resultData.content.rule.parentId);
2024-01-10 16:53:37 +00:00
const quiz = useCurrentQuiz();
2024-01-10 16:53:37 +00:00
useEffect(() => {
if (
resultData.content.hint.text ||
(quiz?.config.resultInfo.showResultForm === "after" &&
resultData.content.redirect)
) {
setButtonPlus(false);
}
}, []);
useEffect(() => {
2023-12-20 20:25:58 +00:00
setExpand(true);
}, [resultContract]);
return (
<Paper
data-cy="quiz-question-card"
sx={{
maxWidth: "796px",
width: "100%",
borderRadius: "12px",
backgroundColor: expand ? "white" : "#EEE4FC",
border: expand ? "none" : "1px solid #9A9AAF",
boxShadow: "0px 10px 30px #e7e7e7",
2023-12-20 20:25:58 +00:00
m: "20px 0",
}}
>
2023-12-26 13:46:54 +00:00
<Typography sx={{ color: theme.palette.grey2.main, padding: "5px 20px" }}>
{resultData?.content.rule.parentId === "line"
? "Единый результат в конце прохождения опроса без ветвления"
2023-12-26 13:46:54 +00:00
: `Заголовок вопроса, после которого появится результат: "${
question?.title || "нет заголовка"
}"`}
</Typography>
<Box
sx={{
display: expand ? "none" : "flex",
alignItems: "center",
2023-12-26 13:46:54 +00:00
padding: isMobile ? "10px" : "0 20px 20px",
// flexDirection: isMobile ? "column" : null,
justifyContent: "space-between",
minHeight: "40px",
}}
>
<FormControl
variant="standard"
sx={{
p: 0,
maxWidth: isTablet ? "549px" : "640px",
width: "100%",
marginRight: isMobile ? "0px" : "16.1px",
}}
>
<CustomTextField
value={resultData.title}
placeholder={"Заголовок результата"}
2024-02-16 23:41:38 +00:00
maxLength={200}
2023-12-20 20:25:58 +00:00
onChange={({ target }: { target: HTMLInputElement }) =>
2023-12-26 13:46:54 +00:00
updateQuestion(
resultData.id,
2023-12-31 02:53:25 +00:00
(question) => (question.title = target.value),
2023-12-26 13:46:54 +00:00
)
2023-12-20 20:25:58 +00:00
}
sx={{
margin: isMobile ? "10px 0" : 0,
backgroundColor: expand
? theme.palette.background.default
: "transparent",
height: "48px",
borderRadius: "10px",
borderWidth: "1px !important",
border: !expand ? "none" : null,
"&::placeholder": {
color: "#4D4D4D",
opacity: 0.8,
},
}}
/>
</FormControl>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
width: "auto",
position: "relative",
}}
>
<IconButton
sx={{ padding: "0", margin: "5px" }}
disableRipple
data-cy="expand-question"
onClick={() => setExpand(!expand)}
>
{expand ? (
<ExpandLessIconBG />
) : (
<ExpandLessIcon
sx={{
boxSizing: "border-box",
fill: theme.palette.brightPurple.main,
background: "#FFF",
borderRadius: "6px",
height: "30px",
width: "30px",
}}
/>
)}
</IconButton>
<InfoView resultData={resultData} />
</Box>
</Box>
{expand && (
<>
<Box
sx={{
overflow: "hidden",
maxWidth: "796px",
height: "100%",
bgcolor: "#FFFFFF",
borderRadius: "12px",
boxShadow: "0px 10px 30px #e7e7e7",
}}
>
2023-12-26 13:46:54 +00:00
<Box sx={{ p: "0 20px", pt: "10px" }}>
<Box
sx={{
width: "100%",
maxWidth: "760px",
display: "flex",
alignItems: "center",
gap: "10px",
mb: "19px",
}}
>
<CustomTextField
id="headline-is-bolder"
value={resultData.description}
onChange={({ target }: { target: HTMLInputElement }) =>
updateQuestion(
resultData.id,
(question) => (question.description = target.value),
)
}
placeholder={"Заголовок пожирнее"}
2024-02-16 23:41:38 +00:00
maxLength={200}
sx={{
borderRadius: "8px",
height: "48px",
width: "100%",
}}
/>
<IconButton
sx={{ padding: "0", margin: "5px" }}
disableRipple
data-cy="expand-question"
onClick={() => setExpand(!expand)}
>
<ExpandLessIconBG />
</IconButton>
<InfoView resultData={resultData} />
</Box>
<Box
sx={{
2023-12-20 20:25:58 +00:00
margin: "20px 0",
}}
>
<CustomTextField
id="heading-result"
value={resultData.title}
placeholder={"Заголовок результата"}
2024-02-16 23:41:38 +00:00
maxLength={200}
onChange={({ target }: { target: HTMLInputElement }) =>
updateQuestion(
resultData.id,
(question) => (question.title = target.value),
)
}
/>
</Box>
<TextField
2024-01-18 15:18:32 +00:00
id="heading-description"
value={inputValue}
onChange={({ target }: { target: HTMLInputElement }) => {
if (target.value.length <= 3000) {
setInputValue(target.value);
}
2023-12-26 13:46:54 +00:00
updateQuestion(
resultData.id,
(question) => (question.content.text = target.value),
);
}}
fullWidth
placeholder="Описание"
multiline
rows={4}
sx={{
"& .MuiInputBase-root": {
backgroundColor: "#F2F3F7",
width: "100%",
height: "110px",
borderRadius: "10px",
},
}}
inputProps={{
sx: {
height: "85px",
borderRadius: "10px",
fontSize: "18px",
lineHeight: "21px",
py: 0,
},
}}
/>
2023-12-20 20:25:58 +00:00
<MediaSelectionAndDisplay resultData={resultData} />
2023-12-20 20:25:58 +00:00
{buttonPlus ? (
<Button
2024-01-18 15:18:32 +00:00
data-cy="add-button"
2023-12-20 20:25:58 +00:00
onClick={() => {
setButtonPlus(false);
}}
sx={{
2023-12-20 20:25:58 +00:00
display: "inline flex",
height: "48px",
padding: "10px 20px",
justifyContent: "center",
alignItems: "center",
gap: "8px",
flexShrink: 0,
borderRadius: "8px",
border: "1px solid #9A9AAF",
background: " #F2F3F7",
color: "#9A9AAF",
my: "30px",
}}
>
2023-12-20 20:25:58 +00:00
Кнопка +
</Button>
) : (
<Box
sx={{
2024-01-04 21:42:05 +00:00
my: "30px",
}}
>
2023-12-20 20:25:58 +00:00
<Box>
2023-12-26 13:46:54 +00:00
<Typography
component={"span"}
sx={{ weight: "500", fontSize: "18px", mb: "10px" }}
>
2023-12-20 20:25:58 +00:00
Призыв к действию
</Typography>
<IconButton
onClick={() => {
setButtonPlus(true);
2023-12-26 13:46:54 +00:00
updateQuestion(
resultData.id,
2023-12-31 02:53:25 +00:00
(q) => (q.content.hint.text = ""),
2023-12-26 13:46:54 +00:00
);
}}
2023-12-20 20:25:58 +00:00
>
<Trash />
</IconButton>
</Box>
<CustomTextField
2024-01-18 15:18:32 +00:00
id="button-text-result"
2023-12-20 20:25:58 +00:00
value={resultData.content.hint.text}
onChange={({ target }: { target: HTMLInputElement }) =>
2024-01-10 16:53:37 +00:00
updateQuestion(resultData.id, (question) => {
question.content.hint.text = target.value;
})
2023-12-20 20:25:58 +00:00
}
maxLength={19}
2023-12-20 20:25:58 +00:00
placeholder="Например: узнать подробнее"
sx={{
2023-12-20 20:25:58 +00:00
"& .MuiInputBase-root": {
backgroundColor: "#F2F3F7",
width: isMobile ? undefined : "409px",
2023-12-20 20:25:58 +00:00
height: "48px",
borderRadius: "8px",
},
}}
2023-12-20 20:25:58 +00:00
inputProps={{
sx: {
height: "85px",
borderRadius: "10px",
fontSize: "18px",
lineHeight: "21px",
py: 0,
},
}}
2023-12-20 20:25:58 +00:00
/>
2024-01-10 16:53:37 +00:00
{quiz?.config.resultInfo.showResultForm === "after" && (
<>
<Typography
sx={{
weight: "500",
fontSize: "18px",
margin: "10px 0",
}}
>
Cсылка для кнопки
</Typography>
<CustomTextField
2024-01-18 15:18:32 +00:00
id="link-page-result"
2024-01-10 16:53:37 +00:00
value={resultData.content.redirect}
onChange={({ target }: { target: HTMLInputElement }) =>
updateQuestion<QuizQuestionResult>(
resultData.id,
(question) => {
question.content.redirect = target.value;
},
)
}
placeholder="https://penahub.ru"
2024-02-16 23:41:38 +00:00
maxLength={200}
2024-01-10 16:53:37 +00:00
sx={{
"& .MuiInputBase-root": {
backgroundColor: "#F2F3F7",
width: isMobile ? undefined : "409px",
height: "48px",
borderRadius: "8px",
},
}}
inputProps={{
sx: {
height: "85px",
borderRadius: "10px",
fontSize: "18px",
lineHeight: "21px",
py: 0,
},
}}
/>
</>
)}
2023-12-20 20:25:58 +00:00
</Box>
)}
</Box>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
width: "100%",
background: "#F2F3F7",
}}
>
{/*<Box*/}
{/* sx={{*/}
{/* padding: "20px",*/}
{/* display: "flex",*/}
{/* flexWrap: "wrap",*/}
{/* gap: "10px",*/}
{/* }}*/}
{/*>*/}
{/* <MiniButtonSetting*/}
{/* onClick={() => {*/}
{/* setResultCardSettings(!resultCardSettings);*/}
{/* }}*/}
{/* sx={{*/}
{/* backgroundColor: resultCardSettings*/}
{/* ? theme.palette.brightPurple.main*/}
{/* : "transparent",*/}
{/* color: resultCardSettings*/}
{/* ? "#ffffff"*/}
{/* : theme.palette.grey3.main,*/}
{/* "&:hover": {*/}
{/* backgroundColor: resultCardSettings*/}
{/* ? "#581CA7"*/}
{/* : "#7E2AEA",*/}
{/* color: "white",*/}
{/* },*/}
{/* }}*/}
{/* >*/}
{/* <SettingIcon*/}
{/* color={*/}
{/* resultCardSettings ? "#ffffff" : theme.palette.grey3.main*/}
{/* }*/}
{/* />*/}
{/* {!isTablet && "Настройки"}*/}
{/* </MiniButtonSetting>*/}
{/*</Box>*/}
</Box>
</Box>
{/*{resultCardSettings && (*/}
{/* <Box*/}
{/* sx={{*/}
{/* backgroundColor: "white",*/}
{/* p: "20px",*/}
{/* borderRadius: "0 0 12px 12px",*/}
{/* }}*/}
{/* >*/}
{/* <CustomTextField*/}
{/* placeholder={"Внутреннее описание вопроса"}*/}
{/* value={resultData.innerName}*/}
{/* onChange={({ target }: { target: HTMLInputElement }) =>*/}
{/* updateQuestion(*/}
{/* resultData.id,*/}
{/* (question) => (question.content.innerName = target.value)*/}
{/* )*/}
{/* }*/}
{/* />*/}
{/* </Box>*/}
{/*)}*/}
</>
2023-12-20 20:25:58 +00:00
)}
</Paper>
);
};