feat: cancel questin deleting

This commit is contained in:
IlyaDoronin 2023-09-27 17:14:48 +03:00
parent 0c1279b37d
commit b4f1e4857d
6 changed files with 193 additions and 39 deletions

@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
import { useParams } from "react-router-dom";
import SettingIcon from "../../assets/icons/questionsPage/settingIcon";
@ -20,6 +20,8 @@ import {
resetSomeField,
copyQuestion,
removeQuestion,
removeQuestionForce,
updateQuestionsList,
} from "@root/questions";
import { DoubleTick } from "@icons/questionsPage/DoubleTick";
import { DoubleArrowRight } from "@icons/questionsPage/DoubleArrowRight";
@ -37,10 +39,16 @@ export default function ButtonsOptions({
totalIndex,
}: Props) {
const quizId = Number(useParams().quizId);
const { openedModalSettings } = questionStore();
const { openedModalSettings, listQuestions } = questionStore();
const [openedReallyChangingModal, setOpenedReallyChangingModal] =
useState<boolean>(false);
useEffect(() => {
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(listQuestions[quizId][totalIndex].deleteTimeoutId);
}
}, [listQuestions]);
const openedModal = () => {
resetSomeField({ openedModalSettings: "open" });
console.log(openedModalSettings);
@ -50,6 +58,7 @@ export default function ButtonsOptions({
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isWrappMiniButtonSetting = useMediaQuery(theme.breakpoints.down(920));
const buttonSetting: {
icon: JSX.Element;
title: string;
@ -241,7 +250,23 @@ export default function ButtonsOptions({
</IconButton>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => removeQuestion(quizId, totalIndex)}
onClick={() => {
const removedId = listQuestions[quizId][totalIndex].id;
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(listQuestions[quizId][totalIndex].deleteTimeoutId);
}
removeQuestion(quizId, totalIndex);
const newTimeoutId = window.setTimeout(() => {
removeQuestionForce(quizId, removedId);
}, 5000);
updateQuestionsList(quizId, totalIndex, {
...listQuestions[quizId][totalIndex],
deleteTimeoutId: newTimeoutId,
});
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>

@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
import SettingIcon from "../../assets/icons/questionsPage/settingIcon";
import Clue from "../../assets/icons/questionsPage/clue";
@ -21,13 +21,14 @@ import {
copyQuestion,
removeQuestion,
resetSomeField,
removeQuestionForce,
updateQuestionsList,
} from "@root/questions";
import { DoubleArrowRight } from "@icons/questionsPage/DoubleArrowRight";
import { DoubleTick } from "@icons/questionsPage/DoubleTick";
import { VectorQuestions } from "@icons/questionsPage/VectorQuestions";
import { ReallyChangingModal } from "@ui_kit/Modal/ReallyChangingModal/ReallyChangingModal";
import "./ButtonsOptionsAndPict.css";
interface Props {
@ -43,12 +44,19 @@ export default function ButtonsOptionsAndPict({
}: Props) {
const [buttonHover, setButtonHover] = useState<string>("");
const quizId = Number(useParams().quizId);
const { openedModalSettings } = questionStore();
const [openedReallyChangingModal, setOpenedReallyChangingModal] = useState<boolean>(false);
const { listQuestions } = questionStore();
const [openedReallyChangingModal, setOpenedReallyChangingModal] =
useState<boolean>(false);
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isIconMobile = useMediaQuery(theme.breakpoints.down(1050));
useEffect(() => {
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(listQuestions[quizId][totalIndex].deleteTimeoutId);
}
}, [listQuestions]);
const openedModal = () => {
resetSomeField({ openedModalSettings: "open" });
};
@ -280,13 +288,32 @@ export default function ButtonsOptionsAndPict({
</IconButton>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => removeQuestion(quizId, totalIndex)}
onClick={() => {
const removedId = listQuestions[quizId][totalIndex].id;
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(listQuestions[quizId][totalIndex].deleteTimeoutId);
}
removeQuestion(quizId, totalIndex);
const newTimeoutId = window.setTimeout(() => {
removeQuestionForce(quizId, removedId);
}, 5000);
updateQuestionsList(quizId, totalIndex, {
...listQuestions[quizId][totalIndex],
deleteTimeoutId: newTimeoutId,
});
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<ReallyChangingModal opened={openedReallyChangingModal} onClose={() => setOpenedReallyChangingModal(false)} />
<ReallyChangingModal
opened={openedReallyChangingModal}
onClose={() => setOpenedReallyChangingModal(false)}
/>
</Box>
);
}

@ -1,8 +1,11 @@
import { useParams } from "react-router-dom";
import { Draggable } from "react-beautiful-dnd";
import { Box, ListItem } from "@mui/material";
import { Box, ListItem, Typography, useTheme } from "@mui/material";
import QuestionsPageCard from "./QuestionPageCard";
import { questionStore, updateQuestionsList } from "@root/questions";
type DraggableListItemProps = {
index: number;
isDragging: boolean;
@ -11,23 +14,69 @@ type DraggableListItemProps = {
export const DraggableListItem = ({
index,
isDragging,
}: DraggableListItemProps) => (
<Draggable draggableId={String(index)} index={index}>
{(provided) => (
<ListItem
ref={provided.innerRef}
{...provided.draggableProps}
sx={{ userSelect: "none", padding: 0 }}
>
<Box sx={{ width: "100%", position: "relative" }}>
<QuestionsPageCard
key={index}
totalIndex={index}
draggableProps={provided.dragHandleProps}
isDragging={isDragging}
/>
</Box>
</ListItem>
)}
</Draggable>
);
}: DraggableListItemProps) => {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const theme = useTheme();
return (
<Draggable draggableId={String(index)} index={index}>
{(provided) => (
<ListItem
ref={provided.innerRef}
{...provided.draggableProps}
sx={{ userSelect: "none", padding: 0 }}
>
{listQuestions[quizId][index].deleted ? (
<Box
{...provided.dragHandleProps}
sx={{
width: "100%",
maxWidth: "800px",
display: "flex",
justifyContent: "center",
marginBottom: "40px",
gap: "5px",
}}
>
<Typography
sx={{
fontSize: "16px",
color: theme.palette.grey2.main,
}}
>
Вопрос удалён.
</Typography>
<Typography
onClick={() => {
updateQuestionsList(quizId, index, {
...listQuestions[quizId][index],
deleted: false,
});
}}
sx={{
cursor: "pointer",
fontSize: "16px",
textDecoration: "underline",
color: theme.palette.brightPurple.main,
textDecorationColor: theme.palette.brightPurple.main,
}}
>
Восстановить?
</Typography>
</Box>
) : (
<Box sx={{ width: "100%", position: "relative" }}>
<QuestionsPageCard
key={index}
totalIndex={index}
draggableProps={provided.dragHandleProps}
isDragging={isDragging}
/>
</Box>
)}
</ListItem>
)}
</Draggable>
);
};

@ -1,4 +1,4 @@
import { useState, useRef } from "react";
import { useState, useRef, useEffect } from "react";
import { useParams } from "react-router-dom";
import {
Box,
@ -24,6 +24,7 @@ import {
createQuestion,
copyQuestion,
removeQuestion,
removeQuestionForce,
} from "@root/questions";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
@ -157,6 +158,12 @@ export default function QuestionsPageCard({
updateQuestionsList(quizId, totalIndex, { title });
}, 1000);
useEffect(() => {
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(listQuestions[quizId][totalIndex].deleteTimeoutId);
}
}, [listQuestions]);
return (
<>
<Paper
@ -288,7 +295,25 @@ export default function QuestionsPageCard({
borderRadius: "6px",
padding: "2px",
}}
onClick={() => removeQuestion(quizId, totalIndex)}
onClick={() => {
const removedId = listQuestions[quizId][totalIndex].id;
if (listQuestions[quizId][totalIndex].deleteTimeoutId) {
clearTimeout(
listQuestions[quizId][totalIndex].deleteTimeoutId
);
}
removeQuestion(quizId, totalIndex);
const newTimeoutId = window.setTimeout(() => {
removeQuestionForce(quizId, removedId);
}, 5000);
updateQuestionsList(quizId, totalIndex, {
...listQuestions[quizId][totalIndex],
deleteTimeoutId: newTimeoutId,
});
}}
>
<DeleteIcon color={"white"} />
</IconButton>

@ -1,4 +1,3 @@
import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box } from "@mui/material";
import { DragDropContext, Droppable } from "react-beautiful-dnd";

@ -29,7 +29,8 @@ export interface Question {
description: string;
type: string;
required: boolean;
deleted: true;
deleted: boolean;
deleteTimeoutId: number;
page: number;
content: {
variants: Variants[];
@ -84,7 +85,8 @@ export const DEFAULT_QUESTION: Omit<Question, "id"> = {
description: "",
type: "",
required: true,
deleted: true,
deleted: false,
deleteTimeoutId: 0,
page: 0,
content: {
largeCheck: false,
@ -147,15 +149,35 @@ export const DEFAULT_QUESTION: Omit<Question, "id"> = {
expanded: false,
};
let isFirstPartialize = true;
export const questionStore = create<QuestionStore>()(
persist<QuestionStore>(
() => ({
listQuestions: {},
openedModalSettings: "",
}),
{
name: "question",
partialize: (state: QuestionStore) => {
if (isFirstPartialize) {
isFirstPartialize = false;
Object.keys(state.listQuestions).forEach((quizId) => {
[...state.listQuestions[quizId]].forEach(({ id, deleted }) => {
if (deleted) {
const removedItemIndex = state.listQuestions[quizId].findIndex(
(item) => item.id === id
);
state.listQuestions[quizId].splice(removedItemIndex, 1);
}
});
});
}
return state;
},
}
)
);
@ -222,11 +244,18 @@ export const copyQuestion = (quizId: number, copiedQuestionIndex: number) => {
questionStore.setState({ listQuestions });
};
export const removeQuestionForce = (quizId: number, removedId: number) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] };
const removedItemIndex = questionListClone[quizId].findIndex(
({ id }) => id === removedId
);
questionListClone[quizId].splice(removedItemIndex, 1);
questionStore.setState({ listQuestions: questionListClone });
};
export const removeQuestion = (quizId: number, index: number) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionListClone[quizId].splice(index, 1);
questionListClone[quizId][index].deleted = true;
questionStore.setState({ listQuestions: questionListClone });
};