diff --git a/src/model/questionTypes/shared.ts b/src/model/questionTypes/shared.ts index e85692af..43679060 100644 --- a/src/model/questionTypes/shared.ts +++ b/src/model/questionTypes/shared.ts @@ -30,6 +30,17 @@ export function createQuestionVariant(): QuestionVariant { answer: "", extendedText: "", hints: "", + isOwn: false, + originalImageUrl: "", + }; +} +export function createQuestionOwnVariant(): QuestionVariant { + return { + id: nanoid(), + answer: "", + extendedText: "", + hints: "", + isOwn: true, originalImageUrl: "", }; } diff --git a/src/pages/IntegrationsPage/IntegrationsModal/Amo/AnswerItem.tsx b/src/pages/IntegrationsPage/IntegrationsModal/Amo/AnswerItem.tsx index a237cd7c..b2e7545d 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/Amo/AnswerItem.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/Amo/AnswerItem.tsx @@ -9,8 +9,6 @@ type AnswerItemProps = { }; export const AnswerItem: FC = ({ fieldName, fieldValue, deleteHC }) => { - console.log("AnswerItem") - console.log(fieldName) const theme = useTheme(); return ( = ({ selectedTags, }) => { const theme = useTheme(); - console.log(step) const isMobile = useMediaQuery(theme.breakpoints.down(600)); if (step === 0) { return; diff --git a/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx b/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx index 1b22b6aa..1fc4d60d 100644 --- a/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx +++ b/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx @@ -10,11 +10,11 @@ import { useMediaQuery, useTheme, } from "@mui/material"; -import { addQuestionVariant, deleteQuestionVariant, setQuestionVariantField } from "@root/questions/actions"; +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 { Draggable } from "react-beautiful-dnd"; -import type { QuestionVariant } from "@frontend/squzanswerer"; +import type { QuestionVariant, QuizQuestionVariant } from "@frontend/squzanswerer"; const TextField = MuiTextField as unknown as FC; @@ -26,10 +26,11 @@ type AnswerItemProps = { disableKeyDown?: boolean; additionalContent?: ReactNode; additionalMobile?: ReactNode; + isOwn: boolean; }; const AnswerItem = memo( - ({ index, variant, questionId, largeCheck = false, additionalContent, additionalMobile, disableKeyDown }) => { + ({ index, variant, questionId, largeCheck = false, additionalContent, additionalMobile, disableKeyDown, isOwn }) => { const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(790)); @@ -58,7 +59,7 @@ const AnswerItem = memo( value={variant.answer} fullWidth focused={false} - placeholder={"Добавьте ответ"} + placeholder={isOwn ? "Добавьте текст-подсказку для ввода “своего ответа”" : "Добавьте ответ"} multiline={largeCheck} onChange={({ target }: ChangeEvent) => { if (target.value.length <= 1000) { @@ -67,7 +68,7 @@ const AnswerItem = memo( }} onKeyDown={(event: KeyboardEvent) => { if (disableKeyDown) { - enqueueSnackbar("100 максимальное количество вопросов"); + enqueueSnackbar("100 максимальное количество"); } else if (event.code === "Enter" && !largeCheck) { addQuestionVariant(questionId); } @@ -88,7 +89,13 @@ const AnswerItem = memo( deleteQuestionVariant(questionId, variant.id)} + onClick={() => { + isOwn ? updateQuestion(questionId, (question) => { + question.content.own = false; + }) + : + deleteQuestionVariant(questionId, variant.id) + }} > ( "& .MuiInputBase-root": { padding: additionalContent ? "5px 13px" : "13px", borderRadius: "10px", - background: "#ffffff", + background: isOwn ? "#F2F3F7" : "white", "& input.MuiInputBase-input": { height: "22px", }, diff --git a/src/pages/Questions/AnswerDraggableList/ImageEditAnswerItem.tsx b/src/pages/Questions/AnswerDraggableList/ImageEditAnswerItem.tsx index 7e45d691..345d288b 100644 --- a/src/pages/Questions/AnswerDraggableList/ImageEditAnswerItem.tsx +++ b/src/pages/Questions/AnswerDraggableList/ImageEditAnswerItem.tsx @@ -14,6 +14,7 @@ type Props = Omit< originalImageUrl?: string | null | undefined, ) => Promise; openImageUploadModal: () => void; + isOwn: boolean; }; export default function ImageEditAnswerItem({ @@ -27,6 +28,7 @@ export default function ImageEditAnswerItem({ pictureUploding, openCropModal, openImageUploadModal, + isOwn, }: Props) { const addOrEditImageButton = useMemo(() => { return ( @@ -105,6 +107,7 @@ export default function ImageEditAnswerItem({ variant={variant} additionalContent={addOrEditImageButton} additionalMobile={addOrEditImageButtonMobile} + isOwn={isOwn} /> ); } diff --git a/src/pages/Questions/Emoji/Emoji.tsx b/src/pages/Questions/Emoji/Emoji.tsx index 6d00bc59..492dce97 100644 --- a/src/pages/Questions/Emoji/Emoji.tsx +++ b/src/pages/Questions/Emoji/Emoji.tsx @@ -18,7 +18,7 @@ interface Props { export default function Emoji({ question, openBranchingPage, setOpenBranchingPage }: Props) { const [switchState, setSwitchState] = useState("setting"); - const onClickAddAnAnswer = useAddAnswer(); + const {onClickAddAnAnswer} = useAddAnswer(); const [open, setOpen] = useState(false); const [anchorElement, setAnchorElement] = useState(null); const [selectedVariant, setSelectedVariant] = useState(null); @@ -29,9 +29,12 @@ export default function Emoji({ question, openBranchingPage, setOpenBranchingPag return ( <> + ( + variants={question.content.variants + .filter(variant => !variant.isOwn ? true : question.content.own && variant.isOwn) + .map((variant, index) => ( ))} /> + , @@ -11,6 +12,7 @@ type Props = Omit< setAnchorElement: React.Dispatch>; setSelectedVariant: React.Dispatch>; setOpen: React.Dispatch>; + isOwn: boolean; }; export default function EmojiAnswerItem({ @@ -23,7 +25,17 @@ export default function EmojiAnswerItem({ setAnchorElement, setSelectedVariant, setOpen, + isOwn }: Props) { + + const setOwnPlaceholder = (replText: string) => { + updateQuestion(questionId, (question) => { + if (question.type !== "varimg") return; + + question.content.ownPlaceholder = replText; + }); + }; + const addOrEditImageButton = useMemo(() => { return ( !isTablet && ( @@ -77,6 +89,8 @@ export default function EmojiAnswerItem({ variant={variant} additionalContent={addOrEditImageButton} additionalMobile={addOrEditImageButtonMobile} + isOwn={isOwn} + changeOwnText={setOwnPlaceholder} /> ); } diff --git a/src/pages/Questions/Emoji/settingEmoji.tsx b/src/pages/Questions/Emoji/settingEmoji.tsx index d4bd6306..1cff9275 100644 --- a/src/pages/Questions/Emoji/settingEmoji.tsx +++ b/src/pages/Questions/Emoji/settingEmoji.tsx @@ -1,11 +1,13 @@ -import type { QuizQuestionEmoji, QuizQuestionVariant } from "@frontend/squzanswerer"; +import type { QuestionType, QuizQuestionEmoji, QuizQuestionVariant } from "@frontend/squzanswerer"; import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; 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"; type SettingEmojiProps = { + question: QuizQuestionEmoji; questionId: string; isRequired: boolean; isMulti: boolean; @@ -13,8 +15,10 @@ type SettingEmojiProps = { isLargeCheck?: boolean; }; -const SettingEmoji = memo(function ({ questionId, ownPlaceholder, isRequired, isLargeCheck, isMulti, isOwn }) { +const SettingEmoji = memo(function ({ question, questionId, isRequired, isLargeCheck, isMulti, isOwn }) { const theme = useTheme(); + const {switchOwn} = useAddAnswer(); + const isWrappColumn = useMediaQuery(theme.breakpoints.down(980)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); const isTablet = useMediaQuery(theme.breakpoints.down(985)); @@ -60,7 +64,7 @@ const SettingEmoji = memo(function ({ questionId, ownPlacehol > Настройки ответов - (function ({ questionId, ownPlacehol question.content.largeCheck = target.checked; }); }} - /> + /> */} (function ({ questionId, ownPlacehol label={'Вариант "свой ответ"'} checked={isOwn} handleChange={({ target }) => { - updateQuestion(questionId, (question) => { - question.content.own = target.checked; - }); + switchOwn({question, checked:target.checked}) }} /> - + {/* (function ({ questionId, ownPlacehol value={ownPlaceholder} onChange={({ target }) => setOwnPlaceholder(target.value)} /> - + */} ( + variants={question.content.variants + .filter(variant => !variant.isOwn ? true : question.content.own && variant.isOwn) + .map((variant, index) => ( ))} /> diff --git a/src/pages/Questions/QuestionOptions/OptionsAndPicture/SettingOptionsAndPict.tsx b/src/pages/Questions/QuestionOptions/OptionsAndPicture/SettingOptionsAndPict.tsx index e798842a..fe5e15cc 100644 --- a/src/pages/Questions/QuestionOptions/OptionsAndPicture/SettingOptionsAndPict.tsx +++ b/src/pages/Questions/QuestionOptions/OptionsAndPicture/SettingOptionsAndPict.tsx @@ -1,3 +1,4 @@ +import { useAddAnswer } from "@/utils/hooks/useAddAnswer"; import type { QuizQuestionVarImg, QuizQuestionVariant } from "@frontend/squzanswerer"; import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; import { updateQuestion } from "@root/questions/actions"; @@ -13,14 +14,18 @@ type SettingOptionsAndPictProps = { isOwn: boolean; ownPlaceholder?: boolean; isMulti?: boolean; + question: QuizQuestionVarImg; }; -const SettingOptionsAndPict = memo(function ({ questionId, ownPlaceholder, isMulti, isLargeCheck, replText, isRequired, isOwn }) { +const SettingOptionsAndPict = memo(function ({ question, questionId, ownPlaceholder, isMulti, isLargeCheck, replText, isRequired, isOwn }) { const theme = useTheme(); + const {switchOwn} = useAddAnswer(); + const isWrappColumn = useMediaQuery(theme.breakpoints.down(980)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); const isTablet = useMediaQuery(theme.breakpoints.down(985)); const isMobile = useMediaQuery(theme.breakpoints.down(680)); + const setReplText = (replText: string) => { updateQuestion(questionId, (question) => { @@ -29,13 +34,6 @@ const SettingOptionsAndPict = memo(function ({ quest question.content.replText = replText; }); }; - const setOwnPlaceholder = (replText: string) => { - updateQuestion(questionId, (question) => { - if (question.type !== "varimg") return; - - question.content.ownPlaceholder = replText; - }); - }; return ( <> @@ -69,63 +67,15 @@ const SettingOptionsAndPict = memo(function ({ quest > Настройки ответов - { - updateQuestion(questionId, (question) => { - question.content.largeCheck = target.checked; - }); - }} - /> - { - updateQuestion(questionId, (question) => { - question.content.multi = target.checked; - }); - }} - /> { - updateQuestion(questionId, (question) => { - question.content.own = target.checked; - }); + switchOwn({question, checked:target.checked}) }} /> - - - Подсказка "своего ответа" - - setOwnPlaceholder(target.value)} - /> - {!isWrappColumn && ( { if (!selectedVariantId) return; @@ -70,7 +69,9 @@ export default function OptionsPicture({ question, openBranchingPage, setOpenBra ( + variants={question.content.variants + .filter(variant => !variant.isOwn ? true : question.content.own && variant.isOwn) + .map((variant, index) => ( ))} /> diff --git a/src/pages/Questions/QuestionOptions/OptionsPicture/settingOptionsPict.tsx b/src/pages/Questions/QuestionOptions/OptionsPicture/settingOptionsPict.tsx index 9367108a..26cfd18a 100644 --- a/src/pages/Questions/QuestionOptions/OptionsPicture/settingOptionsPict.tsx +++ b/src/pages/Questions/QuestionOptions/OptionsPicture/settingOptionsPict.tsx @@ -9,6 +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"; type Proportion = "1:1" | "1:2" | "2:1"; @@ -36,6 +37,7 @@ const FORMATS: FormatItem[] = [ ]; type SettingOptionsPictProps = { + question: QuizQuestionVariant; questionId: string; isRequired: boolean; isMulti: boolean; @@ -47,6 +49,7 @@ type SettingOptionsPictProps = { }; const SettingOptionsPict = memo(function ({ + question, questionId, isRequired, ownPlaceholder, isMulti, isLargeCheck, @@ -66,6 +69,7 @@ const SettingOptionsPict = memo(function ({ question.content.ownPlaceholder = replText; }); }; + const {switchOwn} = useAddAnswer(); return ( (function ({ > Настройки ответов - (function ({ question.content.largeCheck = target.checked; }); }} - /> + /> */} (function ({ label={'Вариант "свой ответ"'} checked={isOwn} handleChange={({ target }) => { - updateQuestion(questionId, (question) => { - question.content.own = target.checked; - }); + switchOwn({question, checked:target.checked}) }} /> - + {/* (function ({ value={ownPlaceholder} onChange={({ target }) => setOwnPlaceholder(target.value)} /> - + */} diff --git a/src/pages/Questions/QuestionOptions/OptionsPicture/switchOptionsPict.tsx b/src/pages/Questions/QuestionOptions/OptionsPicture/switchOptionsPict.tsx index 4a97f575..f7c749ed 100644 --- a/src/pages/Questions/QuestionOptions/OptionsPicture/switchOptionsPict.tsx +++ b/src/pages/Questions/QuestionOptions/OptionsPicture/switchOptionsPict.tsx @@ -12,6 +12,7 @@ export default function SwitchAnswerOptionsPict({ switchState = "setting", quest case "setting": return ( ( + variants={question.content.variants + .filter(variant => !variant.isOwn ? true : question.content.own && variant.isOwn) + .map((variant, index) => ( = 100} questionId={question.id} variant={variant} + isOwn={Boolean(variant.isOwn)} /> ))} /> diff --git a/src/pages/Questions/QuestionOptions/answerOptions/responseSettings.tsx b/src/pages/Questions/QuestionOptions/answerOptions/responseSettings.tsx index 3358734b..655024ef 100644 --- a/src/pages/Questions/QuestionOptions/answerOptions/responseSettings.tsx +++ b/src/pages/Questions/QuestionOptions/answerOptions/responseSettings.tsx @@ -4,8 +4,10 @@ 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"; interface Props { + question: QuizQuestionVariant; questionId: string; isRequired: boolean; isLargeCheck: boolean; @@ -14,18 +16,12 @@ interface Props { ownPlaceholder?: string; } -const ResponseSettings = memo(function ({ questionId, ownPlaceholder, isRequired, isLargeCheck, isMulti, isOwn }) { +const ResponseSettings = memo(function ({question, questionId, ownPlaceholder, isRequired, isLargeCheck, isMulti, isOwn }) { const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(900)); const isFigmaTablte = useMediaQuery(theme.breakpoints.down(990)); const isMobile = useMediaQuery(theme.breakpoints.down(790)); - const setOwnPlaceholder = (replText: string) => { - updateQuestion(questionId, (question) => { - if (question.type !== "varimg") return; - - question.content.ownPlaceholder = replText; - }); - }; + const {switchOwn} = useAddAnswer(); return ( (function ({ questionId, ownPlaceholder, isR label={'Вариант "свой ответ"'} checked={isOwn} handleChange={({ target }) => { - updateQuestion(questionId, (question) => { - question.content.own = target.checked; - }); + switchOwn({question, checked:target.checked}) }} /> - - - Подсказка "своего ответа" - - setOwnPlaceholder(target.value)} - /> - export const createUntypedQuestion = (quizId: number, insertAfterQuestionId?: string) => { const { questions } = useQuestionsStore.getState(); - console.log("insertAfterQuestionId ", insertAfterQuestionId) const questionsAmount = questions.filter(({ type }) => type !== "result").length; @@ -68,7 +67,6 @@ export const createUntypedQuestion = (quizId: number, insertAfterQuestionId?: st export const createUntypedQuestionForm = (quizId: number, insertAfterQuestionId?: string) => { const { questions } = useQuestionsStore.getState(); - console.log("insertAfterQuestionId ", insertAfterQuestionId) const questionsAmount = questions.filter(({ type }) => type !== "result").length; @@ -338,6 +336,20 @@ export const addQuestionVariant = (questionId: string) => { } }); }; +export const addQuestionOwnVariant = (questionId: string) => { + updateQuestion(questionId, (question) => { + switch (question.type) { + case "variant": + case "emoji": + case "images": + case "varimg": + question.content.variants.push(createQuestionOwnVariant()); + break; + default: + throw new Error(`Cannot add variant to question of type "${question.type}"`); + } + }); +}; export const deleteQuestionVariant = (questionId: string, variantId: string) => { updateQuestion(questionId, (question) => { diff --git a/src/utils/hooks/useAddAnswer.ts b/src/utils/hooks/useAddAnswer.ts index fe9b2760..0c8ee048 100644 --- a/src/utils/hooks/useAddAnswer.ts +++ b/src/utils/hooks/useAddAnswer.ts @@ -1,10 +1,26 @@ import { QuizQuestionsWithVariants } from "@frontend/squzanswerer"; -import { addQuestionVariant } from "@root/questions/actions"; +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) + } - return onClickAddAnAnswer; + updateQuestion(question.id, (question) => { + question.content.own = checked; + }); + } + + return { + onClickAddAnAnswer, + switchOwn + }; }; diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts index e4274de3..d0591061 100644 --- a/src/utils/hooks/useAutoPay.ts +++ b/src/utils/hooks/useAutoPay.ts @@ -32,11 +32,9 @@ export const useAfterPay = () => { const [, payCartError] = await cartApi.pay(); if (payCartError) { - console.log("попытка оплаты не удалась") //Не получилось купить корзину. Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты startPayCartProcess(paymentUserId) } else { - enqueueSnackbar("Товары успешно приобретены") if (currentCC) navigate("/tariffs") cancelPayCartProcess() } @@ -52,7 +50,6 @@ export const useAfterPay = () => { //Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло. (async () => { - console.log("Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.") const [, payCartError] = await cartApi.pay(); if (!payCartError) {