461 lines
16 KiB
TypeScript
461 lines
16 KiB
TypeScript
import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon";
|
||
import { Box, IconButton, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||
import { FC, MouseEvent, useState } from "react";
|
||
import { ContactIcon } from "../icons/ContactIcon";
|
||
import { MessageIcon } from "../icons/MessageIcon";
|
||
import { PhoneIcon } from "../icons/PhoneIcon";
|
||
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||
|
||
import { deleteResult, obsolescenceResult } from "@root/results/actions";
|
||
import { IAnswerResult, resultApi } from "@api/result";
|
||
import { useQuizStore } from "@root/quizes/store";
|
||
import { useQuestionsStore } from "@root/questions/store";
|
||
import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
|
||
|
||
import { DeleteModal } from "../DeleteModal";
|
||
|
||
import type { AnyTypedQuizQuestion } from "@frontend/squzanswerer";
|
||
import { useCurrentQuiz } from "@/stores/quizes/hooks";
|
||
import { ListOfOptionsCardAnswer } from "./ListOfOptionsCardAnswer";
|
||
import { ListOfImagesCardAnswer } from "./ListOfImagesCardAnswer";
|
||
|
||
import { timewebContentFile, timewebContent } from "./helper"
|
||
|
||
interface CardAnswerProps {
|
||
isNew: boolean;
|
||
idResult: number;
|
||
dayResult: string;
|
||
timeResult: string;
|
||
name?: string;
|
||
phone?: string;
|
||
email?: string;
|
||
address?: string;
|
||
openPrePaymentModal: () => void;
|
||
}
|
||
|
||
export const CardAnswer: FC<CardAnswerProps> = ({
|
||
name,
|
||
phone,
|
||
email,
|
||
address,
|
||
isNew = true,
|
||
idResult,
|
||
timeResult,
|
||
dayResult,
|
||
openPrePaymentModal,
|
||
}) => {
|
||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||
const [openDelete, setOpenDelete] = useState<boolean>(false);
|
||
const theme = useTheme();
|
||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||
const [resultsAnswer, setResultsAnswer] = useState<IAnswerResult[]>([]);
|
||
const [questionsResultState, setQuestionsResultState] = useState<AnyTypedQuizQuestion[]>([]);
|
||
const { editQuizId } = useQuizStore();
|
||
const { questions } = useQuestionsStore();
|
||
const quiz = useCurrentQuiz();
|
||
const openResults = async () => {
|
||
setIsOpen(!isOpen);
|
||
if (!isOpen) {
|
||
const [resAnswer, answerError] = await resultApi.getAnswerList(idResult);
|
||
|
||
if (answerError || !resAnswer) {
|
||
if (answerError?.includes("Payment Required")) {
|
||
openPrePaymentModal();
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
const resAnswerOnly = resAnswer.filter((res) => res.Result !== true);
|
||
const resQuiz = resAnswer.filter((res) => res.Result === true);
|
||
setResultsAnswer(resAnswerOnly);
|
||
const idResults = resQuiz[0].question_id;
|
||
const questionsResult = questions.filter((q) => q.type && q.backendId === idResults) as AnyTypedQuizQuestion[];
|
||
|
||
setQuestionsResultState(questionsResult);
|
||
}
|
||
};
|
||
|
||
const onClickDelete = (e: MouseEvent) => {
|
||
e.stopPropagation();
|
||
setOpenDelete(true);
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Box
|
||
onClick={() => {
|
||
if (editQuizId !== null) {
|
||
obsolescenceResult(idResult, editQuizId);
|
||
openResults();
|
||
}
|
||
}}
|
||
sx={{
|
||
borderRadius: "12px",
|
||
maxWidth: isTablet ? "450px" : "auto",
|
||
width: "100%",
|
||
boxShadow:
|
||
"0px 2.767px 8.551px 0px rgba(210, 208, 225, 0.07), 0px 6.65px 20.549px 0px rgba(210, 208, 225, 0.10), 0px 12.522px 38.692px 0px rgba(210, 208, 225, 0.12), 0px 22.336px 69.019px 0px rgba(210, 208, 225, 0.14), 0px 41.778px 129.093px 0px rgba(210, 208, 225, 0.17), 0px 100px 309px 0px rgba(210, 208, 225, 0.24)",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
width: "100%",
|
||
display: "flex",
|
||
justifyContent: "space-between",
|
||
flexDirection: isTablet ? "column" : "-moz-initial",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
flexDirection: isTablet ? "column" : "-moz-initial",
|
||
cursor: "pointer",
|
||
p: "20px",
|
||
borderRadius: isTablet ? "12px 12px 0 0" : isOpen ? "12px 0 0 0" : "12px 0 0 12px",
|
||
display: "flex",
|
||
alignItems: "flex-start",
|
||
background: "#FFF",
|
||
width: "100%",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
width: isTablet ? "100%" : "auto",
|
||
display: "flex",
|
||
alignItems: "flex-start",
|
||
flexDirection: isTablet ? "row-reverse" : "-moz-initial",
|
||
justifyContent: isTablet ? "space-between" : "-moz-initial",
|
||
pb: isTablet ? "20px" : "0",
|
||
mb: isTablet ? "20px" : "0",
|
||
borderBottom: isTablet ? "1px solid rgba(154, 154, 175, 0.50)" : "0",
|
||
}}
|
||
>
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: "6px" }}>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
width: "30px",
|
||
height: "30px",
|
||
borderRadius: "50%",
|
||
background: "#EEE4FC",
|
||
color: "#7E2AEA",
|
||
}}
|
||
>
|
||
{idResult}
|
||
</Box>
|
||
<IconButton onClick={openResults}>
|
||
<ArrowDownIcon
|
||
style={{
|
||
transform: isOpen ? "rotate(180deg)" : "rotate(360deg)",
|
||
}}
|
||
fontSize="10px"
|
||
/>
|
||
</IconButton>
|
||
</Box>
|
||
|
||
<Typography
|
||
sx={{
|
||
ml: isTablet ? "0" : "50px",
|
||
mr: isTablet ? "0" : "188px",
|
||
fontSize: "18px",
|
||
color: "#7E2AEA",
|
||
maxWidth: "143px",
|
||
width: "100%",
|
||
}}
|
||
>
|
||
{dayResult} в {timeResult}
|
||
</Typography>
|
||
</Box>
|
||
|
||
<Box sx={{ display: "flex", flexDirection: "column", gap: "10px" }}>
|
||
{name && (
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||
<ContactIcon />
|
||
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>{name}</Typography>
|
||
</Box>
|
||
)}
|
||
{email && (
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||
<MessageIcon />
|
||
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>{email}</Typography>
|
||
</Box>
|
||
)}
|
||
{phone && (
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||
<PhoneIcon />
|
||
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>{phone}</Typography>
|
||
</Box>
|
||
)}
|
||
{address && (
|
||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||
<AddressIcon color={"#9A9AAF"} />
|
||
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>{address}</Typography>
|
||
</Box>
|
||
)}
|
||
</Box>
|
||
|
||
{!isTablet && isNew && (
|
||
<Typography
|
||
sx={{
|
||
ml: "auto",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
background: "#FB5607",
|
||
borderRadius: "8px",
|
||
width: "77px",
|
||
height: "36px",
|
||
color: "white",
|
||
}}
|
||
>
|
||
Новая
|
||
</Typography>
|
||
)}
|
||
</Box>
|
||
|
||
<Box
|
||
sx={{
|
||
borderRadius: "8px",
|
||
p: isTablet ? "20px" : "0",
|
||
cursor: "pointer",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: isTablet ? "space-between" : "center",
|
||
width: isTablet ? "100%" : "100px",
|
||
background: "#F2F3F7",
|
||
}}
|
||
>
|
||
{isTablet && isNew ? (
|
||
<>
|
||
<Typography
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
background: "#FB5607",
|
||
borderRadius: "8px",
|
||
width: "77px",
|
||
height: "36px",
|
||
color: "white",
|
||
}}
|
||
>
|
||
Новая
|
||
</Typography>
|
||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||
<IconButton onClick={onClickDelete}>
|
||
<DeleteIcon
|
||
color="#4D4D4D"
|
||
fontSize="34px"
|
||
/>
|
||
</IconButton>
|
||
</Box>
|
||
</>
|
||
) : (
|
||
<IconButton onClick={onClickDelete}>
|
||
<DeleteIcon
|
||
color="#4D4D4D"
|
||
fontSize="34px"
|
||
/>
|
||
</IconButton>
|
||
)}
|
||
</Box>
|
||
</Box>
|
||
|
||
{isOpen && (
|
||
<Box
|
||
sx={{
|
||
borderRadius: "12px",
|
||
maxWidth: isTablet ? "450px" : "auto",
|
||
width: "100%",
|
||
boxShadow:
|
||
"0px 2.767px 8.551px 0px rgba(210, 208, 225, 0.07), 0px 6.65px 20.549px 0px rgba(210, 208, 225, 0.10), 0px 12.522px 38.692px 0px rgba(210, 208, 225, 0.12), 0px 22.336px 69.019px 0px rgba(210, 208, 225, 0.14), 0px 41.778px 129.093px 0px rgba(210, 208, 225, 0.17), 0px 100px 309px 0px rgba(210, 208, 225, 0.24)",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
p: "20px",
|
||
borderTop: "1px solid #F1F2F6",
|
||
background: "#FFF",
|
||
borderRadius: "0 0 12px 12px",
|
||
}}
|
||
>
|
||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>Ответы</Typography>
|
||
</Box>
|
||
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
gap: isTablet ? "0" : "149px",
|
||
p: "20px",
|
||
flexDirection: isTablet ? "column" : "-moz-initial",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
gap: "15px",
|
||
mt: "20px",
|
||
}}
|
||
>
|
||
{resultsAnswer.map((answer, id) => {
|
||
let titleQuestion;
|
||
let typeOuestion;
|
||
let typeQuestionFile;
|
||
let qid
|
||
let quest = questions; //массив с вопросами
|
||
let i;
|
||
let idAnswer = answer.question_id; //айди вопроса у ответа
|
||
for (i in quest) {
|
||
if (quest[i].backendId === idAnswer) {
|
||
titleQuestion = quest[i].title;
|
||
typeOuestion = quest[i].type;
|
||
typeQuestionFile = quest[i].content.type;
|
||
qid = quest[i].backendId
|
||
}
|
||
}
|
||
if (answer?.Version !== undefined) {
|
||
if (typeOuestion === "variant" || typeOuestion === "emoji") return (
|
||
<ListOfOptionsCardAnswer
|
||
title={titleQuestion || ""}
|
||
answer={answer.content}
|
||
id={id}
|
||
/>
|
||
)
|
||
if (typeOuestion === "varimg" || typeOuestion === "images" && answer.content.includes("Image")) return (
|
||
<ListOfImagesCardAnswer
|
||
title={titleQuestion || ""}
|
||
answer={answer.content}
|
||
id={id}
|
||
quizId={quiz?.id}
|
||
questionId={qid}
|
||
/>
|
||
)
|
||
|
||
}
|
||
|
||
return (
|
||
<Box
|
||
key={answer.id}
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
gap: "13px",
|
||
}}
|
||
onClick={(e) => e.stopPropagation()}
|
||
>
|
||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||
{id + 1}. {titleQuestion}.
|
||
</Typography>
|
||
{typeOuestion === "file" && answer.content && (
|
||
<Link
|
||
download
|
||
href={timewebContentFile(quiz?.qid, answer.content, qid)}
|
||
style={{
|
||
color: "#7E2AEA",
|
||
display: "flex",
|
||
gap: "10px",
|
||
}}
|
||
>
|
||
{typeQuestionFile === "video" && answer.content && (
|
||
<video
|
||
src={timewebContentFile(quiz?.qid, answer.content, qid)}
|
||
width={40}
|
||
height={40}
|
||
></video>
|
||
)}
|
||
{typeQuestionFile === "picture" && answer.content && (
|
||
<img
|
||
src={timewebContentFile(quiz?.qid, answer.content, qid)}
|
||
width={40}
|
||
height={40}
|
||
/>
|
||
)}
|
||
клик для скачивания
|
||
</Link>
|
||
)}
|
||
{(typeOuestion === "images" || typeOuestion === "varimg") && answer.content && (
|
||
<>
|
||
<img
|
||
width={40}
|
||
height={40}
|
||
src={timewebContent(quiz?.qid, answer.content, qid)}
|
||
/>
|
||
|
||
{/* <Typography sx={{ fontSize: "18px" }}>{answer.content.split("<")[0]}</Typography> */}
|
||
</>
|
||
)}
|
||
{!(typeOuestion === "file" || typeOuestion === "images" || typeOuestion === "varimg") && (
|
||
<Typography sx={{ fontSize: "18px" }}>{answer.content}</Typography>
|
||
)}
|
||
|
||
</Box>
|
||
);
|
||
})}
|
||
</Box>
|
||
</Box>
|
||
|
||
<Box
|
||
sx={{
|
||
p: "20px",
|
||
borderTop: "1px solid #F1F2F6",
|
||
background: "#FFF",
|
||
borderRadius: "0 0 12px 12px",
|
||
}}
|
||
>
|
||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>Результаты</Typography>
|
||
</Box>
|
||
{questionsResultState.map((res) => {
|
||
return (
|
||
<Box
|
||
key={res.id}
|
||
sx={{
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
gap: "15px",
|
||
p: "20px",
|
||
}}
|
||
>
|
||
<Typography
|
||
sx={{
|
||
fontSize: "18px",
|
||
fontWeight: "500",
|
||
wordBreak: "break-word",
|
||
}}
|
||
>
|
||
{res.description}
|
||
</Typography>
|
||
<Typography sx={{ fontSize: "18px", wordBreak: "break-word" }}>{res.title}</Typography>
|
||
{res.content.useImage && res.content.back && res.content.back !== " " && (
|
||
<img
|
||
src={res.content.back}
|
||
style={{ width: "40px", height: "40px" }}
|
||
alt={""}
|
||
/>
|
||
)}
|
||
{!res.content.useImage && res.content.back && res.content.back !== " " && (
|
||
<video
|
||
src={res.content.back}
|
||
style={{ width: "40px", height: "40px" }}
|
||
></video>
|
||
)}
|
||
</Box>
|
||
);
|
||
})}
|
||
</Box>
|
||
)}
|
||
</Box>
|
||
<DeleteModal
|
||
openDelete={openDelete}
|
||
handleClose={() => setOpenDelete(false)}
|
||
onClick={() => {
|
||
deleteResult(Number(idResult));
|
||
setOpenDelete(false);
|
||
}}
|
||
/>
|
||
</>
|
||
);
|
||
};
|