From 860c883037b1facc911de50faede0d76d7b4f7fe Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 19 Dec 2023 14:23:09 +0300 Subject: [PATCH 1/5] feat: new SliderOptions logic --- .../Questions/SliderOptions/SliderOptions.tsx | 93 +++++++++++++------ src/ui_kit/CustomNumberField.tsx | 20 +--- src/ui_kit/CustomTextField.tsx | 4 +- 3 files changed, 72 insertions(+), 45 deletions(-) diff --git a/src/pages/Questions/SliderOptions/SliderOptions.tsx b/src/pages/Questions/SliderOptions/SliderOptions.tsx index bcc23b7d..a449d69c 100644 --- a/src/pages/Questions/SliderOptions/SliderOptions.tsx +++ b/src/pages/Questions/SliderOptions/SliderOptions.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; import ButtonsOptions from "../ButtonsOptions"; import CustomNumberField from "@ui_kit/CustomNumberField"; @@ -16,6 +16,22 @@ export default function SliderOptions({ question }: Props) { const isMobile = useMediaQuery(theme.breakpoints.down(790)); const [switchState, setSwitchState] = useState("setting"); const [stepError, setStepError] = useState(""); + const [startError, setStartError] = useState(false); + + useEffect(() => { + const min = Number(question.content.range.split("—")[0]); + const max = Number(question.content.range.split("—")[1]); + const start = Number(question.content.start); + console.log(min, max, start); + + if (start < min || start > max) { + setStartError(true); + } + + if (start >= min && start <= max) { + setStartError(false); + } + }, [question.content.range, question.content.start]); const SSHC = (data: string) => { setSwitchState(data); @@ -44,10 +60,19 @@ export default function SliderOptions({ question }: Props) { marginRight: isMobile ? "10px" : "0px", }} > - + Выбор значения из диапазона - + { if (question.type !== "number") return; - question.content.range = `${target.value}—${question.content.range.split("—")[1]}`; + question.content.range = `${target.value}—${ + question.content.range.split("—")[1] + }`; }); }} onBlur={({ target }) => { - const start = question.content.start; const min = Number(target.value); const max = Number(question.content.range.split("—")[1]); @@ -70,15 +96,9 @@ export default function SliderOptions({ question }: Props) { updateQuestion(question.id, (question) => { if (question.type !== "number") return; - question.content.range = `${max - 1 >= 0 ? max - 1 : 0}—${question.content.range.split("—")[1]}`; - }); - } - - if (start < min) { - updateQuestion(question.id, (question) => { - if (question.type !== "number") return; - - question.content.start = min; + question.content.range = `${max - 1 >= 0 ? max - 1 : 0}—${ + question.content.range.split("—")[1] + }`; }); } }} @@ -94,11 +114,12 @@ export default function SliderOptions({ question }: Props) { updateQuestion(question.id, (question) => { if (question.type !== "number") return; - question.content.range = `${question.content.range.split("—")[0]}—${target.value}`; + question.content.range = `${ + question.content.range.split("—")[0] + }—${target.value}`; }); }} onBlur={({ target }) => { - const start = question.content.start; const step = question.content.step; const min = Number(question.content.range.split("—")[0]); const max = Number(target.value); @@ -108,15 +129,9 @@ export default function SliderOptions({ question }: Props) { updateQuestion(question.id, (question) => { if (question.type !== "number") return; - question.content.range = `${min}—${min + 1 >= 100 ? 100 : min + 1}`; - }); - } - - if (start > max) { - updateQuestion(question.id, (question) => { - if (question.type !== "number") return; - - question.content.start = max; + question.content.range = `${min}—${ + min + 1 >= 100 ? 100 : min + 1 + }`; }); } @@ -128,7 +143,11 @@ export default function SliderOptions({ question }: Props) { }); if (range % step) { - setStepError(`Шаг должен делить без остатка диапазон ${max} - ${min} = ${max - min}`); + setStepError( + `Шаг должен делить без остатка диапазон ${max} - ${min} = ${ + max - min + }` + ); } else { setStepError(""); } @@ -147,7 +166,14 @@ export default function SliderOptions({ question }: Props) { }} > - + Начальное значение { updateQuestion(question.id, (question) => { if (question.type !== "number") return; @@ -205,7 +232,11 @@ export default function SliderOptions({ question }: Props) { } if (range % step) { - setStepError(`Шаг должен делить без остатка диапазон ${max} - ${min} = ${max - min}`); + setStepError( + `Шаг должен делить без остатка диапазон ${max} - ${min} = ${ + max - min + }` + ); } else { setStepError(""); } @@ -214,7 +245,11 @@ export default function SliderOptions({ question }: Props) { - + ); diff --git a/src/ui_kit/CustomNumberField.tsx b/src/ui_kit/CustomNumberField.tsx index 8797d74f..9a443fc7 100644 --- a/src/ui_kit/CustomNumberField.tsx +++ b/src/ui_kit/CustomNumberField.tsx @@ -9,6 +9,7 @@ interface CustomNumberFieldProps { onKeyDown?: (event: KeyboardEvent) => void; onBlur?: (event: FocusEvent) => void; error?: string; + emptyError?: boolean; value: string; sx?: SxProps; min?: number; @@ -20,6 +21,7 @@ export default function CustomNumberField({ value, sx, error, + emptyError, onChange, onKeyDown, onBlur, @@ -34,32 +36,20 @@ export default function CustomNumberField({ inputValue.match(/^\d*$/) || (inputValue[0] === "-" && inputValue.slice(1).match(/^\d*$/)) ) { + console.log("inputValue", inputValue); onChange?.({ ...event, target: { ...event.target, value: inputValue } }); } }; - const onInputBlur = (event: FocusEvent) => { - const inputValue = event.target.value; - - if (Number(inputValue) < min) { - onChange?.({ ...event, target: { ...event.target, value: String(min) } }); - } - - if (Number(inputValue) > max) { - onChange?.({ ...event, target: { ...event.target, value: String(max) } }); - } - - onBlur?.(event); - }; - return ( ); diff --git a/src/ui_kit/CustomTextField.tsx b/src/ui_kit/CustomTextField.tsx index 34dc98b8..8ce1f705 100755 --- a/src/ui_kit/CustomTextField.tsx +++ b/src/ui_kit/CustomTextField.tsx @@ -7,6 +7,7 @@ interface CustomTextFieldProps { placeholder: string; value?: string; error?: string; + emptyError?: boolean; onChange?: (event: ChangeEvent) => void; onKeyDown?: (event: KeyboardEvent) => void; onBlur?: (event: FocusEvent) => void; @@ -25,6 +26,7 @@ export default function CustomTextField({ text, sx, error, + emptyError, InputProps, maxLength = 200, }: CustomTextFieldProps) { @@ -62,7 +64,7 @@ export default function CustomTextField({ value={inputValue} placeholder={placeholder} onChange={handleInputChange} - error={!!error} + error={!!error || emptyError} label={error} onFocus={handleInputFocus} onBlur={handleInputBlur} From d179e0cecaa78693cdb3f1b840f509bcd5123fa8 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 19 Dec 2023 15:31:01 +0300 Subject: [PATCH 2/5] fix: min max value --- .../Questions/SliderOptions/SliderOptions.tsx | 45 +++++++++---------- src/ui_kit/CustomNumberField.tsx | 17 ++++++- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/pages/Questions/SliderOptions/SliderOptions.tsx b/src/pages/Questions/SliderOptions/SliderOptions.tsx index a449d69c..b178d82d 100644 --- a/src/pages/Questions/SliderOptions/SliderOptions.tsx +++ b/src/pages/Questions/SliderOptions/SliderOptions.tsx @@ -17,12 +17,13 @@ export default function SliderOptions({ question }: Props) { const [switchState, setSwitchState] = useState("setting"); const [stepError, setStepError] = useState(""); const [startError, setStartError] = useState(false); + const [minError, setMinError] = useState(false); + const [maxError, setMaxError] = useState(false); useEffect(() => { const min = Number(question.content.range.split("—")[0]); const max = Number(question.content.range.split("—")[1]); const start = Number(question.content.start); - console.log(min, max, start); if (start < min || start > max) { setStartError(true); @@ -79,7 +80,11 @@ export default function SliderOptions({ question }: Props) { min={0} max={99999999999} value={question.content.range.split("—")[0]} + emptyError={minError} onChange={({ target }) => { + const min = Number(target.value); + const max = Number(question.content.range.split("—")[1]); + updateQuestion(question.id, (question) => { if (question.type !== "number") return; @@ -87,19 +92,12 @@ export default function SliderOptions({ question }: Props) { question.content.range.split("—")[1] }`; }); - }} - onBlur={({ target }) => { - const min = Number(target.value); - const max = Number(question.content.range.split("—")[1]); if (min >= max) { - updateQuestion(question.id, (question) => { - if (question.type !== "number") return; - - question.content.range = `${max - 1 >= 0 ? max - 1 : 0}—${ - question.content.range.split("—")[1] - }`; - }); + setMinError(true); + } else { + setMinError(false); + setMaxError(false); } }} /> @@ -110,7 +108,11 @@ export default function SliderOptions({ question }: Props) { min={0} max={100000000000} value={question.content.range.split("—")[1]} + emptyError={maxError} onChange={({ target }) => { + const min = Number(question.content.range.split("—")[0]); + const max = Number(target.value); + updateQuestion(question.id, (question) => { if (question.type !== "number") return; @@ -118,6 +120,13 @@ export default function SliderOptions({ question }: Props) { question.content.range.split("—")[0] }—${target.value}`; }); + + if (max <= min) { + setMaxError(true); + } else { + setMaxError(false); + setMinError(false); + } }} onBlur={({ target }) => { const step = question.content.step; @@ -125,16 +134,6 @@ export default function SliderOptions({ question }: Props) { const max = Number(target.value); const range = max - min; - if (max <= min) { - updateQuestion(question.id, (question) => { - if (question.type !== "number") return; - - question.content.range = `${min}—${ - min + 1 >= 100 ? 100 : min + 1 - }`; - }); - } - if (step > max) { updateQuestion(question.id, (question) => { if (question.type !== "number") return; @@ -179,8 +178,6 @@ export default function SliderOptions({ question }: Props) { { diff --git a/src/ui_kit/CustomNumberField.tsx b/src/ui_kit/CustomNumberField.tsx index 9a443fc7..c74be2eb 100644 --- a/src/ui_kit/CustomNumberField.tsx +++ b/src/ui_kit/CustomNumberField.tsx @@ -36,11 +36,24 @@ export default function CustomNumberField({ inputValue.match(/^\d*$/) || (inputValue[0] === "-" && inputValue.slice(1).match(/^\d*$/)) ) { - console.log("inputValue", inputValue); onChange?.({ ...event, target: { ...event.target, value: inputValue } }); } }; + const onInputBlur = (event: FocusEvent) => { + const inputValue = event.target.value; + + if (Number(inputValue) < min) { + onChange?.({ ...event, target: { ...event.target, value: String(min) } }); + } + + if (Number(inputValue) > max) { + onChange?.({ ...event, target: { ...event.target, value: String(max) } }); + } + + onBlur?.(event); + }; + return ( ); From 223ec98bc44cc2d0ad4d227762333a584998d798 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 19 Dec 2023 16:15:42 +0300 Subject: [PATCH 3/5] feat: stepError logic --- .../Questions/SliderOptions/SliderOptions.tsx | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/pages/Questions/SliderOptions/SliderOptions.tsx b/src/pages/Questions/SliderOptions/SliderOptions.tsx index b178d82d..d1fa632d 100644 --- a/src/pages/Questions/SliderOptions/SliderOptions.tsx +++ b/src/pages/Questions/SliderOptions/SliderOptions.tsx @@ -34,6 +34,21 @@ export default function SliderOptions({ question }: Props) { } }, [question.content.range, question.content.start]); + useEffect(() => { + const min = Number(question.content.range.split("—")[0]); + const max = Number(question.content.range.split("—")[1]); + const step = Number(question.content.step); + const range = max - min; + + if (range % step) { + setStepError( + `Шаг должен делить без остатка диапазон ${max} - ${min} = ${max - min}` + ); + } else { + setStepError(""); + } + }, [question]); + const SSHC = (data: string) => { setSwitchState(data); }; @@ -132,7 +147,6 @@ export default function SliderOptions({ question }: Props) { const step = question.content.step; const min = Number(question.content.range.split("—")[0]); const max = Number(target.value); - const range = max - min; if (step > max) { updateQuestion(question.id, (question) => { @@ -140,16 +154,6 @@ export default function SliderOptions({ question }: Props) { question.content.step = min; }); - - if (range % step) { - setStepError( - `Шаг должен делить без остатка диапазон ${max} - ${min} = ${ - max - min - }` - ); - } else { - setStepError(""); - } } }} /> @@ -217,7 +221,6 @@ export default function SliderOptions({ question }: Props) { onBlur={({ target }) => { const min = Number(question.content.range.split("—")[0]); const max = Number(question.content.range.split("—")[1]); - const range = max - min; const step = Number(target.value); if (step > max) { @@ -227,16 +230,6 @@ export default function SliderOptions({ question }: Props) { question.content.step = max; }); } - - if (range % step) { - setStepError( - `Шаг должен делить без остатка диапазон ${max} - ${min} = ${ - max - min - }` - ); - } else { - setStepError(""); - } }} /> From 6056d32fd8b21ff71a3a7ab64a333c48a49dd9eb Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 19 Dec 2023 16:40:46 +0300 Subject: [PATCH 4/5] fix: step --- .../Questions/SliderOptions/SliderOptions.tsx | 5 ++- .../ViewPublicationPage/questions/Number.tsx | 34 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/pages/Questions/SliderOptions/SliderOptions.tsx b/src/pages/Questions/SliderOptions/SliderOptions.tsx index d1fa632d..4a7225fe 100644 --- a/src/pages/Questions/SliderOptions/SliderOptions.tsx +++ b/src/pages/Questions/SliderOptions/SliderOptions.tsx @@ -206,8 +206,8 @@ export default function SliderOptions({ question }: Props) { { - const min = Number(question.content.range.split("—")[0]); const max = Number(question.content.range.split("—")[1]); const step = Number(target.value); diff --git a/src/pages/ViewPublicationPage/questions/Number.tsx b/src/pages/ViewPublicationPage/questions/Number.tsx index 28936e83..6056beab 100644 --- a/src/pages/ViewPublicationPage/questions/Number.tsx +++ b/src/pages/ViewPublicationPage/questions/Number.tsx @@ -18,21 +18,29 @@ export const Number = ({ currentQuestion }: NumberProps) => { const [maxRange, setMaxRange] = useState("100000000000"); const theme = useTheme(); const { answers } = useQuizViewStore(); - const updateMinRangeDebounced = useDebouncedCallback((value, crowded = false) => { - if (crowded) { - setMinRange(maxRange); - } + const updateMinRangeDebounced = useDebouncedCallback( + (value, crowded = false) => { + if (crowded) { + setMinRange(maxRange); + } - updateAnswer(currentQuestion.content.id, value); - }, 1000); - const updateMaxRangeDebounced = useDebouncedCallback((value, crowded = false) => { - if (crowded) { - setMaxRange(minRange); - } + updateAnswer(currentQuestion.content.id, value); + }, + 1000 + ); + const updateMaxRangeDebounced = useDebouncedCallback( + (value, crowded = false) => { + if (crowded) { + setMaxRange(minRange); + } - updateAnswer(currentQuestion.content.id, value); - }, 1000); - const answer = answers.find(({ questionId }) => questionId === currentQuestion.content.id)?.answer as string; + updateAnswer(currentQuestion.content.id, value); + }, + 1000 + ); + const answer = answers.find( + ({ questionId }) => questionId === currentQuestion.content.id + )?.answer as string; const min = window.Number(currentQuestion.content.range.split("—")[0]); const max = window.Number(currentQuestion.content.range.split("—")[1]); From 0c04498dde2f4d53983790315b62575e1fa8761f Mon Sep 17 00:00:00 2001 From: Tamara Date: Wed, 20 Dec 2023 10:44:44 +0300 Subject: [PATCH 5/5] =?UTF-8?q?=D1=81=D0=B2=D0=BE=D1=80=D0=B0=D1=87=D0=B8?= =?UTF-8?q?=D0=B2=D0=B0=D0=B5=D0=BC=D0=BE=D1=81=D1=82=D1=8C=20=D0=BF=D0=BB?= =?UTF-8?q?=D0=B0=D1=88=D0=B5=D0=BA=20=D0=B0=D0=BD=D0=BA=D0=B5=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FormDraggableList/QuestionPageCard.tsx | 396 +++++++++++------- 1 file changed, 254 insertions(+), 142 deletions(-) diff --git a/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx b/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx index d4f140f5..103aef35 100644 --- a/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx +++ b/src/pages/Questions/Form/FormDraggableList/QuestionPageCard.tsx @@ -11,8 +11,23 @@ import OptionsPict from "@icons/questionsPage/options_pict"; import Page from "@icons/questionsPage/page"; import RatingIcon from "@icons/questionsPage/rating"; import Slider from "@icons/questionsPage/slider"; -import { Box, FormControlLabel, IconButton, InputAdornment, Paper, useMediaQuery, useTheme } from "@mui/material"; -import { toggleExpandQuestion, updateQuestion, updateUntypedQuestion } from "@root/questions/actions"; +import { + Box, Checkbox, + FormControl, + FormControlLabel, + IconButton, + InputAdornment, + Paper, TextField, + useMediaQuery, + useTheme +} from "@mui/material"; +import { + copyQuestion, + deleteQuestion, deleteQuestionWithTimeout, + toggleExpandQuestion, + updateQuestion, + updateUntypedQuestion +} from "@root/questions/actions"; import CustomTextField from "@ui_kit/CustomTextField"; import { useRef, useState } from "react"; import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd"; @@ -51,150 +66,247 @@ export default function QuestionsPageCard({ question, questionIndex, draggablePr }); }, 200); - return ( - <> - - - - setTitle(target.value)} - sx={{ width: "100%" }} - InputProps={{ - startAdornment: ( - - setOpen((isOpened) => !isOpened)} - > - {IconAndrom(question.type)} - - setOpen(false)} - anchorRef={anchorRef} - question={question} - questionType={question.type} - /> - - ), - }} - /> - + - - toggleExpandQuestion(question.id)} - > - {question.expanded ? ( - - ) : ( - - )} - - - {questionIndex + 1} + + + setTitle(target.value)} + sx={{ + width: "100%", + margin: isMobile ? "10px 0" : 0, + "& .MuiInputBase-root": { + color: "#000000", + backgroundColor: question.expanded + ? theme.palette.background.default + : "transparent", + height: "48px", + borderRadius: "10px", + ".MuiOutlinedInput-notchedOutline": { + borderWidth: "1px !important", + border: !question.expanded ? "none" : null, + }, + "& .MuiInputBase-input::placeholder": { + color: "#4D4D4D", + opacity: 0.8, + }, + }, + }} + InputProps={{ + startAdornment: ( + + setOpen((isOpened) => !isOpened)} + > + {IconAndrom(question.type)} + + setOpen(false)} + anchorRef={anchorRef} + question={question} + questionType={question.type} + /> + + ), + }} + /> + + + + toggleExpandQuestion(question.id)} + > + {question.expanded ? ( + + ) : ( + + )} + + + {question.expanded ? ( + <> + ) : ( + + + } + checkedIcon={} + /> + } + label={""} + sx={{ + color: theme.palette.grey2.main, + ml: "-9px", + mr: 0, + userSelect: "none", + }} + /> + copyQuestion(question.id, question.quizId)} + > + + + { + deleteQuestionWithTimeout(question.id, deleteQuestion(question.id)); + + }} + > + + + + )} + + + {questionIndex + 1} + + + + + + + + + {question.expanded && ( + <> + {question.type === null ? ( + + ) : ( + + )} + + )} - - - - - - - - - {question.type === null ? ( - - ) : ( - - )} - - - - ); + + + ); } const IconAndrom = (questionType: QuestionType | null) => {