diff --git a/src/pages/Questions/DraggableList/QuestionPageCard.tsx b/src/pages/Questions/DraggableList/QuestionPageCard.tsx index 385c27e0..1bc09693 100644 --- a/src/pages/Questions/DraggableList/QuestionPageCard.tsx +++ b/src/pages/Questions/DraggableList/QuestionPageCard.tsx @@ -158,7 +158,6 @@ export default function QuestionsPageCard({ padding: "20px", }} > - <>{isExpanded && console.log(listQuestions[totalIndex])} ); +export default function SwitchQuestionsPage({ totalIndex }: Props) { + const params = Number(useParams().quizId); + const { listQuestions } = questionStore(); + const switchState = listQuestions[totalIndex].type; + switch (switchState) { + case "variant": + return ; - case 'images': - return (); + case "images": + return ; - case 'varimg': - return (); + case "varimg": + return ; - case 'emoji': - return (); + case "emoji": + return ; - case 'text': - return (); + case "text": + return ; - case 'select': - return (); + case "select": + return ; - case 'date': - return (); + case "date": + return ; - case 'number': - return (); + case "number": + return ; - case 'file': - return (); + case "file": + return ; - case 'page': - return (); + case "page": + return ; - case 'rating': - return (); + case "rating": + return ; - default: - return (<>) - } -} \ No newline at end of file + default: + return <>; + } +} diff --git a/src/pages/Questions/answerOptions/AnswerDraggableList/AnswerItem.tsx b/src/pages/Questions/answerOptions/AnswerDraggableList/AnswerItem.tsx new file mode 100644 index 00000000..7635c5f8 --- /dev/null +++ b/src/pages/Questions/answerOptions/AnswerDraggableList/AnswerItem.tsx @@ -0,0 +1,159 @@ +import { useState } from "react"; +import { Draggable } from "react-beautiful-dnd"; +import { + TextField, + FormControl, + InputAdornment, + IconButton, + ListItem, + useTheme, +} from "@mui/material"; + +import { questionStore, updateQuestionsList } from "@root/questions"; + +import PointsIcon from "@icons/questionsPage/PointsIcon"; +import DeleteIcon from "@icons/questionsPage/deleteIcon"; +import MessageIcon from "@icons/messagIcon"; +import Popover from "@mui/material/Popover"; +import TextareaAutosize from "@mui/base/TextareaAutosize"; + +import type { ChangeEvent, KeyboardEvent } from "react"; +import type { Variants } from "@root/questions"; + +type AnswerItemProps = { + index: number; + totalIndex: number; + variants: Variants[]; + variant: Variants; +}; + +export const AnswerItem = ({ + index, + totalIndex, + variants, + variant, +}: AnswerItemProps) => { + const { listQuestions } = questionStore(); + const theme = useTheme(); + + const [isOpen, setIsOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + setIsOpen(true); + }; + + const handleClose = () => { + setIsOpen(false); + }; + + const onChangeText = (event: ChangeEvent) => { + const answerNew = variants.slice(); + answerNew[index].answer = event.target.value; + + updateQuestionsList(totalIndex, { + content: { ...listQuestions[totalIndex].content, variants: answerNew }, + }); + }; + + const addNewAnswer = () => { + const answerNew = variants.slice(); + answerNew.push({ answer: "", answerLong: "", hints: "" }); + + updateQuestionsList(totalIndex, { + content: { ...listQuestions[totalIndex].content, variants: answerNew }, + }); + }; + + const deleteAnswer = () => { + const answerNew = variants.slice(); + answerNew.splice(index, 1); + + updateQuestionsList(totalIndex, { + content: { ...listQuestions[totalIndex].content, variants: answerNew }, + }); + }; + + const changeAnswerHint = (event: ChangeEvent) => { + const answerNew = variants.slice(); + answerNew[index].hints = event.target.value; + + updateQuestionsList(totalIndex, { + content: { ...listQuestions[totalIndex].content, variants: answerNew }, + }); + }; + + return ( + + {(provided) => ( + + + ) => + event.code === "Enter" && addNewAnswer() + } + InputProps={{ + startAdornment: ( + + + + ), + endAdornment: ( + + + + + + + + + + + + ), + }} + sx={{ + "& .MuiInputBase-root": { + height: "48px", + borderRadius: "10px", + background: "#ffffff", + }, + }} + inputProps={{ + sx: { fontSize: "18px", lineHeight: "21px", py: 0 }, + }} + /> + + + )} + + ); +}; diff --git a/src/pages/Questions/answerOptions/AnswerDraggableList/StrictModeDroppable.tsx b/src/pages/Questions/answerOptions/AnswerDraggableList/StrictModeDroppable.tsx new file mode 100644 index 00000000..6441c17e --- /dev/null +++ b/src/pages/Questions/answerOptions/AnswerDraggableList/StrictModeDroppable.tsx @@ -0,0 +1,23 @@ +import { useState, useEffect } from "react"; +import { Droppable } from "react-beautiful-dnd"; + +import type { DroppableProps } from "react-beautiful-dnd"; + +export const StrictModeDroppable = ({ children, ...props }: DroppableProps) => { + const [enabled, setEnabled] = useState(false); + + useEffect(() => { + const animation = requestAnimationFrame(() => setEnabled(true)); + + return () => { + setEnabled(false); + cancelAnimationFrame(animation); + }; + }, []); + + if (!enabled) { + return null; + } + + return {children}; +}; diff --git a/src/pages/Questions/answerOptions/AnswerDraggableList/helper.ts b/src/pages/Questions/answerOptions/AnswerDraggableList/helper.ts new file mode 100644 index 00000000..203ee13b --- /dev/null +++ b/src/pages/Questions/answerOptions/AnswerDraggableList/helper.ts @@ -0,0 +1,11 @@ +export const reorder = ( + list: T[], + startIndex: number, + endIndex: number +): T[] => { + const result = Array.from(list); + const [removed] = result.splice(startIndex, 1); + result.splice(endIndex, 0, removed); + + return result; +}; diff --git a/src/pages/Questions/answerOptions/AnswerDraggableList/index.tsx b/src/pages/Questions/answerOptions/AnswerDraggableList/index.tsx new file mode 100644 index 00000000..a145573c --- /dev/null +++ b/src/pages/Questions/answerOptions/AnswerDraggableList/index.tsx @@ -0,0 +1,51 @@ +import { Box } from "@mui/material"; +import { DragDropContext } from "react-beautiful-dnd"; + +import { StrictModeDroppable } from "./StrictModeDroppable"; +import { AnswerItem } from "./AnswerItem"; + +import { updateVariants } from "@root/questions"; + +import { reorder } from "./helper"; + +import type { DropResult } from "react-beautiful-dnd"; +import type { Variants } from "@root/questions"; + +type AnswerDraggableListProps = { + variants: Variants[]; + totalIndex: number; +}; + +export const AnswerDraggableList = ({ + variants, + totalIndex, +}: AnswerDraggableListProps) => { + const onDragEnd = ({ destination, source }: DropResult) => { + if (destination) { + const newItems = reorder(variants, source.index, destination.index); + + updateVariants(totalIndex, newItems); + } + }; + + return ( + + + {(provided) => ( + + {variants.map((variant, index) => ( + + ))} + {provided.placeholder} + + )} + + + ); +}; diff --git a/src/pages/Questions/answerOptions/AnswerOptions.tsx b/src/pages/Questions/answerOptions/AnswerOptions.tsx index 265a1cc1..a0c82379 100755 --- a/src/pages/Questions/answerOptions/AnswerOptions.tsx +++ b/src/pages/Questions/answerOptions/AnswerOptions.tsx @@ -1,27 +1,11 @@ -import { - Box, - Typography, - Link, - useTheme, - TextField, - FormControl, - InputAdornment, - IconButton, -} from "@mui/material"; -import React, { useState } from "react"; +import { useState } from "react"; +import { Box, Typography, Link, useTheme } from "@mui/material"; import EnterIcon from "../../../assets/icons/questionsPage/enterIcon"; import SwitchAnswerOptions from "./switchAnswerOptions"; +import { AnswerDraggableList } from "./AnswerDraggableList"; import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict"; -import QuestionsPageCard from "../DraggableList/QuestionPageCard"; -import { useParams } from "react-router-dom"; -import { Variants, questionStore, updateQuestionsList } from "@root/questions"; -import PointsIcon from "@icons/questionsPage/PointsIcon"; -import DeleteIcon from "@icons/questionsPage/deleteIcon"; -import MessageIcon from "@icons/messagIcon"; -import Popover from "@mui/material/Popover"; -import TextareaAutosize from "@mui/base/TextareaAutosize"; +import { questionStore, updateQuestionsList } from "@root/questions"; -import type { KeyboardEvent } from "react"; // Импортируем интерфейс Varian interface Props { @@ -29,33 +13,17 @@ interface Props { } export default function AnswerOptions({ totalIndex }: Props) { + const [switchState, setSwitchState] = useState("setting"); const { listQuestions } = questionStore(); - const Answer = listQuestions[totalIndex].content.variants; - console.log(Answer); + const variants = listQuestions[totalIndex].content.variants; const theme = useTheme(); - const [switchState, setSwitchState] = React.useState("setting"); + const SSHC = (data: string) => { setSwitchState(data); }; - const [isOpen, setIsOpen] = React.useState(false); - const [anchorEl, setAnchorEl] = React.useState( - null - ); - - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - setIsOpen(true); - }; - - const handleClose = () => { - setIsOpen(false); - }; - - const id = "my-popover-id"; - const addNewAnswer = () => { - const answerNew = Answer.slice(); // Create a shallow copy of the array + const answerNew = variants.slice(); // Create a shallow copy of the array answerNew.push({ answer: "", answerLong: "", hints: "" }); updateQuestionsList(totalIndex, { @@ -66,7 +34,7 @@ export default function AnswerOptions({ totalIndex }: Props) { return ( <> - {Answer.length === 0 ? ( + {variants.length === 0 ? ( ) : ( - - {Answer.map((variant: Variants, index: number) => ( - - { - const answerNew = Answer.slice(); // Create a shallow copy of the array - answerNew[index].answer = e.target.value; - let clonContent = listQuestions[totalIndex].content; - clonContent.variants = answerNew; - updateQuestionsList(totalIndex, { content: clonContent }); - }} - onKeyDown={(event: KeyboardEvent) => - event.code === "Enter" && addNewAnswer() - } - InputProps={{ - startAdornment: ( - - - - ), - endAdornment: ( - - - - - - { - const answerNew = Answer.slice(); // Create a shallow copy of the array - answerNew[index].hints = e.target.value; - let clonContent = - listQuestions[totalIndex].content; - clonContent.variants = answerNew; - updateQuestionsList(totalIndex, { - content: clonContent, - }); - }} - /> - - { - const answerNew = Answer.slice(); // Create a shallow copy of the array - answerNew.splice(index, 1); - let clonContent = listQuestions[totalIndex].content; - clonContent.variants = answerNew; - updateQuestionsList(totalIndex, { - content: clonContent, - }); - }} - > - - - - ), - }} - sx={{ - "& .MuiInputBase-root": { - height: "48px", - borderRadius: "10px", - }, - }} - inputProps={{ - sx: { - fontSize: "18px", - lineHeight: "21px", - py: 0, - }, - }} - /> - - ))} - + )} { + const listQuestions = [...questionStore.getState()["listQuestions"]]; + + listQuestions[index].content.variants = variants; + + questionStore.setState({ listQuestions }); +}; + export const createQuestion = (id: number) => { const idQ = getRandom(1000000, 10000000); const newData = [...questionStore.getState()["listQuestions"]]; //пересоздание массива