frontPanel/src/pages/Questions/DraggableList/QuestionPageCard.tsx

306 lines
11 KiB
TypeScript
Raw Normal View History

2023-09-20 12:42:14 +00:00
import { useState, useRef } from "react";
2023-09-06 13:20:12 +00:00
import { useParams } from "react-router-dom";
2023-08-08 11:01:37 +00:00
import {
Box,
Checkbox,
FormControl,
2023-08-08 11:01:37 +00:00
FormControlLabel,
IconButton,
InputAdornment,
2023-08-08 11:01:37 +00:00
Paper,
TextField,
2023-09-15 12:37:12 +00:00
useMediaQuery,
2023-08-08 11:01:37 +00:00
useTheme,
} from "@mui/material";
2023-09-20 09:07:33 +00:00
import { useDebouncedCallback } from "use-debounce";
2023-09-20 12:42:14 +00:00
import { ChooseAnswerModal } from "./ChooseAnswerModal";
2023-08-11 07:25:28 +00:00
import TypeQuestions from "../TypeQuestions";
import SwitchQuestionsPage from "../SwitchQuestionsPage";
2023-09-25 13:43:15 +00:00
import { questionStore, updateQuestionsList, createQuestion, copyQuestion, removeQuestion } from "@root/questions";
2023-08-11 07:25:28 +00:00
2023-08-08 11:01:37 +00:00
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
2023-09-25 13:43:15 +00:00
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import { OneIcon } from "@icons/questionsPage/OneIcon";
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
import { CopyIcon } from "@icons/questionsPage/CopyIcon";
import CrossedEyeIcon from "@icons/CrossedEyeIcon";
2023-09-25 13:43:15 +00:00
import { HideIcon } from "@icons/questionsPage/hideIcon";
import Answer from "@icons/questionsPage/answer";
import OptionsPict from "@icons/questionsPage/options_pict";
import OptionsAndPict from "@icons/questionsPage/options_and_pict";
import Emoji from "@icons/questionsPage/emoji";
import Input from "@icons/questionsPage/input";
import DropDown from "@icons/questionsPage/drop_down";
import Date from "@icons/questionsPage/date";
import Slider from "@icons/questionsPage/slider";
import Download from "@icons/questionsPage/download";
import Page from "@icons/questionsPage/page";
import RatingIcon from "@icons/questionsPage/rating";
2023-09-13 10:58:07 +00:00
import { ReactComponent as PlusIcon } from "../../../assets/icons/plus.svg";
2023-08-08 11:01:37 +00:00
import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
2023-09-25 13:43:15 +00:00
import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon";
2023-08-08 11:01:37 +00:00
interface Props {
2023-08-08 11:01:37 +00:00
totalIndex: number;
2023-08-11 07:25:28 +00:00
draggableProps: DraggableProvidedDragHandleProps | null | undefined;
2023-09-13 10:58:07 +00:00
isDragging: boolean;
}
const IconAndrom = (isExpanded: boolean, switchState: string) => {
switch (switchState) {
case "variant":
2023-09-25 13:43:15 +00:00
return <Answer color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "images":
2023-09-25 13:43:15 +00:00
return <OptionsPict color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "varimg":
2023-09-25 13:43:15 +00:00
return <OptionsAndPict color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "emoji":
2023-09-25 13:43:15 +00:00
return <Emoji color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "text":
2023-09-25 13:43:15 +00:00
return <Input color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "select":
2023-09-25 13:43:15 +00:00
return <DropDown color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "date":
2023-09-25 13:43:15 +00:00
return <Date color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "number":
2023-09-25 13:43:15 +00:00
return <Slider color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "file":
2023-09-25 13:43:15 +00:00
return <Download color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "page":
2023-09-25 13:43:15 +00:00
return <Page color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
case "rating":
2023-09-25 13:43:15 +00:00
return <RatingIcon color={isExpanded ? "#9A9AAF" : "white"} sx={{ height: "22px", width: "20px" }} />;
default:
return <></>;
}
};
2023-09-25 13:43:15 +00:00
export default function QuestionsPageCard({ totalIndex, draggableProps, isDragging }: Props) {
2023-09-13 10:58:07 +00:00
const [plusVisible, setPlusVisible] = useState<boolean>(false);
2023-09-20 12:42:14 +00:00
const [open, setOpen] = useState<boolean>(false);
2023-09-06 13:20:12 +00:00
const quizId = Number(useParams().quizId);
2023-08-08 11:01:37 +00:00
const theme = useTheme();
2023-09-15 12:37:12 +00:00
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const { listQuestions } = questionStore();
2023-09-25 13:43:15 +00:00
const { type: switchState, expanded: isExpanded } = listQuestions[quizId][totalIndex];
2023-09-20 12:42:14 +00:00
const anchorRef = useRef(null);
2023-09-20 09:07:33 +00:00
const debounced = useDebouncedCallback((title) => {
updateQuestionsList(quizId, totalIndex, { title });
}, 1000);
2023-08-08 11:01:37 +00:00
return (
2023-09-13 10:58:07 +00:00
<>
<Paper
id={String(totalIndex)}
2023-08-11 07:25:28 +00:00
sx={{
2023-09-13 10:58:07 +00:00
maxWidth: "796px",
2023-08-11 07:25:28 +00:00
width: "100%",
2023-09-25 13:43:15 +00:00
borderRadius: "8px",
2023-09-13 10:58:07 +00:00
backgroundColor: isExpanded ? "white" : "#333647",
2023-08-11 07:25:28 +00:00
}}
2023-08-08 11:01:37 +00:00
>
2023-09-13 10:58:07 +00:00
<Box
sx={{
display: "flex",
alignItems: "center",
2023-09-25 13:43:15 +00:00
justifyContent: "space-between",
padding: isTablet ? (isMobile ? "20px 20px 0px 20px" : "20px 10px 20px 20px ") : "20px 10px 20px 20px",
2023-09-15 12:37:12 +00:00
flexDirection: isMobile ? "column-reverse" : null,
2023-09-13 10:58:07 +00:00
}}
2023-08-18 07:48:16 +00:00
>
2023-09-15 12:37:12 +00:00
<FormControl
variant="standard"
2023-09-20 09:07:33 +00:00
sx={{
p: 0,
2023-09-25 13:43:15 +00:00
maxWidth: isTablet ? "549px" : "640px",
2023-09-20 09:07:33 +00:00
width: "100%",
}}
2023-09-15 12:37:12 +00:00
>
2023-09-13 10:58:07 +00:00
<TextField
2023-09-20 09:07:33 +00:00
defaultValue={listQuestions[quizId][totalIndex].title}
2023-09-13 10:58:07 +00:00
placeholder={"Заголовок вопроса"}
2023-09-20 09:07:33 +00:00
onChange={({ target }) => debounced(target.value)}
2023-09-13 10:58:07 +00:00
InputProps={{
2023-09-20 09:07:33 +00:00
startAdornment: (
2023-09-20 12:42:14 +00:00
<Box>
<InputAdornment
ref={anchorRef}
position="start"
sx={{ cursor: "pointer" }}
onClick={() => setOpen((isOpened) => !isOpened)}
>
{IconAndrom(isExpanded, switchState)}
</InputAdornment>
<ChooseAnswerModal
open={open}
onClose={() => setOpen(false)}
anchorRef={anchorRef}
totalIndex={totalIndex}
/>
</Box>
2023-09-20 09:07:33 +00:00
),
2023-09-13 10:58:07 +00:00
}}
sx={{
2023-09-13 10:58:07 +00:00
"& .MuiInputBase-root": {
color: isExpanded ? "#9A9AAF" : "white",
2023-09-25 13:43:15 +00:00
backgroundColor: isExpanded ? theme.palette.background.default : "transparent",
2023-09-13 10:58:07 +00:00
height: "48px",
borderRadius: "10px",
2023-09-15 12:59:45 +00:00
".MuiOutlinedInput-notchedOutline": {
borderWidth: "1px !important",
},
2023-09-13 10:58:07 +00:00
},
}}
inputProps={{
sx: {
fontSize: "18px",
lineHeight: "21px",
py: 0,
paddingLeft: switchState.length === 0 ? 0 : "18px",
},
}}
/>
2023-09-13 10:58:07 +00:00
</FormControl>
2023-09-20 09:07:33 +00:00
<Box
sx={{
display: "flex",
2023-09-25 13:43:15 +00:00
alignItems: "flex-start",
2023-09-20 09:07:33 +00:00
width: isMobile ? "100%" : "auto",
position: "relative",
2023-09-25 13:43:15 +00:00
height: "30px",
marginBottom: "10px",
2023-09-20 09:07:33 +00:00
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
}}
>
<IconButton
2023-09-25 13:43:15 +00:00
sx={{ paddingBottom: isMobile ? "0" : "" }}
disableRipple
2023-09-20 09:07:33 +00:00
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
expanded: !isExpanded,
})
}
>
{isExpanded ? (
2023-09-25 13:43:15 +00:00
<ArrowDownIcon
style={{
width: "18px",
marginLeft: isMobile ? "0px" : "16.1px",
color: "#4D4D4D",
}}
/>
2023-09-20 09:07:33 +00:00
) : (
<ExpandLessIcon fill="#7E2AEA" />
)}
2023-09-13 10:58:07 +00:00
</IconButton>
2023-09-15 12:37:12 +00:00
{isExpanded ? (
<></>
) : (
<Box sx={{ display: "flex", borderRight: "solid 1px white" }}>
<FormControlLabel
2023-09-20 09:07:33 +00:00
control={
2023-09-25 13:43:15 +00:00
<Checkbox icon={<HideIcon style={{ color: "#7E2AEA" }} />} checkedIcon={<CrossedEyeIcon />} />
2023-09-20 09:07:33 +00:00
}
2023-09-15 12:37:12 +00:00
label={""}
sx={{
color: theme.palette.grey2.main,
ml: "-9px",
mr: 0,
userSelect: "none",
}}
/>
<IconButton onClick={() => copyQuestion(quizId, totalIndex)}>
2023-09-25 13:43:15 +00:00
<CopyIcon style={{ color: "white" }} />
2023-09-15 12:37:12 +00:00
</IconButton>
<IconButton
2023-09-20 09:07:33 +00:00
sx={{
cursor: "pointer",
borderRadius: "6px",
padding: "2px",
}}
2023-09-15 12:37:12 +00:00
onClick={() => removeQuestion(quizId, totalIndex)}
>
2023-09-25 13:43:15 +00:00
<DeleteIcon style={{ color: "white" }} />
2023-09-15 12:37:12 +00:00
</IconButton>
</Box>
)}
2023-09-13 10:58:07 +00:00
2023-09-25 13:43:15 +00:00
<OneIcon style={{ fontSize: "30px", marginLeft: "1.5px" }} />
2023-09-15 12:37:12 +00:00
</Box>
<IconButton
2023-09-25 13:43:15 +00:00
disableRipple
2023-09-15 12:37:12 +00:00
sx={{
2023-09-25 13:43:15 +00:00
padding: isMobile ? "0" : "5px 8px 8px 8px",
2023-09-15 12:37:12 +00:00
position: isMobile ? "absolute" : "relative",
2023-09-21 07:00:08 +00:00
right: isMobile ? "0" : null,
2023-09-15 12:37:12 +00:00
bottom: isMobile ? "0" : null,
}}
{...draggableProps}
>
2023-09-25 13:43:15 +00:00
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px", marginLeft: "-px" }} />
2023-09-15 12:37:12 +00:00
</IconButton>
</Box>
2023-09-13 10:58:07 +00:00
</Box>
{isExpanded && (
<Box
sx={{
display: "flex",
flexDirection: "column",
padding: 0,
borderRadius: "12px",
}}
>
{switchState.length === 0 ? (
<TypeQuestions totalIndex={totalIndex} />
) : (
<SwitchQuestionsPage totalIndex={totalIndex} />
)}
</Box>
)}
2023-09-13 10:58:07 +00:00
</Paper>
<Box
onMouseEnter={() => setPlusVisible(true)}
onMouseLeave={() => setPlusVisible(false)}
sx={{
maxWidth: "825px",
display: "flex",
alignItems: "center",
height: "40px",
cursor: "pointer",
}}
>
2023-08-11 07:25:28 +00:00
<Box
2023-09-13 10:58:07 +00:00
onClick={() => createQuestion(quizId, totalIndex + 1)}
2023-08-11 07:25:28 +00:00
sx={{
2023-09-13 10:58:07 +00:00
display: plusVisible && !isDragging ? "flex" : "none",
width: "100%",
alignItems: "center",
columnGap: "10px",
2023-08-11 07:25:28 +00:00
}}
>
2023-09-13 10:58:07 +00:00
<Box
sx={{
boxSizing: "border-box",
width: "100%",
height: "1px",
backgroundPosition: "bottom",
backgroundRepeat: "repeat-x",
backgroundSize: "20px 1px",
2023-09-25 13:43:15 +00:00
backgroundImage: "radial-gradient(circle, #7E2AEA 6px, #F2F3F7 1px)",
2023-09-13 10:58:07 +00:00
}}
/>
<PlusIcon />
2023-08-08 11:01:37 +00:00
</Box>
2023-09-13 10:58:07 +00:00
</Box>
</>
2023-08-08 11:01:37 +00:00
);
}