fix: AnswerDraggableList logic

This commit is contained in:
IlyaDoronin 2023-09-28 15:29:48 +03:00
parent 7edb4fc9f2
commit 6c46a4b32e
3 changed files with 166 additions and 158 deletions

@ -12,18 +12,15 @@ import {
useMediaQuery, useMediaQuery,
} from "@mui/material"; } from "@mui/material";
import { useDebouncedCallback } from "use-debounce"; import { useDebouncedCallback } from "use-debounce";
import { EmojiPicker } from "@ui_kit/EmojiPicker";
import { questionStore, updateQuestionsList } from "@root/questions"; import { questionStore, updateQuestionsList } from "@root/questions";
import PointsIcon from "@icons/questionsPage/PointsIcon"; import PointsIcon from "@icons/questionsPage/PointsIcon";
import DeleteIcon from "@icons/questionsPage/deleteIcon"; import DeleteIcon from "@icons/questionsPage/deleteIcon";
import MessageIcon from "@icons/messagIcon"; import MessageIcon from "@icons/messagIcon";
import { EmojiIcons } from "@icons/EmojiIocns";
import TextareaAutosize from "@mui/base/TextareaAutosize"; import TextareaAutosize from "@mui/base/TextareaAutosize";
import AddEmoji from "../../../assets/icons/questionsPage/addEmoji";
import type { ChangeEvent, KeyboardEvent } from "react"; import type { ChangeEvent, KeyboardEvent, ReactNode } from "react";
import type { Variants } from "@root/questions"; import type { Variants } from "@root/questions";
type AnswerItemProps = { type AnswerItemProps = {
@ -31,7 +28,8 @@ type AnswerItemProps = {
totalIndex: number; totalIndex: number;
variants: Variants[]; variants: Variants[];
variant: Variants; variant: Variants;
emoji: boolean; additionalContent?: ReactNode;
additionalMobile?: ReactNode;
}; };
export const AnswerItem = ({ export const AnswerItem = ({
@ -39,15 +37,13 @@ export const AnswerItem = ({
totalIndex, totalIndex,
variants, variants,
variant, variant,
emoji, additionalContent,
additionalMobile,
}: AnswerItemProps) => { }: AnswerItemProps) => {
const [open, setOpen] = useState<boolean>(false);
const quizId = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(790)); const isTablet = useMediaQuery(theme.breakpoints.down(790));
const anchorElement = useRef();
const anchorMobileElement = useRef();
const debounced = useDebouncedCallback((value) => { const debounced = useDebouncedCallback((value) => {
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew[index].answer = value; answerNew[index].answer = value;
@ -147,58 +143,7 @@ export const AnswerItem = ({
> >
<PointsIcon /> <PointsIcon />
</InputAdornment> </InputAdornment>
{emoji && !isTablet && ( {additionalContent}
<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",
}}
>
{variant.emoji && (
<Box sx={{ width: "30px" }}>{variant.emoji}</Box>
)}
<AddEmoji />
</Box>
</Box>
<Popover
open={open}
anchorEl={anchorElement.current}
onClose={() => setOpen(false)}
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
sx={{
".MuiPaper-root.MuiPaper-rounded": {
borderRadius: "10px",
},
}}
>
<EmojiPicker
onEmojiSelect={({ native }) => {
setOpen(false);
const cloneVariants = [...variants];
cloneVariants[index] = {
...cloneVariants[index],
emoji: native,
};
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: cloneVariants,
},
});
}}
/>
</Popover>
</Box>
)}
</> </>
), ),
endAdornment: ( endAdornment: (
@ -232,9 +177,9 @@ export const AnswerItem = ({
), ),
}} }}
sx={{ sx={{
padding: emoji && isTablet ? "10px 0px" : 0, padding: isTablet ? "10px 0px" : 0,
"& .MuiInputBase-root": { "& .MuiInputBase-root": {
padding: emoji ? "5px 13.5px" : "13.5px", minHeight: "48px",
borderRadius: "10px", borderRadius: "10px",
background: "#ffffff", background: "#ffffff",
"& .MuiOutlinedInput-notchedOutline": { "& .MuiOutlinedInput-notchedOutline": {
@ -246,94 +191,7 @@ export const AnswerItem = ({
sx: { fontSize: "18px", height: "21px", py: 0 }, sx: { fontSize: "18px", height: "21px", py: 0 },
}} }}
/> />
{emoji && isTablet && ( {additionalMobile}
<Box
ref={anchorMobileElement}
onClick={() => setOpen(true)}
sx={{
display: "flex",
alignItems: "center",
m: "8px",
position: "relative",
}}
>
<Box
sx={{ width: "100%", background: "#EEE4FC", height: "40px" }}
/>
{variant.emoji ? (
<Box
sx={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
>
{variant.emoji}
</Box>
) : (
<EmojiIcons
style={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
/>
)}
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
}}
>
+
</Box>
<Popover
open={open}
anchorEl={anchorMobileElement.current}
onClick={(event) => event.stopPropagation()}
onClose={() => setOpen(false)}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
sx={{
display: open ? "block" : "none",
".MuiPaper-root.MuiPaper-rounded": {
borderRadius: "10px",
},
}}
>
<EmojiPicker
onEmojiSelect={({ native }) => {
setOpen(false);
const cloneVariants = [...variants];
cloneVariants[index] = {
...cloneVariants[index],
emoji: native,
};
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: cloneVariants,
},
});
}}
/>
</Popover>
</Box>
)}
</FormControl> </FormControl>
</Box> </Box>
)} )}

@ -8,19 +8,22 @@ import { updateVariants } from "@root/questions";
import { reorder } from "./helper"; import { reorder } from "./helper";
import type { ReactNode } from "react";
import type { DropResult } from "react-beautiful-dnd"; import type { DropResult } from "react-beautiful-dnd";
import type { Variants } from "@root/questions"; import type { Variants } from "@root/questions";
type AnswerDraggableListProps = { type AnswerDraggableListProps = {
variants: Variants[]; variants: Variants[];
totalIndex: number; totalIndex: number;
emoji?: boolean; additionalContent?: (variant: Variants, index: number) => ReactNode;
additionalMobile?: (variant: Variants, index: number) => ReactNode;
}; };
export const AnswerDraggableList = ({ export const AnswerDraggableList = ({
variants, variants,
totalIndex, totalIndex,
emoji = false, additionalContent,
additionalMobile,
}: AnswerDraggableListProps) => { }: AnswerDraggableListProps) => {
const quizId = Number(useParams().quizId); const quizId = Number(useParams().quizId);
@ -44,7 +47,8 @@ export const AnswerDraggableList = ({
totalIndex={totalIndex} totalIndex={totalIndex}
variants={variants} variants={variants}
variant={variant} variant={variant}
emoji={emoji} additionalContent={additionalContent?.(variant, index)}
additionalMobile={additionalMobile?.(variant, index)}
/> />
))} ))}
{provided.placeholder} {provided.placeholder}

@ -1,21 +1,39 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { Box, Link, Typography, useMediaQuery, useTheme } from "@mui/material"; import {
Box,
Link,
Typography,
Popover,
useMediaQuery,
useTheme,
} from "@mui/material";
import EnterIcon from "../../../assets/icons/questionsPage/enterIcon"; import EnterIcon from "../../../assets/icons/questionsPage/enterIcon";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import SwitchEmoji from "./switchEmoji"; import SwitchEmoji from "./switchEmoji";
import { AnswerDraggableList } from "../AnswerDraggableList"; import { AnswerDraggableList } from "../AnswerDraggableList";
import { EmojiPicker } from "@ui_kit/EmojiPicker";
import { EmojiIcons } from "@icons/EmojiIocns";
import { questionStore, updateQuestionsList } from "@root/questions"; import { questionStore, updateQuestionsList } from "@root/questions";
import AddEmoji from "../../../assets/icons/questionsPage/addEmoji";
interface Props { interface Props {
totalIndex: number; totalIndex: number;
} }
export default function Emoji({ totalIndex }: Props) { export default function Emoji({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState<string>("setting"); const [switchState, setSwitchState] = useState<string>("setting");
const [open, setOpen] = useState<boolean>(false);
const [anchorElement, setAnchorElement] = useState<HTMLDivElement | null>(
null
);
const [currentIndex, setCurrentIndex] = useState<number>(0);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const quizId = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790)); const isTablet = useMediaQuery(theme.breakpoints.down(790));
const SSHC = (data: string) => { const SSHC = (data: string) => {
setSwitchState(data); setSwitchState(data);
@ -27,8 +45,136 @@ export default function Emoji({ totalIndex }: Props) {
<AnswerDraggableList <AnswerDraggableList
variants={listQuestions[quizId][totalIndex].content.variants} variants={listQuestions[quizId][totalIndex].content.variants}
totalIndex={totalIndex} totalIndex={totalIndex}
emoji additionalContent={(variant, index) => (
<>
{!isTablet && (
<Box sx={{ cursor: "pointer", margin: "0 15px 0 5px" }}>
<Box
onClick={({ currentTarget }) => {
setAnchorElement(currentTarget);
setCurrentIndex(index);
setOpen(true);
}}
>
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "5px",
}}
>
{variant.emoji && (
<Box sx={{ width: "30px" }}>{variant.emoji}</Box>
)}
<AddEmoji />
</Box>
</Box>
</Box>
)}
</>
)}
additionalMobile={(variant, index) => (
<>
{isTablet && (
<Box
onClick={({ currentTarget }) => {
setAnchorElement(currentTarget);
setCurrentIndex(index);
setOpen(true);
}}
sx={{
display: "flex",
alignItems: "center",
m: "8px",
position: "relative",
}}
>
<Box
sx={{
width: "100%",
background: "#EEE4FC",
height: "40px",
}}
/>
{variant.emoji ? (
<Box
sx={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
>
{variant.emoji}
</Box>
) : (
<EmojiIcons
style={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
/>
)}
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
}}
>
+
</Box>
</Box>
)}
</>
)}
/> />
<Popover
open={open}
anchorEl={anchorElement}
onClick={(event) => event.stopPropagation()}
onClose={() => setOpen(false)}
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
sx={{
".MuiPaper-root.MuiPaper-rounded": {
borderRadius: "10px",
},
}}
>
<EmojiPicker
onEmojiSelect={({ native }) => {
setOpen(false);
const cloneVariants = [
...listQuestions[quizId][totalIndex].content.variants,
];
cloneVariants[currentIndex] = {
...cloneVariants[currentIndex],
emoji: native,
};
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: cloneVariants,
},
});
}}
/>
</Popover>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}> <Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Link <Link
component="button" component="button"
@ -49,7 +195,7 @@ export default function Emoji({ totalIndex }: Props) {
> >
Добавьте ответ Добавьте ответ
</Link> </Link>
{isMobile ? null : ( {!isTablet && (
<> <>
<Typography <Typography
sx={{ sx={{