fix conflicts
This commit is contained in:
parent
f463270a9b
commit
bf8a41a3bc
@ -1,10 +1,11 @@
|
|||||||
import { makeRequest } from "@frontend/kitui";
|
import { makeRequest } from "@frontend/kitui";
|
||||||
import { CreateQuestionRequest } from "model/question/create";
|
import { CreateQuestionRequest } from "model/question/create";
|
||||||
import { RawQuestion } from "model/question/question";
|
import { RawQuestion } from "model/question/question";
|
||||||
import { GetQuestionListRequest, GetQuestionListResponse } from "model/question/getList";
|
import { GetQuestionListRequest, GetQuestionListResponse } from "@model/question/getList";
|
||||||
import { EditQuestionRequest, EditQuestionResponse } from "model/question/edit";
|
import { EditQuestionRequest, EditQuestionResponse } from "@model/question/edit";
|
||||||
import { DeleteQuestionRequest, DeleteQuestionResponse } from "model/question/delete";
|
import { DeleteQuestionRequest, DeleteQuestionResponse } from "@model/question/delete";
|
||||||
import { CopyQuestionRequest, CopyQuestionResponse } from "model/question/copy";
|
import { CopyQuestionRequest, CopyQuestionResponse } from "@model/question/copy";
|
||||||
|
import { QUIZ_QUESTION_VARIANT } from "../constants/variant";
|
||||||
|
|
||||||
|
|
||||||
const baseUrl = process.env.NODE_ENV === "production" ? "/squiz" : "https://squiz.pena.digital/squiz";
|
const baseUrl = process.env.NODE_ENV === "production" ? "/squiz" : "https://squiz.pena.digital/squiz";
|
||||||
@ -70,16 +71,11 @@ const defaultCreateQuestionBody: CreateQuestionRequest = {
|
|||||||
"type": "variant",
|
"type": "variant",
|
||||||
"required": true,
|
"required": true,
|
||||||
"page": 0,
|
"page": 0,
|
||||||
"content": "string",
|
"content": JSON.stringify(QUIZ_QUESTION_VARIANT.content),
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultGetQuestionListBody: GetQuestionListRequest = {
|
const defaultGetQuestionListBody: GetQuestionListRequest = {
|
||||||
"limit": 0,
|
"limit": 0,
|
||||||
"offset": 0,
|
"offset": 0,
|
||||||
"from": 0,
|
"type": "",
|
||||||
"to": 0,
|
|
||||||
"search": "string",
|
|
||||||
"type": "string",
|
|
||||||
"deleted": true,
|
|
||||||
"required": true,
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { QUIZ_QUESTION_BASE } from "./base";
|
import { QUIZ_QUESTION_BASE } from "./base";
|
||||||
|
|
||||||
import type { QuizQuestionEmoji } from "../model/questionTypes/emoji";
|
import type { QuizQuestionEmoji } from "../model/questionTypes/emoji";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const QUIZ_QUESTION_EMOJI: Omit<QuizQuestionEmoji, "id"> = {
|
export const QUIZ_QUESTION_EMOJI: Omit<QuizQuestionEmoji, "id"> = {
|
||||||
...QUIZ_QUESTION_BASE,
|
...QUIZ_QUESTION_BASE,
|
||||||
@ -14,6 +15,7 @@ export const QUIZ_QUESTION_EMOJI: Omit<QuizQuestionEmoji, "id"> = {
|
|||||||
required: false,
|
required: false,
|
||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
|
id: nanoid(),
|
||||||
answer: "",
|
answer: "",
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
hints: ""
|
hints: ""
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { QUIZ_QUESTION_BASE } from "./base";
|
import { QUIZ_QUESTION_BASE } from "./base";
|
||||||
|
|
||||||
import type { QuizQuestionImages } from "../model/questionTypes/images";
|
import type { QuizQuestionImages } from "../model/questionTypes/images";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const QUIZ_QUESTION_IMAGES: Omit<QuizQuestionImages, "id"> = {
|
export const QUIZ_QUESTION_IMAGES: Omit<QuizQuestionImages, "id"> = {
|
||||||
...QUIZ_QUESTION_BASE,
|
...QUIZ_QUESTION_BASE,
|
||||||
@ -17,6 +18,7 @@ export const QUIZ_QUESTION_IMAGES: Omit<QuizQuestionImages, "id"> = {
|
|||||||
required: false,
|
required: false,
|
||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
|
id: nanoid(),
|
||||||
answer: "",
|
answer: "",
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
originalImageUrl: "",
|
originalImageUrl: "",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { QUIZ_QUESTION_BASE } from "./base";
|
import { QUIZ_QUESTION_BASE } from "./base";
|
||||||
|
|
||||||
import type { QuizQuestionSelect } from "../model/questionTypes/select";
|
import type { QuizQuestionSelect } from "../model/questionTypes/select";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const QUIZ_QUESTION_SELECT: Omit<QuizQuestionSelect, "id"> = {
|
export const QUIZ_QUESTION_SELECT: Omit<QuizQuestionSelect, "id"> = {
|
||||||
...QUIZ_QUESTION_BASE,
|
...QUIZ_QUESTION_BASE,
|
||||||
@ -12,6 +13,6 @@ export const QUIZ_QUESTION_SELECT: Omit<QuizQuestionSelect, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
default: "",
|
default: "",
|
||||||
variants: [{ answer: "", extendedText: "", hints: "" }],
|
variants: [{ id: nanoid(), answer: "", extendedText: "", hints: "" }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { QUIZ_QUESTION_BASE } from "./base";
|
import { QUIZ_QUESTION_BASE } from "./base";
|
||||||
|
|
||||||
import type { QuizQuestionVariant } from "../model/questionTypes/variant";
|
import type { QuizQuestionVariant } from "../model/questionTypes/variant";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const QUIZ_QUESTION_VARIANT: Omit<QuizQuestionVariant, "id"> = {
|
export const QUIZ_QUESTION_VARIANT: Omit<QuizQuestionVariant, "id"> = {
|
||||||
...QUIZ_QUESTION_BASE,
|
...QUIZ_QUESTION_BASE,
|
||||||
@ -13,6 +14,6 @@ export const QUIZ_QUESTION_VARIANT: Omit<QuizQuestionVariant, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
required: false,
|
required: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
variants: [{ answer: "", extendedText: "", hints: "" }],
|
variants: [{ id: nanoid(), answer: "", extendedText: "", hints: "" }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { QUIZ_QUESTION_BASE } from "./base";
|
import { QUIZ_QUESTION_BASE } from "./base";
|
||||||
|
|
||||||
import type { QuizQuestionVarImg } from "../model/questionTypes/varimg";
|
import type { QuizQuestionVarImg } from "../model/questionTypes/varimg";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
export const QUIZ_QUESTION_VARIMG: Omit<QuizQuestionVarImg, "id"> = {
|
export const QUIZ_QUESTION_VARIMG: Omit<QuizQuestionVarImg, "id"> = {
|
||||||
...QUIZ_QUESTION_BASE,
|
...QUIZ_QUESTION_BASE,
|
||||||
@ -11,7 +12,7 @@ export const QUIZ_QUESTION_VARIMG: Omit<QuizQuestionVarImg, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
required: false,
|
required: false,
|
||||||
variants: [{ answer: "", hints: "", extendedText: "", originalImageUrl: "" }],
|
variants: [{ id: nanoid(), answer: "", hints: "", extendedText: "", originalImageUrl: "" }],
|
||||||
largeCheck: false,
|
largeCheck: false,
|
||||||
replText: "",
|
replText: "",
|
||||||
},
|
},
|
||||||
|
@ -9,6 +9,7 @@ export interface EditQuestionRequest {
|
|||||||
type?: QuestionType;
|
type?: QuestionType;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
page?: number;
|
page?: number;
|
||||||
|
content: AnyQuizQuestion["content"];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditQuestionResponse {
|
export interface EditQuestionResponse {
|
||||||
@ -23,5 +24,6 @@ export function questionToEditQuestionRequest(question: AnyQuizQuestion): EditQu
|
|||||||
type: question.type,
|
type: question.type,
|
||||||
required: question.required,
|
required: question.required,
|
||||||
page: question.page,
|
page: question.page,
|
||||||
|
content: question.content,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RawQuestion } from "./question";
|
import { QuestionType, RawQuestion } from "./question";
|
||||||
|
|
||||||
|
|
||||||
export interface GetQuestionListRequest {
|
export interface GetQuestionListRequest {
|
||||||
@ -13,7 +13,7 @@ export interface GetQuestionListRequest {
|
|||||||
/** string for fulltext search in titles of questions */
|
/** string for fulltext search in titles of questions */
|
||||||
search?: string;
|
search?: string;
|
||||||
/** allow only - text, select, file, variant, images, varimg, emoji, date, number, page, rating or empty string */
|
/** allow only - text, select, file, variant, images, varimg, emoji, date, number, page, rating or empty string */
|
||||||
type?: string;
|
type: "" | QuestionType;
|
||||||
/** get deleted quizes */
|
/** get deleted quizes */
|
||||||
deleted?: boolean;
|
deleted?: boolean;
|
||||||
/** get only require questions */
|
/** get only require questions */
|
||||||
|
@ -43,7 +43,7 @@ export const AnswerItem = ({
|
|||||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
const setQuestionVariantAnswer = useDebouncedCallback((value) => {
|
const setQuestionVariantAnswer = useDebouncedCallback((value) => {
|
||||||
setQuestionVariantField(questionId, variant.id,"answer", value);
|
setQuestionVariantField(questionId, variant.id, "answer", value);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import { AnyQuizQuestion } from "@model/questionTypes/shared";
|
||||||
import { Box, ListItem, Typography, useTheme } from "@mui/material";
|
import { Box, ListItem, Typography, useTheme } from "@mui/material";
|
||||||
import { memo } from "react";
|
import { memo } from "react";
|
||||||
import { Draggable } from "react-beautiful-dnd";
|
import { Draggable } from "react-beautiful-dnd";
|
||||||
import QuestionsPageCard from "./QuestionPageCard";
|
import QuestionsPageCard from "./QuestionPageCard";
|
||||||
import { AnyQuizQuestion } from "@model/questionTypes/shared";
|
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -22,7 +22,7 @@ function DraggableListItem({ question, isDragging, index }: Props) {
|
|||||||
{...provided.draggableProps}
|
{...provided.draggableProps}
|
||||||
sx={{ userSelect: "none", padding: 0 }}
|
sx={{ userSelect: "none", padding: 0 }}
|
||||||
>
|
>
|
||||||
{/* questionData.deleted TODO */ true ? (
|
{question.deleted ? (
|
||||||
<Box
|
<Box
|
||||||
{...provided.dragHandleProps}
|
{...provided.dragHandleProps}
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -1,17 +1,3 @@
|
|||||||
import {
|
|
||||||
Box,
|
|
||||||
Checkbox,
|
|
||||||
FormControl,
|
|
||||||
FormControlLabel,
|
|
||||||
IconButton,
|
|
||||||
InputAdornment,
|
|
||||||
Paper,
|
|
||||||
TextField,
|
|
||||||
useMediaQuery,
|
|
||||||
useTheme,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { useRef, useState } from "react";
|
|
||||||
import { useDebouncedCallback } from "use-debounce";
|
|
||||||
import { CrossedEyeIcon } from "@icons/CrossedEyeIcon";
|
import { CrossedEyeIcon } from "@icons/CrossedEyeIcon";
|
||||||
import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon";
|
import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon";
|
||||||
import { CopyIcon } from "@icons/questionsPage/CopyIcon";
|
import { CopyIcon } from "@icons/questionsPage/CopyIcon";
|
||||||
@ -31,8 +17,22 @@ import Page from "@icons/questionsPage/page";
|
|||||||
import RatingIcon from "@icons/questionsPage/rating";
|
import RatingIcon from "@icons/questionsPage/rating";
|
||||||
import Slider from "@icons/questionsPage/slider";
|
import Slider from "@icons/questionsPage/slider";
|
||||||
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
||||||
import { copyQuestion, createQuestion, deleteQuestion, toggleExpandQuestion } from "@root/questions/actions";
|
import {
|
||||||
|
Box,
|
||||||
|
Checkbox,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
IconButton,
|
||||||
|
InputAdornment,
|
||||||
|
Paper,
|
||||||
|
TextField,
|
||||||
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { copyQuestion, createQuestion, deleteQuestion, toggleExpandQuestion, updateQuestionWithFnOptimistic } from "@root/questions/actions";
|
||||||
|
import { useRef, useState } from "react";
|
||||||
import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
|
import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
import { ReactComponent as PlusIcon } from "../../../assets/icons/plus.svg";
|
import { ReactComponent as PlusIcon } from "../../../assets/icons/plus.svg";
|
||||||
import type { AnyQuizQuestion } from "../../../model/questionTypes/shared";
|
import type { AnyQuizQuestion } from "../../../model/questionTypes/shared";
|
||||||
import SwitchQuestionsPage from "../SwitchQuestionsPage";
|
import SwitchQuestionsPage from "../SwitchQuestionsPage";
|
||||||
@ -52,8 +52,11 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
|
|||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const anchorRef = useRef(null);
|
const anchorRef = useRef(null);
|
||||||
const debounced = useDebouncedCallback((title) => { // TODO update title
|
|
||||||
// updateQuestionsList<QuizQuestionInitial>(quizId, totalIndex, { title });
|
const setTitle = useDebouncedCallback((title) => {
|
||||||
|
updateQuestionWithFnOptimistic(question.id, question => {
|
||||||
|
question.title = title;
|
||||||
|
});
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -88,8 +91,8 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
|
|||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
defaultValue={question.title}
|
defaultValue={question.title}
|
||||||
placeholder={"Заголовок вопроса"}
|
placeholder={"Заголовок вопроса2"}
|
||||||
onChange={({ target }) => debounced(target.value)}
|
onChange={({ target }) => setTitle(target.value)}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<Box>
|
<Box>
|
||||||
|
@ -1,38 +1,29 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Typography,
|
|
||||||
Popper,
|
|
||||||
Grow,
|
|
||||||
Paper,
|
|
||||||
MenuList,
|
|
||||||
MenuItem,
|
|
||||||
ClickAwayListener,
|
|
||||||
Modal,
|
|
||||||
Button,
|
Button,
|
||||||
|
ClickAwayListener,
|
||||||
|
Grow,
|
||||||
|
MenuItem,
|
||||||
|
MenuList,
|
||||||
|
Modal,
|
||||||
|
Paper,
|
||||||
|
Popper,
|
||||||
|
Typography,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
import {
|
|
||||||
questionStore,
|
|
||||||
updateQuestionsList,
|
|
||||||
removeQuestionForce,
|
|
||||||
createQuestion,
|
|
||||||
} from "@root/questions";
|
|
||||||
import { BUTTON_TYPE_QUESTIONS } from "../../TypeQuestions";
|
import { BUTTON_TYPE_QUESTIONS } from "../../TypeQuestions";
|
||||||
|
|
||||||
import type { RefObject } from "react";
|
|
||||||
import type {
|
|
||||||
QuizQuestionBase,
|
|
||||||
} from "../../../../model/questionTypes/shared";
|
|
||||||
import { QuestionType } from "@model/question/question";
|
import { QuestionType } from "@model/question/question";
|
||||||
|
import { updateQuestionWithFnOptimistic } from "@root/questions/actions";
|
||||||
|
import type { RefObject } from "react";
|
||||||
|
import type { AnyQuizQuestion } from "../../../../model/questionTypes/shared";
|
||||||
|
|
||||||
|
|
||||||
type ChooseAnswerModalProps = {
|
type ChooseAnswerModalProps = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
anchorRef: RefObject<HTMLDivElement>;
|
anchorRef: RefObject<HTMLDivElement>;
|
||||||
totalIndex: number;
|
question: AnyQuizQuestion;
|
||||||
switchState: string;
|
switchState: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,13 +31,11 @@ export const ChooseAnswerModal = ({
|
|||||||
open,
|
open,
|
||||||
onClose,
|
onClose,
|
||||||
anchorRef,
|
anchorRef,
|
||||||
totalIndex,
|
question,
|
||||||
switchState,
|
switchState,
|
||||||
}: ChooseAnswerModalProps) => {
|
}: ChooseAnswerModalProps) => {
|
||||||
const [openModal, setOpenModal] = useState<boolean>(false);
|
const [openModal, setOpenModal] = useState<boolean>(false);
|
||||||
const [selectedValue, setSelectedValue] = useState<QuestionType>("text");
|
const [selectedValue, setSelectedValue] = useState<QuestionType>("text");
|
||||||
const quizId = Number(useParams().quizId);
|
|
||||||
const { listQuestions } = questionStore();
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -129,12 +118,8 @@ export const ChooseAnswerModal = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setOpenModal(false);
|
setOpenModal(false);
|
||||||
|
|
||||||
const question = { ...listQuestions[quizId][totalIndex] };
|
updateQuestionWithFnOptimistic(question.id, question => {
|
||||||
|
question.type = selectedValue;
|
||||||
removeQuestionForce(quizId, question.id);
|
|
||||||
createQuestion(quizId, selectedValue, totalIndex);
|
|
||||||
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
|
|
||||||
expanded: question.expanded,
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -2,30 +2,28 @@ import { memo } from "react";
|
|||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { Draggable } from "react-beautiful-dnd";
|
import { Draggable } from "react-beautiful-dnd";
|
||||||
import { Box, ListItem, Typography, useTheme } from "@mui/material";
|
import { Box, ListItem, Typography, useTheme } from "@mui/material";
|
||||||
|
|
||||||
import QuestionsPageCard from "./QuestionPageCard";
|
import QuestionsPageCard from "./QuestionPageCard";
|
||||||
|
|
||||||
import { updateQuestionsList } from "@root/questions";
|
import { updateQuestionsList } from "@root/questions";
|
||||||
|
import { AnyQuizQuestion, QuizQuestionBase } from "../../../../model/questionTypes/shared";
|
||||||
|
|
||||||
import { QuizQuestionBase } from "../../../../model/questionTypes/shared";
|
|
||||||
|
|
||||||
type FormDraggableListItemProps = {
|
type FormDraggableListItemProps = {
|
||||||
index: number;
|
question: AnyQuizQuestion;
|
||||||
isDragging: boolean;
|
questionIndex: number;
|
||||||
questionData: QuizQuestionBase;
|
questionData: QuizQuestionBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(
|
export default memo(
|
||||||
({ index, isDragging, questionData }: FormDraggableListItemProps) => {
|
({ question, questionIndex, questionData }: FormDraggableListItemProps) => {
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable draggableId={String(index)} index={index}>
|
<Draggable draggableId={String(questionIndex)} index={questionIndex}>
|
||||||
{(provided) => (
|
{(provided) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
{...(index !== 0 ? provided.draggableProps : {})}
|
{...(questionIndex !== 0 ? provided.draggableProps : {})}
|
||||||
sx={{ userSelect: "none", padding: 0 }}
|
sx={{ userSelect: "none", padding: 0 }}
|
||||||
>
|
>
|
||||||
{questionData.deleted ? (
|
{questionData.deleted ? (
|
||||||
@ -50,7 +48,7 @@ export default memo(
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
updateQuestionsList<QuizQuestionBase>(quizId, index, {
|
updateQuestionsList<QuizQuestionBase>(quizId, questionIndex, {
|
||||||
...questionData,
|
...questionData,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
});
|
});
|
||||||
@ -75,8 +73,9 @@ export default memo(
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<QuestionsPageCard
|
<QuestionsPageCard
|
||||||
key={index}
|
key={questionIndex}
|
||||||
question={question}
|
question={question}
|
||||||
|
questionIndex={questionIndex}
|
||||||
draggableProps={provided.dragHandleProps}
|
draggableProps={provided.dragHandleProps}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -24,11 +24,13 @@ import { ChooseAnswerModal } from "./ChooseAnswerModal";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: AnyQuizQuestion;
|
question: AnyQuizQuestion;
|
||||||
|
questionIndex: number;
|
||||||
draggableProps: DraggableProvidedDragHandleProps | null | undefined;
|
draggableProps: DraggableProvidedDragHandleProps | null | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QuestionsPageCard({
|
export default function QuestionsPageCard({
|
||||||
question,
|
question,
|
||||||
|
questionIndex,
|
||||||
draggableProps,
|
draggableProps,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
@ -64,7 +66,7 @@ export default function QuestionsPageCard({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
placeholder={`Заголовок ${totalIndex + 1} вопроса`}
|
placeholder={`Заголовок ${questionIndex + 1} вопроса`}
|
||||||
text={question.title}
|
text={question.title}
|
||||||
onChange={({ target }) => setTitle(target.value)}
|
onChange={({ target }) => setTitle(target.value)}
|
||||||
sx={{ margin: "20px", width: "auto" }}
|
sx={{ margin: "20px", width: "auto" }}
|
||||||
@ -90,7 +92,7 @@ export default function QuestionsPageCard({
|
|||||||
),
|
),
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
<Box {...draggableProps}>
|
<Box {...draggableProps}>
|
||||||
{totalIndex !== 0 && (
|
{questionIndex !== 0 && (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<PointsIcon
|
<PointsIcon
|
||||||
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
||||||
|
@ -3,10 +3,26 @@ import type { DropResult } from "react-beautiful-dnd";
|
|||||||
import { DragDropContext, Droppable } from "react-beautiful-dnd";
|
import { DragDropContext, Droppable } from "react-beautiful-dnd";
|
||||||
import FormDraggableListItem from "./FormDraggableListItem";
|
import FormDraggableListItem from "./FormDraggableListItem";
|
||||||
import { useQuestionsStore } from "@root/questions/store";
|
import { useQuestionsStore } from "@root/questions/store";
|
||||||
import { reorderQuestions } from "@root/questions/actions";
|
import { reorderQuestions, setQuestions } from "@root/questions/actions";
|
||||||
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
|
import useSWR from "swr";
|
||||||
|
import { questionApi } from "@api/question";
|
||||||
|
import { devlog } from "@frontend/kitui";
|
||||||
|
import { isAxiosError } from "axios";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
|
|
||||||
export const FormDraggableList = () => {
|
export const FormDraggableList = () => {
|
||||||
|
const { quiz } = useCurrentQuiz();
|
||||||
|
useSWR(["questions", quiz?.id], ([, id]) => questionApi.getList({ quiz_id: id }), {
|
||||||
|
onSuccess: setQuestions,
|
||||||
|
onError: error => {
|
||||||
|
const message = isAxiosError<string>(error) ? (error.response?.data ?? "") : "";
|
||||||
|
|
||||||
|
devlog("Error getting question list", error);
|
||||||
|
enqueueSnackbar(`Не удалось получить вопросы. ${message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
const questions = useQuestionsStore(state => state.questions);
|
const questions = useQuestionsStore(state => state.questions);
|
||||||
|
|
||||||
const onDragEnd = ({ destination, source }: DropResult) => {
|
const onDragEnd = ({ destination, source }: DropResult) => {
|
||||||
@ -16,13 +32,13 @@ export const FormDraggableList = () => {
|
|||||||
return (
|
return (
|
||||||
<DragDropContext onDragEnd={onDragEnd}>
|
<DragDropContext onDragEnd={onDragEnd}>
|
||||||
<Droppable droppableId="droppable-list">
|
<Droppable droppableId="droppable-list">
|
||||||
{(provided, snapshot) => (
|
{(provided) => (
|
||||||
<Box ref={provided.innerRef} {...provided.droppableProps}>
|
<Box ref={provided.innerRef} {...provided.droppableProps}>
|
||||||
{questions.map((question, index) => (
|
{questions.map((question, index) => (
|
||||||
<FormDraggableListItem
|
<FormDraggableListItem
|
||||||
key={index}
|
key={question.id}
|
||||||
index={index}
|
question={question}
|
||||||
isDragging={snapshot.isDraggingOver}
|
questionIndex={index}
|
||||||
questionData={question}
|
questionData={question}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -839,7 +839,6 @@ export default function StartPageSettings() {
|
|||||||
quiz.config.startpage.background.video = "https://youtu.be/dbaPkCiLPKQ";
|
quiz.config.startpage.background.video = "https://youtu.be/dbaPkCiLPKQ";
|
||||||
});
|
});
|
||||||
incrementCurrentStep();
|
incrementCurrentStep();
|
||||||
// TODO create new question
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Настроить вопросы
|
Настроить вопросы
|
||||||
|
@ -5,7 +5,7 @@ import { QuestionType, RawQuestion, rawQuestionToQuestion } from "@model/questio
|
|||||||
import { AnyQuizQuestion, ImageQuestionVariant, QuestionVariant, createQuestionImageVariant, createQuestionVariant } from "@model/questionTypes/shared";
|
import { AnyQuizQuestion, ImageQuestionVariant, QuestionVariant, createQuestionImageVariant, createQuestionVariant } from "@model/questionTypes/shared";
|
||||||
import { produce } from "immer";
|
import { produce } from "immer";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { notReachable } from "utils/notReachable";
|
import { notReachable } from "../../utils/notReachable";
|
||||||
import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError";
|
import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError";
|
||||||
import { QuestionsStore, useQuestionsStore } from "./store";
|
import { QuestionsStore, useQuestionsStore } from "./store";
|
||||||
|
|
||||||
@ -25,6 +25,13 @@ const setQuestion = (question: AnyQuizQuestion) => setProducedState(state => {
|
|||||||
question,
|
question,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const addQuestion = (question: AnyQuizQuestion) => setProducedState(state => {
|
||||||
|
state.questions.push(question);
|
||||||
|
}, {
|
||||||
|
type: "addQuestion",
|
||||||
|
question,
|
||||||
|
});
|
||||||
|
|
||||||
const removeQuestion = (questionId: number) => setProducedState(state => {
|
const removeQuestion = (questionId: number) => setProducedState(state => {
|
||||||
const index = state.questions.findIndex(q => q.id === questionId);
|
const index = state.questions.findIndex(q => q.id === questionId);
|
||||||
state.questions.splice(index, 1);
|
state.questions.splice(index, 1);
|
||||||
@ -322,7 +329,7 @@ export const createQuestion = async (quizId: number, type: QuestionType = "varia
|
|||||||
type,
|
type,
|
||||||
});
|
});
|
||||||
|
|
||||||
setQuestion(rawQuestionToQuestion(question));
|
addQuestion(rawQuestionToQuestion(question));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
devlog("Error creating question", error);
|
devlog("Error creating question", error);
|
||||||
enqueueSnackbar("Не удалось создать вопрос");
|
enqueueSnackbar("Не удалось создать вопрос");
|
||||||
|
@ -13,6 +13,9 @@ import { createQuestion } from "@root/questions/actions";
|
|||||||
|
|
||||||
export const setEditQuizId = (quizId: number | null) => setProducedState(state => {
|
export const setEditQuizId = (quizId: number | null) => setProducedState(state => {
|
||||||
state.editQuizId = quizId;
|
state.editQuizId = quizId;
|
||||||
|
}, {
|
||||||
|
type: "setEditQuizId",
|
||||||
|
quizId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const resetEditConfig = () => setProducedState(state => {
|
export const resetEditConfig = () => setProducedState(state => {
|
||||||
|
Loading…
Reference in New Issue
Block a user