новый ответ на вопрос получает фокус
This commit is contained in:
parent
751d9eb4f3
commit
862ed4f395
@ -12,7 +12,7 @@ import {
|
||||
} from "@mui/material";
|
||||
import { addQuestionVariant, deleteQuestionVariant, setQuestionVariantField, updateQuestion } from "@root/questions/actions";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { memo, type ChangeEvent, type FC, type KeyboardEvent, type ReactNode } from "react";
|
||||
import { memo, useCallback, type ChangeEvent, type FC, type KeyboardEvent, type ReactNode } from "react";
|
||||
import { Draggable } from "react-beautiful-dnd";
|
||||
import type { QuestionVariant, QuizQuestionVariant } from "@frontend/squzanswerer";
|
||||
|
||||
@ -28,10 +28,13 @@ type AnswerItemProps = {
|
||||
additionalMobile?: ReactNode;
|
||||
isOwn: boolean;
|
||||
ownPlaceholder: string;
|
||||
shouldAutoFocus?: boolean;
|
||||
onFocusHandled?: () => void;
|
||||
onEnterKeyPress?: () => void;
|
||||
};
|
||||
|
||||
const AnswerItem = memo<AnswerItemProps>(
|
||||
({ index, variant, questionId, largeCheck = false, additionalContent, additionalMobile, disableKeyDown, isOwn, ownPlaceholder }) => {
|
||||
({ index, variant, questionId, largeCheck = false, additionalContent, additionalMobile, disableKeyDown, isOwn, ownPlaceholder, shouldAutoFocus, onFocusHandled, onEnterKeyPress }) => {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(790));
|
||||
|
||||
@ -41,6 +44,26 @@ const AnswerItem = memo<AnswerItemProps>(
|
||||
});
|
||||
};
|
||||
|
||||
const inputRefCallback = useCallback((element: HTMLInputElement | null) => {
|
||||
if (element && shouldAutoFocus) {
|
||||
element.focus();
|
||||
onFocusHandled?.();
|
||||
}
|
||||
}, [shouldAutoFocus, onFocusHandled]);
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (disableKeyDown) {
|
||||
enqueueSnackbar("100 максимальное количество");
|
||||
} else if (event.code === "Enter" && !largeCheck) {
|
||||
if (onEnterKeyPress) {
|
||||
onEnterKeyPress();
|
||||
} else {
|
||||
// Fallback если onEnterKeyPress не передан
|
||||
addQuestionVariant(questionId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Draggable
|
||||
@ -64,10 +87,11 @@ const AnswerItem = memo<AnswerItemProps>(
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
inputRef={inputRefCallback}
|
||||
value={isOwn ? ownPlaceholder : variant.answer}
|
||||
fullWidth
|
||||
focused={false}
|
||||
placeholder={isOwn ? "Добавьте текст-подсказку для ввода “своего ответа”" : "Добавьте ответ"}
|
||||
placeholder={isOwn ? "Добавьте текст-подсказку для ввода \"своего ответа\"" : "Добавьте ответ"}
|
||||
multiline={largeCheck}
|
||||
onChange={({ target }: ChangeEvent<HTMLInputElement>) => {
|
||||
if (target.value.length <= 1000) {
|
||||
@ -79,13 +103,7 @@ const AnswerItem = memo<AnswerItemProps>(
|
||||
enqueueSnackbar("Превышена длина вводимого текста")
|
||||
}
|
||||
}}
|
||||
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
|
||||
if (disableKeyDown) {
|
||||
enqueueSnackbar("100 максимальное количество");
|
||||
} else if (event.code === "Enter" && !largeCheck) {
|
||||
addQuestionVariant(questionId);
|
||||
}
|
||||
}}
|
||||
onKeyDown={handleKeyDown}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<>
|
||||
|
||||
@ -16,6 +16,9 @@ type Props = Omit<
|
||||
openImageUploadModal: () => void;
|
||||
isOwn: boolean;
|
||||
ownPlaceholder: string;
|
||||
shouldAutoFocus?: boolean;
|
||||
onFocusHandled?: () => void;
|
||||
onEnterKeyPress?: () => void;
|
||||
};
|
||||
|
||||
export default function ImageEditAnswerItem({
|
||||
@ -31,6 +34,9 @@ export default function ImageEditAnswerItem({
|
||||
openImageUploadModal,
|
||||
isOwn,
|
||||
ownPlaceholder,
|
||||
shouldAutoFocus,
|
||||
onFocusHandled,
|
||||
onEnterKeyPress,
|
||||
}: Props) {
|
||||
const addOrEditImageButton = useMemo(() => {
|
||||
return (
|
||||
@ -111,6 +117,9 @@ export default function ImageEditAnswerItem({
|
||||
additionalMobile={addOrEditImageButtonMobile}
|
||||
isOwn={isOwn}
|
||||
ownPlaceholder={ownPlaceholder}
|
||||
shouldAutoFocus={shouldAutoFocus}
|
||||
onFocusHandled={onFocusHandled}
|
||||
onEnterKeyPress={onEnterKeyPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Box, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { useCallback, useState } from "react";
|
||||
import { EnterIcon } from "@/assets/icons/questionsPage/enterIcon";
|
||||
import { useAddAnswer } from "../../../utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "../../../utils/questionVariants";
|
||||
import { AnswerDraggableList } from "../AnswerDraggableList";
|
||||
import ButtonsOptions from "../QuestionOptions/ButtonsLayout/ButtonsOptions";
|
||||
import SwitchDropDown from "./switchDropDown";
|
||||
@ -16,7 +16,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function DropDown({ question, openBranchingPage, setOpenBranchingPage }: Props) {
|
||||
const {onClickAddAnAnswer} = useAddAnswer();
|
||||
const {addVariantWithFocus, addVariantOnEnter, focusedVariantId, clearFocusedVariant} = useQuestionVariantsWithFocus();
|
||||
const [switchState, setSwitchState] = useState("setting");
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
@ -50,6 +50,11 @@ export default function DropDown({ question, openBranchingPage, setOpenBranching
|
||||
disableKeyDown={question.content.variants.length >= 100}
|
||||
questionId={question.id}
|
||||
variant={variant}
|
||||
isOwn={Boolean(variant?.isOwn)}
|
||||
ownPlaceholder={question.content.ownPlaceholder || ""}
|
||||
shouldAutoFocus={focusedVariantId === variant.id}
|
||||
onFocusHandled={clearFocusedVariant}
|
||||
onEnterKeyPress={() => addVariantOnEnter(question.id)}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@ -71,7 +76,7 @@ export default function DropDown({ question, openBranchingPage, setOpenBranching
|
||||
mr: "4px",
|
||||
height: "19px",
|
||||
}}
|
||||
onClick={() => onClickAddAnAnswer(question)}
|
||||
onClick={() => addVariantWithFocus(question)}
|
||||
>
|
||||
Добавьте ответ
|
||||
</Link>
|
||||
|
||||
@ -4,7 +4,7 @@ import { EmojiPicker } from "@ui_kit/EmojiPicker";
|
||||
import { useState } from "react";
|
||||
import { EnterIcon } from "@/assets/icons/questionsPage/enterIcon";
|
||||
import type { QuizQuestionEmoji } from "@frontend/squzanswerer";
|
||||
import { useAddAnswer } from "../../../utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "../../../utils/questionVariants";
|
||||
import { AnswerDraggableList } from "../AnswerDraggableList";
|
||||
import ButtonsOptions from "../QuestionOptions/ButtonsLayout/ButtonsOptions";
|
||||
import EmojiAnswerItem from "./EmojiAnswerItem/EmojiAnswerItem";
|
||||
@ -19,7 +19,7 @@ interface Props {
|
||||
|
||||
export default function Emoji({ question, openBranchingPage, setOpenBranchingPage }: Props) {
|
||||
const [switchState, setSwitchState] = useState<string>("setting");
|
||||
const {onClickAddAnAnswer} = useAddAnswer();
|
||||
const {addVariantWithFocus, addVariantOnEnter, focusedVariantId, clearFocusedVariant} = useQuestionVariantsWithFocus();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [anchorElement, setAnchorElement] = useState<HTMLDivElement | null>(null);
|
||||
const [selectedVariant, setSelectedVariant] = useState<string | null>(null);
|
||||
@ -48,6 +48,9 @@ export default function Emoji({ question, openBranchingPage, setOpenBranchingPag
|
||||
setSelectedVariant={setSelectedVariant}
|
||||
isOwn={Boolean(variant?.isOwn)}
|
||||
ownPlaceholder={question.content.ownPlaceholder}
|
||||
shouldAutoFocus={focusedVariantId === variant.id}
|
||||
onFocusHandled={clearFocusedVariant}
|
||||
onEnterKeyPress={() => addVariantOnEnter(question.id)}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@ -93,7 +96,7 @@ export default function Emoji({ question, openBranchingPage, setOpenBranchingPag
|
||||
component="button"
|
||||
variant="body2"
|
||||
sx={{ color: theme.palette.brightPurple.main }}
|
||||
onClick={() => onClickAddAnAnswer(question)}
|
||||
onClick={() => addVariantWithFocus(question)}
|
||||
>
|
||||
Добавьте ответ
|
||||
</Link>
|
||||
|
||||
@ -14,6 +14,9 @@ type Props = Omit<
|
||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
isOwn: boolean;
|
||||
ownPlaceholder: string;
|
||||
shouldAutoFocus?: boolean;
|
||||
onFocusHandled?: () => void;
|
||||
onEnterKeyPress?: () => void;
|
||||
};
|
||||
|
||||
export default function EmojiAnswerItem({
|
||||
@ -28,6 +31,9 @@ export default function EmojiAnswerItem({
|
||||
setOpen,
|
||||
isOwn,
|
||||
ownPlaceholder,
|
||||
shouldAutoFocus,
|
||||
onFocusHandled,
|
||||
onEnterKeyPress,
|
||||
}: Props) {
|
||||
|
||||
|
||||
@ -99,6 +105,9 @@ export default function EmojiAnswerItem({
|
||||
additionalMobile={addOrEditImageButtonMobile}
|
||||
isOwn={isOwn}
|
||||
ownPlaceholder={ownPlaceholder}
|
||||
shouldAutoFocus={shouldAutoFocus}
|
||||
onFocusHandled={onFocusHandled}
|
||||
onEnterKeyPress={onEnterKeyPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { updateQuestion } from "@root/questions/actions";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import { memo } from "react";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
|
||||
type SettingEmojiProps = {
|
||||
question: QuizQuestionEmoji;
|
||||
@ -17,7 +17,7 @@ type SettingEmojiProps = {
|
||||
|
||||
const SettingEmoji = memo<SettingEmojiProps>(function ({ question, questionId, isRequired, isLargeCheck, isMulti, isOwn }) {
|
||||
const theme = useTheme();
|
||||
const {switchOwn} = useAddAnswer();
|
||||
const {switchOwnVariant} = useQuestionVariantsWithFocus();
|
||||
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990));
|
||||
@ -92,7 +92,7 @@ const SettingEmoji = memo<SettingEmojiProps>(function ({ question, questionId, i
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={isOwn}
|
||||
handleChange={({ target }) => {
|
||||
switchOwn({question, checked:target.checked})
|
||||
switchOwnVariant({question, checked:target.checked})
|
||||
}}
|
||||
/>
|
||||
{/* <Box sx={{ mt: isMobile ? "11px" : "6px", width: "100%" }}>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Box, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import {
|
||||
addQuestionVariant,
|
||||
clearQuestionImages,
|
||||
uploadQuestionImage,
|
||||
} from "@root/questions/actions";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { EnterIcon } from "@/assets/icons/questionsPage/enterIcon";
|
||||
@ -31,6 +31,7 @@ export default function OptionsAndPicture({
|
||||
const [switchState, setSwitchState] = useState("setting");
|
||||
const [pictureUploding, setPictureUploading] = useState<boolean>(false);
|
||||
const [openCropModal, setOpenCropModal] = useState(false);
|
||||
const {addVariantWithFocus, addVariantOnEnter, focusedVariantId, clearFocusedVariant} = useQuestionVariantsWithFocus();
|
||||
|
||||
const [selectedVariantId, setSelectedVariantId] = useState<string | null>(
|
||||
null,
|
||||
@ -111,6 +112,9 @@ export default function OptionsAndPicture({
|
||||
setSelectedVariantId={setSelectedVariantId}
|
||||
isOwn={Boolean(variant?.isOwn)}
|
||||
ownPlaceholder={question.content.ownPlaceholder}
|
||||
shouldAutoFocus={focusedVariantId === variant.id}
|
||||
onFocusHandled={clearFocusedVariant}
|
||||
onEnterKeyPress={() => addVariantOnEnter(question.id)}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@ -148,7 +152,7 @@ export default function OptionsAndPicture({
|
||||
height: "19px",
|
||||
}}
|
||||
onClick={() => {
|
||||
addQuestionVariant(question.id);
|
||||
addVariantWithFocus(question);
|
||||
}}
|
||||
>
|
||||
Добавьте ответ
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
import type { QuizQuestionVarImg, QuizQuestionVariant } from "@frontend/squzanswerer";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { updateQuestion } from "@root/questions/actions";
|
||||
@ -19,7 +19,7 @@ type SettingOptionsAndPictProps = {
|
||||
|
||||
const SettingOptionsAndPict = memo<SettingOptionsAndPictProps>(function ({ question, questionId, ownPlaceholder, isMulti, isLargeCheck, replText, isRequired, isOwn }) {
|
||||
const theme = useTheme();
|
||||
const { switchOwn } = useAddAnswer();
|
||||
const { switchOwnVariant } = useQuestionVariantsWithFocus();
|
||||
|
||||
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
|
||||
const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990));
|
||||
@ -73,7 +73,7 @@ const SettingOptionsAndPict = memo<SettingOptionsAndPictProps>(function ({ quest
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={isOwn}
|
||||
handleChange={({ target }) => {
|
||||
switchOwn({ question, checked: target.checked })
|
||||
switchOwnVariant({ question, checked: target.checked })
|
||||
}}
|
||||
/>
|
||||
<CustomCheckbox
|
||||
|
||||
@ -9,7 +9,7 @@ import { EnterIcon } from "@/assets/icons/questionsPage/enterIcon";
|
||||
import type { QuizQuestionVarImg } from "@frontend/squzanswerer/dist-package/model/questionTypes/varimg";
|
||||
|
||||
//@/model/questionTypes/images";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
import { useDisclosure } from "@/utils/useDisclosure";
|
||||
import { AnswerDraggableList } from "../../AnswerDraggableList";
|
||||
import ImageEditAnswerItem from "../../AnswerDraggableList/ImageEditAnswerItem";
|
||||
@ -31,7 +31,7 @@ export default function OptionsPicture({
|
||||
setOpenBranchingPage,
|
||||
}: Props) {
|
||||
const theme = useTheme();
|
||||
const {onClickAddAnAnswer} = useAddAnswer();
|
||||
const {addVariantWithFocus, addVariantOnEnter, focusedVariantId, clearFocusedVariant} = useQuestionVariantsWithFocus();
|
||||
const quizQid = useCurrentQuiz()?.qid;
|
||||
const [pictureUploding, setPictureUploading] = useState<boolean>(false);
|
||||
const [openCropModal, setOpenCropModal] = useState(false);
|
||||
@ -93,6 +93,9 @@ export default function OptionsPicture({
|
||||
setSelectedVariantId={setSelectedVariantId}
|
||||
isOwn={Boolean(variant?.isOwn)}
|
||||
ownPlaceholder={question.content.ownPlaceholder}
|
||||
shouldAutoFocus={focusedVariantId === variant.id}
|
||||
onFocusHandled={clearFocusedVariant}
|
||||
onEnterKeyPress={() => addVariantOnEnter(question.id)}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@ -117,7 +120,7 @@ export default function OptionsPicture({
|
||||
component="button"
|
||||
variant="body2"
|
||||
sx={{ color: theme.palette.brightPurple.main }}
|
||||
onClick={() => onClickAddAnAnswer(question)}
|
||||
onClick={() => addVariantWithFocus(question)}
|
||||
>
|
||||
Добавьте ответ
|
||||
</Link>
|
||||
|
||||
@ -9,7 +9,7 @@ import ProportionsIcon11 from "@/assets/icons/questionsPage/ProportionsIcon11";
|
||||
import ProportionsIcon12 from "@/assets/icons/questionsPage/ProportionsIcon12";
|
||||
import ProportionsIcon21 from "@/assets/icons/questionsPage/ProportionsIcon21";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
|
||||
type Proportion = "1:1" | "1:2" | "2:1";
|
||||
|
||||
@ -69,7 +69,7 @@ const SettingOptionsPict = memo<SettingOptionsPictProps>(function ({
|
||||
question.content.ownPlaceholder = replText;
|
||||
});
|
||||
};
|
||||
const {switchOwn} = useAddAnswer();
|
||||
const {switchOwnVariant} = useQuestionVariantsWithFocus();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -175,7 +175,7 @@ const SettingOptionsPict = memo<SettingOptionsPictProps>(function ({
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={isOwn}
|
||||
handleChange={({ target }) => {
|
||||
switchOwn({question, checked:target.checked})
|
||||
switchOwnVariant({question, checked:target.checked})
|
||||
}}
|
||||
/>
|
||||
{/* <Box sx={{ mt: isMobile ? "11px" : "6px", width: "100%" }}>
|
||||
|
||||
@ -9,7 +9,7 @@ import ProportionsIcon11 from "@/assets/icons/questionsPage/ProportionsIcon11";
|
||||
import ProportionsIcon12 from "@/assets/icons/questionsPage/ProportionsIcon12";
|
||||
import ProportionsIcon21 from "@/assets/icons/questionsPage/ProportionsIcon21";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
|
||||
type Proportion = "1:1" | "1:2" | "2:1";
|
||||
|
||||
@ -69,7 +69,7 @@ const SettingOptionsPict = memo<SettingOptionsPictProps>(function ({
|
||||
question.content.ownPlaceholder = replText;
|
||||
});
|
||||
};
|
||||
const {switchOwn} = useAddAnswer();
|
||||
const {switchOwnVariant} = useQuestionVariantsWithFocus();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -175,7 +175,7 @@ const SettingOptionsPict = memo<SettingOptionsPictProps>(function ({
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={isOwn}
|
||||
handleChange={({ target }) => {
|
||||
switchOwn({question, checked:target.checked})
|
||||
switchOwnVariant({question, checked:target.checked})
|
||||
}}
|
||||
/>
|
||||
{/* <Box sx={{ mt: isMobile ? "11px" : "6px", width: "100%" }}>
|
||||
|
||||
@ -2,7 +2,7 @@ import { Box, Link, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { EnterIcon } from "@/assets/icons/questionsPage/enterIcon";
|
||||
import type { QuizQuestionVariant } from "@frontend/squzanswerer";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
import { AnswerDraggableList } from "../../AnswerDraggableList";
|
||||
import AnswerItem from "../../AnswerDraggableList/AnswerItem";
|
||||
import ButtonsOptions from "../ButtonsLayout/ButtonsOptions";
|
||||
@ -15,7 +15,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function AnswerOptions({ question, openBranchingPage, setOpenBranchingPage }: Props) {
|
||||
const {onClickAddAnAnswer} = useAddAnswer();
|
||||
const {addVariantWithFocus, addVariantOnEnter, focusedVariantId, clearFocusedVariant} = useQuestionVariantsWithFocus();
|
||||
const [switchState, setSwitchState] = useState("setting");
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
@ -55,6 +55,9 @@ export default function AnswerOptions({ question, openBranchingPage, setOpenBran
|
||||
variant={variant}
|
||||
isOwn={Boolean(variant.isOwn)}
|
||||
ownPlaceholder={question.content.ownPlaceholder}
|
||||
shouldAutoFocus={focusedVariantId === variant.id}
|
||||
onFocusHandled={clearFocusedVariant}
|
||||
onEnterKeyPress={() => addVariantOnEnter(question.id)}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@ -77,7 +80,7 @@ export default function AnswerOptions({ question, openBranchingPage, setOpenBran
|
||||
mr: "4px",
|
||||
height: "19px",
|
||||
}}
|
||||
onClick={() => onClickAddAnAnswer(question)}
|
||||
onClick={() => addVariantWithFocus(question)}
|
||||
>
|
||||
Добавьте ответ
|
||||
</Link>
|
||||
|
||||
@ -4,7 +4,7 @@ import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import type { QuizQuestionVariant } from "@frontend/squzanswerer";
|
||||
import { memo } from "react";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useAddAnswer } from "@/utils/hooks/useAddAnswer";
|
||||
import { useQuestionVariantsWithFocus } from "@/utils/questionVariants";
|
||||
|
||||
interface Props {
|
||||
question: QuizQuestionVariant;
|
||||
@ -21,7 +21,7 @@ const ResponseSettings = memo<Props>(function ({question, questionId, ownPlaceho
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(900));
|
||||
const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||
const {switchOwn} = useAddAnswer();
|
||||
const {switchOwnVariant} = useQuestionVariantsWithFocus();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -84,7 +84,7 @@ const ResponseSettings = memo<Props>(function ({question, questionId, ownPlaceho
|
||||
label={'Вариант "свой ответ"'}
|
||||
checked={isOwn}
|
||||
handleChange={({ target }) => {
|
||||
switchOwn({question, checked:target.checked})
|
||||
switchOwnVariant({question, checked:target.checked})
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@ -327,7 +327,8 @@ export const updateQuestion = async <T = AnyTypedQuizQuestion>(
|
||||
requestQueue.enqueue(`updateQuestion-${questionId}`, request);
|
||||
};
|
||||
|
||||
export const addQuestionVariant = (questionId: string) => {
|
||||
export const addQuestionVariant = (questionId: string): string => {
|
||||
const newVariant = createQuestionVariant();
|
||||
updateQuestion(questionId, (question) => {
|
||||
switch (question.type) {
|
||||
case "variant":
|
||||
@ -335,12 +336,13 @@ export const addQuestionVariant = (questionId: string) => {
|
||||
case "select":
|
||||
case "images":
|
||||
case "varimg":
|
||||
question.content.variants.push(createQuestionVariant());
|
||||
question.content.variants.push(newVariant);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Cannot add variant to question of type "${question.type}"`);
|
||||
}
|
||||
});
|
||||
return newVariant.id;
|
||||
};
|
||||
export const addQuestionOwnVariant = (questionId: string) => {
|
||||
updateQuestion(questionId, (question) => {
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
import { QuizQuestionsWithVariants } from "@frontend/squzanswerer";
|
||||
import { addQuestionOwnVariant, addQuestionVariant, updateQuestion } from "@root/questions/actions";
|
||||
|
||||
export const useAddAnswer = () => {
|
||||
const onClickAddAnAnswer = (question: QuizQuestionsWithVariants) => {
|
||||
addQuestionVariant(question.id);
|
||||
};
|
||||
interface SwitchOwnProps {
|
||||
question: QuizQuestionsWithVariants;
|
||||
checked: boolean
|
||||
}
|
||||
const switchOwn = ({ question, checked }: SwitchOwnProps) => {
|
||||
if (!question.content.variants.some(v => v.isOwn) && checked) {
|
||||
addQuestionOwnVariant(question.id)
|
||||
}
|
||||
|
||||
updateQuestion<QuizQuestionVariant>(question.id, (question) => {
|
||||
question.content.own = checked;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
onClickAddAnAnswer,
|
||||
switchOwn
|
||||
};
|
||||
};
|
||||
47
src/utils/questionVariants.ts
Normal file
47
src/utils/questionVariants.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { QuizQuestionsWithVariants, QuizQuestionVariant } from "@frontend/squzanswerer";
|
||||
import { addQuestionOwnVariant, addQuestionVariant, updateQuestion } from "@root/questions/actions";
|
||||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* Утилита для управления вариантами ответов с автофокусом
|
||||
*/
|
||||
export const useQuestionVariantsWithFocus = () => {
|
||||
const [focusedVariantId, setFocusedVariantId] = useState<string | null>(null);
|
||||
|
||||
const addVariantWithFocus = (question: QuizQuestionsWithVariants) => {
|
||||
const newVariantId = addQuestionVariant(question.id);
|
||||
setFocusedVariantId(newVariantId);
|
||||
};
|
||||
|
||||
const addVariantOnEnter = (questionId: string) => {
|
||||
const newVariantId = addQuestionVariant(questionId);
|
||||
setFocusedVariantId(newVariantId);
|
||||
};
|
||||
|
||||
const clearFocusedVariant = () => {
|
||||
setFocusedVariantId(null);
|
||||
};
|
||||
|
||||
interface SwitchOwnProps {
|
||||
question: QuizQuestionsWithVariants;
|
||||
checked: boolean
|
||||
}
|
||||
|
||||
const switchOwnVariant = ({ question, checked }: SwitchOwnProps) => {
|
||||
if (!question.content.variants.some(v => v.isOwn) && checked) {
|
||||
addQuestionOwnVariant(question.id)
|
||||
}
|
||||
|
||||
updateQuestion<QuizQuestionVariant>(question.id, (question) => {
|
||||
question.content.own = checked;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
addVariantWithFocus,
|
||||
addVariantOnEnter,
|
||||
switchOwnVariant,
|
||||
focusedVariantId,
|
||||
clearFocusedVariant
|
||||
};
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user