frontPanel/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx

239 lines
8.1 KiB
TypeScript
Raw Normal View History

2023-09-21 10:07:30 +00:00
import { useState, useRef } from "react";
2023-09-06 13:20:12 +00:00
import { useParams } from "react-router-dom";
2023-08-18 11:16:56 +00:00
import { Draggable } from "react-beautiful-dnd";
2023-09-18 09:07:13 +00:00
import {
Box,
TextField,
FormControl,
InputAdornment,
IconButton,
2023-09-21 10:07:30 +00:00
Popover,
2023-09-18 09:07:13 +00:00
useTheme,
useMediaQuery,
} from "@mui/material";
2023-09-20 09:07:33 +00:00
import { useDebouncedCallback } from "use-debounce";
2023-09-21 10:07:30 +00:00
import { EmojiPicker } from "@ui_kit/EmojiPicker";
2023-08-18 11:16:56 +00:00
import { questionStore, updateQuestionsList } from "@root/questions";
import PointsIcon from "@icons/questionsPage/PointsIcon";
import DeleteIcon from "@icons/questionsPage/deleteIcon";
import MessageIcon from "@icons/messagIcon";
import TextareaAutosize from "@mui/base/TextareaAutosize";
2023-09-21 10:07:30 +00:00
import AddEmoji from "../../../assets/icons/questionsPage/addEmoji";
2023-08-18 11:16:56 +00:00
import type { ChangeEvent, KeyboardEvent } from "react";
2023-10-04 09:07:59 +00:00
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
import type { QuestionVariant } from "../../../model/questionTypes/shared";
2023-08-18 11:16:56 +00:00
type AnswerItemProps = {
index: number;
totalIndex: number;
2023-10-04 09:07:59 +00:00
variants: QuestionVariant[];
variant: QuestionVariant;
2023-09-21 10:07:30 +00:00
emoji: boolean;
2023-08-18 11:16:56 +00:00
};
2023-09-18 09:07:13 +00:00
export const AnswerItem = ({
index,
totalIndex,
variants,
variant,
2023-09-21 10:07:30 +00:00
emoji,
2023-09-18 09:07:13 +00:00
}: AnswerItemProps) => {
2023-09-21 10:07:30 +00:00
const [open, setOpen] = useState<boolean>(false);
2023-09-06 13:20:12 +00:00
const quizId = Number(useParams().quizId);
2023-08-18 11:16:56 +00:00
const { listQuestions } = questionStore();
const theme = useTheme();
2023-09-15 12:37:12 +00:00
const isMobile = useMediaQuery(theme.breakpoints.down(790));
2023-09-21 10:07:30 +00:00
const anchorElement = useRef();
2023-10-04 09:07:59 +00:00
const question = listQuestions[quizId][totalIndex] as QuizQuestionVariant;
2023-09-20 09:07:33 +00:00
const debounced = useDebouncedCallback((value) => {
const answerNew = variants.slice();
answerNew[index].answer = value;
updateQuestionsList(quizId, totalIndex, {
content: {
2023-10-04 09:07:59 +00:00
...question.content,
2023-09-20 09:07:33 +00:00
variants: answerNew,
},
});
}, 1000);
2023-08-18 11:16:56 +00:00
const [isOpen, setIsOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
setIsOpen(true);
};
const handleClose = () => {
setIsOpen(false);
};
const addNewAnswer = () => {
const answerNew = variants.slice();
2023-10-04 09:07:59 +00:00
answerNew.push({ answer: "", hints: "", extendedText: "" });
2023-08-18 11:16:56 +00:00
2023-09-06 13:20:12 +00:00
updateQuestionsList(quizId, totalIndex, {
2023-10-04 09:07:59 +00:00
content: { ...question.content, variants: answerNew },
2023-08-18 11:16:56 +00:00
});
};
const deleteAnswer = () => {
const answerNew = variants.slice();
answerNew.splice(index, 1);
2023-09-06 13:20:12 +00:00
updateQuestionsList(quizId, totalIndex, {
2023-10-04 09:07:59 +00:00
content: { ...question.content, variants: answerNew },
2023-08-18 11:16:56 +00:00
});
};
const changeAnswerHint = (event: ChangeEvent<HTMLTextAreaElement>) => {
const answerNew = variants.slice();
answerNew[index].hints = event.target.value;
2023-09-06 13:20:12 +00:00
updateQuestionsList(quizId, totalIndex, {
2023-10-04 09:07:59 +00:00
content: { ...question.content, variants: answerNew },
2023-08-18 11:16:56 +00:00
});
};
return (
<Draggable draggableId={String(index)} index={index}>
{(provided) => (
2023-08-18 15:39:41 +00:00
<Box ref={provided.innerRef} {...provided.draggableProps}>
2023-08-18 11:16:56 +00:00
<FormControl
key={index}
fullWidth
variant="standard"
2023-09-15 12:37:12 +00:00
sx={{ padding: isMobile ? " 15px 0 20px 0" : "0 0 20px 0" }}
2023-08-18 11:16:56 +00:00
>
<TextField
2023-09-20 09:07:33 +00:00
defaultValue={variant.answer}
2023-08-18 11:16:56 +00:00
fullWidth
2023-08-18 15:44:29 +00:00
focused={false}
2023-08-18 11:16:56 +00:00
placeholder={"Добавьте ответ"}
2023-10-04 09:07:59 +00:00
multiline={question.content.largeCheck}
2023-09-20 09:07:33 +00:00
onChange={({ target }) => debounced(target.value)}
2023-09-07 08:02:15 +00:00
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
2023-10-04 09:07:59 +00:00
if (event.code === "Enter" && !question.content.largeCheck) {
2023-09-07 08:02:15 +00:00
addNewAnswer();
}
}}
2023-08-18 11:16:56 +00:00
InputProps={{
startAdornment: (
2023-09-06 07:30:27 +00:00
<>
2023-09-18 09:07:13 +00:00
<InputAdornment
{...provided.dragHandleProps}
position="start"
>
2023-09-06 07:30:27 +00:00
<PointsIcon />
</InputAdornment>
2023-09-21 10:07:30 +00:00
{emoji && (
<Box sx={{ cursor: "pointer", margin: "0 15px 0 5px" }}>
<Box ref={anchorElement} onClick={() => setOpen(true)}>
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "5px",
}}
>
2023-10-04 09:07:59 +00:00
{variant.extendedText && (
<Box sx={{ width: "30px" }}>
{variant.extendedText}
</Box>
2023-09-21 10:24:53 +00:00
)}
2023-09-21 10:07:30 +00:00
<AddEmoji />
</Box>
</Box>
<Popover
open={open}
anchorEl={anchorElement.current}
onClose={() => setOpen(false)}
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
sx={{
".MuiPaper-root.MuiPaper-rounded": {
2023-09-21 11:37:10 +00:00
borderRadius: "10px",
2023-09-21 10:07:30 +00:00
},
}}
>
<EmojiPicker
onEmojiSelect={({ native }) => {
setOpen(false);
const cloneVariants = [...variants];
cloneVariants[index] = {
...cloneVariants[index],
2023-10-04 09:07:59 +00:00
extendedText: native,
2023-09-21 10:07:30 +00:00
};
updateQuestionsList(quizId, totalIndex, {
content: {
2023-10-04 09:45:51 +00:00
...question.content,
2023-09-21 10:07:30 +00:00
variants: cloneVariants,
},
});
}}
/>
</Popover>
</Box>
)}
2023-09-06 07:30:27 +00:00
</>
2023-08-18 11:16:56 +00:00
),
endAdornment: (
<InputAdornment position="end">
2023-09-21 10:07:30 +00:00
<IconButton onClick={handleClick}>
2023-08-18 11:16:56 +00:00
<MessageIcon />
</IconButton>
<Popover
open={isOpen}
anchorEl={anchorEl}
onClose={handleClose}
2023-08-18 15:39:41 +00:00
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
2023-08-18 11:16:56 +00:00
>
<TextareaAutosize
style={{ margin: "10px" }}
placeholder="Подсказка для этого ответа"
value={variant.hints}
onChange={changeAnswerHint}
2023-09-18 09:07:13 +00:00
onKeyDown={(
event: KeyboardEvent<HTMLTextAreaElement>
) => event.stopPropagation()}
2023-08-18 11:16:56 +00:00
/>
</Popover>
<IconButton onClick={deleteAnswer}>
<DeleteIcon color={theme.palette.grey2.main} />
</IconButton>
</InputAdornment>
),
}}
sx={{
"& .MuiInputBase-root": {
2023-10-04 09:07:59 +00:00
padding: emoji ? "5px 13px" : "13px",
2023-08-18 11:16:56 +00:00
borderRadius: "10px",
background: "#ffffff",
2023-10-04 09:07:59 +00:00
"& input.MuiInputBase-input": {
height: "22px",
},
"& textarea.MuiInputBase-input": {
marginTop: "1px",
},
2023-08-18 11:16:56 +00:00
},
}}
inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
}}
/>
</FormControl>
2023-08-18 15:39:41 +00:00
</Box>
2023-08-18 11:16:56 +00:00
)}
</Draggable>
);
};