From 667a0cd0692aefb0a75c48d1945106b22d1fbb90 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Wed, 10 Jan 2024 19:53:37 +0300 Subject: [PATCH 1/5] feat: new ResultForm logic --- src/constants/result.ts | 1 + src/model/questionTypes/result.ts | 1 + src/model/quizSettings.ts | 6 +- src/pages/ContactFormPage/ContactFormPage.tsx | 28 +++--- src/pages/ResultPage/ResultSettings.tsx | 2 +- src/pages/ResultPage/cards/ResultCard.tsx | 86 +++++++++++++++---- src/pages/ResultPage/cards/WhenCard.tsx | 85 ++++++++++++++---- src/pages/ViewPublicationPage/ContactForm.tsx | 6 +- src/pages/ViewPublicationPage/Footer.tsx | 16 ++-- src/pages/ViewPublicationPage/Question.tsx | 35 ++++---- src/pages/ViewPublicationPage/ResultForm.tsx | 58 +++++++------ .../ViewPublicationPage/questions/Page.tsx | 1 + .../ViewPublicationPage/questions/Variant.tsx | 1 + src/utils/replaceSpacesToEmptyLines.ts | 2 +- 14 files changed, 221 insertions(+), 107 deletions(-) diff --git a/src/constants/result.ts b/src/constants/result.ts index 668c0413..ab8fa049 100644 --- a/src/constants/result.ts +++ b/src/constants/result.ts @@ -17,5 +17,6 @@ export const QUIZ_QUESTION_RESULT: Omit< price: [0], useImage: true, usage: true, + redirect: "", }, }; diff --git a/src/model/questionTypes/result.ts b/src/model/questionTypes/result.ts index 80ab935a..5b084765 100644 --- a/src/model/questionTypes/result.ts +++ b/src/model/questionTypes/result.ts @@ -19,5 +19,6 @@ export interface QuizQuestionResult extends QuizQuestionBase { hint: QuestionHint; autofill: boolean; usage: boolean; + redirect: string; }; } diff --git a/src/model/quizSettings.ts b/src/model/quizSettings.ts index cee0dbcc..fd3f6e82 100644 --- a/src/model/quizSettings.ts +++ b/src/model/quizSettings.ts @@ -65,12 +65,13 @@ export interface QuizConfig { | "BlueTheme" | "BlueDarkTheme"; resultInfo: { - when: "before" | "after" | "email"; + when: "email" | ""; share: true | false; replay: true | false; theme: string; reply: string; replname: string; + showResultForm: "before" | "after"; }; startpage: { description: string; @@ -133,12 +134,13 @@ export const defaultQuizConfig: QuizConfig = { haveRoot: null, theme: "StandardTheme", resultInfo: { - when: "after", + when: "", share: false, replay: false, theme: "", reply: "", replname: "", + showResultForm: "after", }, startpage: { description: "", diff --git a/src/pages/ContactFormPage/ContactFormPage.tsx b/src/pages/ContactFormPage/ContactFormPage.tsx index 8b0f4ac0..d77e8b26 100644 --- a/src/pages/ContactFormPage/ContactFormPage.tsx +++ b/src/pages/ContactFormPage/ContactFormPage.tsx @@ -265,19 +265,21 @@ const SettingField = ({ - - updateQuiz(quiz?.id, (quiz) => { - quiz.config.formContact.fields[type].used = false; - }) - } - sx={{ - width: "48px", - ml: "5px", - }} - > - - + {(type !== "email" || quiz?.config.resultInfo.when !== "email") && ( + + updateQuiz(quiz?.id, (quiz) => { + quiz.config.formContact.fields[type].used = false; + }) + } + sx={{ + width: "48px", + ml: "5px", + }} + > + + + )} ); diff --git a/src/pages/ResultPage/ResultSettings.tsx b/src/pages/ResultPage/ResultSettings.tsx index 97b598d8..14524fae 100644 --- a/src/pages/ResultPage/ResultSettings.tsx +++ b/src/pages/ResultPage/ResultSettings.tsx @@ -113,7 +113,7 @@ export const ResultSettings = () => { - {quiz.config.resultInfo.when === "email" && ( + {quiz?.config.resultInfo.when === "email" && ( )} diff --git a/src/pages/ResultPage/cards/ResultCard.tsx b/src/pages/ResultPage/cards/ResultCard.tsx index 1d75583b..8f325f70 100644 --- a/src/pages/ResultPage/cards/ResultCard.tsx +++ b/src/pages/ResultPage/cards/ResultCard.tsx @@ -1,9 +1,10 @@ -import * as React from "react"; +import { useState, useEffect } from "react"; import { getQuestionByContentId, updateQuestion, } from "@root/questions/actions"; +import { useCurrentQuiz } from "@root/quizes/hooks"; import CustomTextField from "@ui_kit/CustomTextField"; @@ -26,9 +27,12 @@ import ExpandLessIcon from "@mui/icons-material/ExpandLess"; import Trash from "@icons/trash"; import Info from "@icons/Info"; import SettingIcon from "@icons/questionsPage/settingIcon"; -import { QuizQuestionResult } from "@model/questionTypes/result"; import { MediaSelectionAndDisplay } from "@ui_kit/MediaSelectionAndDisplay"; +import type { MouseEvent } from "react"; + +import type { QuizQuestionResult } from "@model/questionTypes/result"; + interface Props { resultContract: boolean; resultData: QuizQuestionResult; @@ -57,11 +61,9 @@ export const checkEmptyData = ({ const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => { const checkEmpty = checkEmptyData({ resultData }); const question = getQuestionByContentId(resultData.content.rule.parentId); - const [anchorEl, setAnchorEl] = React.useState( - null, - ); + const [anchorEl, setAnchorEl] = useState(null); - const handleClick = (event: React.MouseEvent) => { + const handleClick = (event: MouseEvent) => { setAnchorEl(event.currentTarget); }; @@ -126,12 +128,23 @@ export const ResultCard = ({ resultContract, resultData }: Props) => { const isMobile = useMediaQuery(theme.breakpoints.down(790)); const isTablet = useMediaQuery(theme.breakpoints.down(800)); - const [expand, setExpand] = React.useState(true); - const [resultCardSettings, setResultCardSettings] = React.useState(false); - const [buttonPlus, setButtonPlus] = React.useState(true); + const [expand, setExpand] = useState(true); + const [resultCardSettings, setResultCardSettings] = useState(false); + const [buttonPlus, setButtonPlus] = useState(true); const question = getQuestionByContentId(resultData.content.rule.parentId); + const quiz = useCurrentQuiz(); - React.useEffect(() => { + useEffect(() => { + if ( + resultData.content.hint.text || + (quiz?.config.resultInfo.showResultForm === "after" && + resultData.content.redirect) + ) { + setButtonPlus(false); + } + }, []); + + useEffect(() => { setExpand(true); }, [resultContract]); @@ -390,17 +403,13 @@ export const ResultCard = ({ resultContract, resultData }: Props) => { - - updateQuestion( - resultData.id, - (question) => - (question.content.hint.text = target.value), - ) + updateQuestion(resultData.id, (question) => { + question.content.hint.text = target.value; + }) } - fullWidth maxLength={19} placeholder="Например: узнать подробнее" sx={{ @@ -421,6 +430,49 @@ export const ResultCard = ({ resultContract, resultData }: Props) => { }, }} /> + + {quiz?.config.resultInfo.showResultForm === "after" && ( + <> + + Cсылка для кнопки + + + updateQuestion( + resultData.id, + (question) => { + question.content.redirect = target.value; + }, + ) + } + placeholder="https://penahub.ru" + sx={{ + "& .MuiInputBase-root": { + backgroundColor: "#F2F3F7", + width: isMobile ? undefined : "409px", + height: "48px", + borderRadius: "8px", + }, + }} + inputProps={{ + sx: { + height: "85px", + borderRadius: "10px", + fontSize: "18px", + lineHeight: "21px", + py: 0, + }, + }} + /> + + )} )} diff --git a/src/pages/ResultPage/cards/WhenCard.tsx b/src/pages/ResultPage/cards/WhenCard.tsx index a32b5ff8..8374c14e 100644 --- a/src/pages/ResultPage/cards/WhenCard.tsx +++ b/src/pages/ResultPage/cards/WhenCard.tsx @@ -22,7 +22,12 @@ import ExpandLessIcon from "@mui/icons-material/ExpandLess"; import ShareNetwork from "@icons/ShareNetwork.svg"; import ArrowCounterClockWise from "@icons/ArrowCounterClockWise.svg"; -const whenValues = [ +type WhenVariants = { + title: string; + value: "before" | "after"; +}; + +const whenValues: WhenVariants[] = [ { title: "До формы контактов", value: "before", @@ -31,10 +36,6 @@ const whenValues = [ title: "После формы контактов", value: "after", }, - { - title: "Отправить на E-mail", - value: "email", - }, ]; interface Props { @@ -170,7 +171,7 @@ export const WhenCard = ({ quizExpand }: Props) => { - {expand && ( + {expand && quiz && ( <> { {whenValues.map(({ title, value }, index) => ( - {value === "email" && } ))} + + + + {/* { diff --git a/src/pages/ViewPublicationPage/ContactForm.tsx b/src/pages/ViewPublicationPage/ContactForm.tsx index dd694179..efbe94b7 100644 --- a/src/pages/ViewPublicationPage/ContactForm.tsx +++ b/src/pages/ViewPublicationPage/ContactForm.tsx @@ -186,14 +186,14 @@ export const ContactForm = ({ { // resultQuestion && - // quiz?.config.resultInfo.when === "after" && + // quiz?.config.resultInfo.showResultForm === "after" && + )} + {quiz?.config.resultInfo.showResultForm === "after" && + resultQuestion.content.redirect && ( - - - )} + )} + ); diff --git a/src/pages/ViewPublicationPage/questions/Page.tsx b/src/pages/ViewPublicationPage/questions/Page.tsx index a9ca961b..7af7b25f 100644 --- a/src/pages/ViewPublicationPage/questions/Page.tsx +++ b/src/pages/ViewPublicationPage/questions/Page.tsx @@ -45,6 +45,7 @@ export const Page = ({ currentQuestion }: PageProps) => { }} > { currentQuestion.content.back !== " " && ( (object: T): T => { for (const [key, value] of Object.entries(object)) { if (typeof value === "string") { - result[key] = value.replace(/\" \"/g, '""'); + result[key] = value.replace(" ", "").replace(/\" \"/g, '""'); continue; } From 605667ad0e760c0a4bc8849527abd0f7c4883b8d Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Thu, 11 Jan 2024 11:46:50 +0300 Subject: [PATCH 2/5] fix: Form, delete button for first item removed --- src/pages/Questions/ButtonsOptions.tsx | 5 ++- .../FormDraggableList/QuestionPageCard.tsx | 36 ++++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/pages/Questions/ButtonsOptions.tsx b/src/pages/Questions/ButtonsOptions.tsx index 3a1bf9ac..4a3f3dc2 100644 --- a/src/pages/Questions/ButtonsOptions.tsx +++ b/src/pages/Questions/ButtonsOptions.tsx @@ -311,7 +311,10 @@ export default function ButtonsOptions({ }} data-cy="delete-question" > - + {(quiz?.config.type !== "form" || + question.id !== questions[0].id) && ( + + )} setOpenDelete(false)}> - { - deleteQuestionWithTimeout(question.id, () => - deleteQuestion(question.id), - ); - }} - > - - + {questionIndex > 0 && ( + { + deleteQuestionWithTimeout(question.id, () => + deleteQuestion(question.id), + ); + }} + > + + + )} )} From 28bfd30fdb4013aa57dd1565cad9280cbfd707c5 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Thu, 11 Jan 2024 11:59:59 +0300 Subject: [PATCH 3/5] feat: Form first item don't draggable --- .../FormDraggableListItem.tsx | 156 ++++++++++-------- .../FormDraggableList/QuestionPageCard.tsx | 24 +-- .../Form/FormDraggableList/index.tsx | 39 +++-- 3 files changed, 123 insertions(+), 96 deletions(-) diff --git a/src/pages/Questions/Form/FormDraggableList/FormDraggableListItem.tsx b/src/pages/Questions/Form/FormDraggableList/FormDraggableListItem.tsx index adf33167..621c5628 100644 --- a/src/pages/Questions/Form/FormDraggableList/FormDraggableListItem.tsx +++ b/src/pages/Questions/Form/FormDraggableList/FormDraggableListItem.tsx @@ -8,79 +8,99 @@ import { } from "../../../../model/questionTypes/shared"; import QuestionsPageCard from "./QuestionPageCard"; +import type { DraggableProvided } from "react-beautiful-dnd"; + type FormDraggableListItemProps = { question: AnyTypedQuizQuestion | UntypedQuizQuestion; questionIndex: number; }; -export default memo( - ({ question, questionIndex }: FormDraggableListItemProps) => { - const theme = useTheme(); +type FormItemProps = FormDraggableListItemProps & { + provided?: DraggableProvided; +}; - return ( - - {(provided) => ( - { + const theme = useTheme(); + + return ( + <> + {question.deleted ? ( + + - {question.deleted ? ( - - - Вопрос удалён. - - { - updateQuestion(question.id, (question) => { - question.deleted = false; - }); - }} - sx={{ - cursor: "pointer", - fontSize: "16px", - textDecoration: "underline", - color: theme.palette.brightPurple.main, - textDecorationColor: theme.palette.brightPurple.main, - }} - > - Восстановить? - - - ) : ( - - - - )} - - )} - - ); - }, + Вопрос удалён. + + { + updateQuestion(question.id, (question) => { + question.deleted = false; + }); + }} + sx={{ + cursor: "pointer", + fontSize: "16px", + textDecoration: "underline", + color: theme.palette.brightPurple.main, + textDecorationColor: theme.palette.brightPurple.main, + }} + > + Восстановить? + + + ) : ( + + + + )} + + ); +}; + +export const FormDraggableListItem = memo( + ({ question, questionIndex }: FormDraggableListItemProps) => ( + + {(provided) => ( + + + + )} + + ), ); diff --git a/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx b/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx index 5cbe8f20..1697152b 100644 --- a/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx +++ b/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx @@ -301,17 +301,19 @@ export default function QuestionsPageCard({ - - - + {draggableProps && ( + + + + )} {question.expanded && ( diff --git a/src/pages/Questions/Form/FormDraggableList/index.tsx b/src/pages/Questions/Form/FormDraggableList/index.tsx index 0417fcdc..bf2edf5c 100644 --- a/src/pages/Questions/Form/FormDraggableList/index.tsx +++ b/src/pages/Questions/Form/FormDraggableList/index.tsx @@ -2,7 +2,7 @@ import { Box } from "@mui/material"; import { reorderQuestions } from "@root/questions/actions"; import type { DropResult } from "react-beautiful-dnd"; import { DragDropContext, Droppable } from "react-beautiful-dnd"; -import FormDraggableListItem from "./FormDraggableListItem"; +import { FormDraggableListItem, FormItem } from "./FormDraggableListItem"; import { useQuestions } from "@root/questions/hooks"; export const FormDraggableList = () => { @@ -12,21 +12,26 @@ export const FormDraggableList = () => { }; return ( - - - {(provided) => ( - - {questions?.map((question, index) => ( - - ))} - {provided.placeholder} - - )} - - + + {questions[0] && } + + + {(provided) => ( + + {questions + ?.slice(1) + .map((question, index) => ( + + ))} + {provided.placeholder} + + )} + + + ); }; From fbde202ce56a7a050eab8dc867291d9f38d1a06b Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Thu, 11 Jan 2024 12:05:59 +0300 Subject: [PATCH 4/5] fix: index bug --- src/pages/Questions/Form/FormDraggableList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Questions/Form/FormDraggableList/index.tsx b/src/pages/Questions/Form/FormDraggableList/index.tsx index bf2edf5c..9f0e264e 100644 --- a/src/pages/Questions/Form/FormDraggableList/index.tsx +++ b/src/pages/Questions/Form/FormDraggableList/index.tsx @@ -24,7 +24,7 @@ export const FormDraggableList = () => { ))} {provided.placeholder} From e76c90cb78c9b9a1356d75a0564c6f3e084c3cb0 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Fri, 12 Jan 2024 12:35:50 +0300 Subject: [PATCH 5/5] fix: drag&drop bug --- src/pages/Questions/ButtonsOptions.tsx | 39 +++++++++---------- src/pages/Questions/ButtonsOptionsAndPict.tsx | 38 +++++++++--------- .../FormDraggableListItem.tsx | 2 +- .../Form/FormDraggableList/index.tsx | 4 +- 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/pages/Questions/ButtonsOptions.tsx b/src/pages/Questions/ButtonsOptions.tsx index 4a3f3dc2..dd91ec0d 100644 --- a/src/pages/Questions/ButtonsOptions.tsx +++ b/src/pages/Questions/ButtonsOptions.tsx @@ -295,27 +295,26 @@ export default function ButtonsOptions({ > - { - if (question.type === null) { - deleteQuestion(question.id); - } - if (question.content.rule.parentId.length !== 0) { - setOpenDelete(true); - } else { - deleteQuestionWithTimeout(question.id, () => - DeleteFunction(questions, question, quiz), - ); - } - }} - data-cy="delete-question" - > - {(quiz?.config.type !== "form" || - question.id !== questions[0].id) && ( + {(quiz?.config.type !== "form" || question.id !== questions[0].id) && ( + { + if (question.type === null) { + deleteQuestion(question.id); + } + if (question.content.rule.parentId.length !== 0) { + setOpenDelete(true); + } else { + deleteQuestionWithTimeout(question.id, () => + DeleteFunction(questions, question, quiz), + ); + } + }} + data-cy="delete-question" + > - )} - + + )} setOpenDelete(false)}> - { - if (question.type === null) { - deleteQuestion(question.id); - } - if (question.content.rule.parentId.length !== 0) { - setOpenDelete(true); - } else { - deleteQuestionWithTimeout(question.id, () => - DeleteFunction(questions, question, quiz), - ); - } - }} - data-cy="delete-question" - > - - + {(quiz?.config.type !== "form" || question.id !== questions[0].id) && ( + { + if (question.type === null) { + deleteQuestion(question.id); + } + if (question.content.rule.parentId.length !== 0) { + setOpenDelete(true); + } else { + deleteQuestionWithTimeout(question.id, () => + DeleteFunction(questions, question, quiz), + ); + } + }} + data-cy="delete-question" + > + + + )} setOpenDelete(false)}> ( - + {(provided) => ( { const questions = useQuestions().questions.filter((q) => q.type !== "result"); const onDragEnd = ({ destination, source }: DropResult) => { - if (destination) reorderQuestions(source.index, destination.index); + if (destination) { + reorderQuestions(source.index, destination.index); + } }; return (