frontPanel/src/pages/Questions/SliderOptions/SliderOptions.tsx

235 lines
7.5 KiB
TypeScript
Raw Normal View History

2024-02-16 14:10:25 +00:00
import { useState } from "react";
2023-09-15 12:37:12 +00:00
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
2024-02-16 14:10:25 +00:00
import { useDebouncedCallback } from "use-debounce";
2023-12-27 08:28:37 +00:00
2023-09-12 14:36:22 +00:00
import CustomNumberField from "@ui_kit/CustomNumberField";
2023-12-27 08:28:37 +00:00
import ButtonsOptions from "../ButtonsOptions";
import SwitchSlider from "./switchSlider";
2023-12-27 08:28:37 +00:00
2023-11-27 23:07:24 +00:00
import { updateQuestion } from "@root/questions/actions";
2023-12-27 08:28:37 +00:00
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
2023-08-24 11:09:47 +00:00
interface Props {
2023-12-15 20:05:16 +00:00
question: QuizQuestionNumber;
openBranchingPage: boolean;
setOpenBranchingPage: (a: boolean) => void;
}
export default function SliderOptions({
question,
openBranchingPage,
setOpenBranchingPage,
}: Props) {
2023-12-15 20:05:16 +00:00
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const [switchState, setSwitchState] = useState("setting");
2024-02-16 14:10:25 +00:00
const [startError, setStartError] = useState("");
2023-12-15 20:05:16 +00:00
const [stepError, setStepError] = useState("");
2024-02-16 14:10:25 +00:00
const updateStartDebounced = useDebouncedCallback((value: number) => {
setStartError("");
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
question.content.start = value;
});
}, 5000);
const updateStepDebounced = useDebouncedCallback((value: number) => {
setStepError("");
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
question.content.step = value;
});
}, 5000);
const calculateValues = () => {
const { step, start } = question.content;
const [min, max] = question.content.range.split("—").map(Number);
const minBorder = min <= max ? min : max;
const maxBorder = max >= min ? max : min;
const range = maxBorder - minBorder;
const reversed = min > max;
if (start < minBorder) {
setStartError("Стартовое значени должно быть внутри диапазона");
updateStartDebounced(reversed ? max : min);
}
if (start > maxBorder) {
setStartError("Стартовое значени должно быть внутри диапазона");
updateStartDebounced(reversed ? min : max);
}
if (!step) {
setStepError("Стартовое значение должно быть больше 0");
updateStepDebounced(1);
}
if (step > maxBorder) {
setStepError("Шаг не может выходить за пределы диапазона");
updateStepDebounced(1);
}
2023-12-19 13:15:42 +00:00
if (range % step) {
setStepError(
2024-02-16 14:10:25 +00:00
`Шаг должен делить без остатка диапазон ${maxBorder} - ${minBorder} = ${
maxBorder - minBorder
}`,
2023-12-19 13:15:42 +00:00
);
2024-02-16 14:10:25 +00:00
updateStepDebounced(1);
2023-12-19 13:15:42 +00:00
}
2023-12-15 20:05:16 +00:00
};
return (
<>
<Box
sx={{
width: isTablet ? "auto" : "100%",
maxWidth: "720.8px",
display: "flex",
pl: "20px",
pr: isMobile ? "13px" : "20px",
pb: isMobile ? "30px" : "20px",
flexDirection: "column",
gap: isMobile ? "25px" : "20px",
}}
>
<Box
sx={{
gap: isMobile ? "10px" : "14px",
mt: isMobile ? "25px" : "0px",
display: "flex",
flexDirection: "column",
marginRight: isMobile ? "10px" : "0px",
}}
>
2023-12-19 11:23:09 +00:00
<Typography
sx={{ fontWeight: "500", fontSize: "18px", color: "#4D4D4D" }}
>
2023-12-15 20:05:16 +00:00
Выбор значения из диапазона
</Typography>
2023-12-19 11:23:09 +00:00
<Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
gap: isMobile ? "9px" : "20px",
}}
>
2023-12-15 20:05:16 +00:00
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"0"}
min={0}
max={99999999999}
value={question.content.range.split("—")[0]}
onChange={({ target }) => {
2024-02-16 14:10:25 +00:00
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
2023-12-19 11:23:09 +00:00
question.content.range = `${target.value}${
question.content.range.split("—")[1]
}`;
2023-12-15 20:05:16 +00:00
});
}}
2024-02-16 14:10:25 +00:00
onBlur={calculateValues}
2023-12-15 20:05:16 +00:00
/>
<Typography></Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"100"}
min={0}
max={100000000000}
value={question.content.range.split("—")[1]}
onChange={({ target }) => {
2024-02-16 14:10:25 +00:00
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
2023-12-19 11:23:09 +00:00
question.content.range = `${
question.content.range.split("—")[0]
}${target.value}`;
2023-12-15 20:05:16 +00:00
});
}}
2024-02-16 14:10:25 +00:00
onBlur={calculateValues}
2023-12-15 20:05:16 +00:00
/>
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
flexDirection: isMobile ? "column-reverse" : "",
gap: isMobile ? "15px" : "50px",
}}
>
<Box sx={{ width: "100%" }}>
2023-12-19 11:23:09 +00:00
<Typography
sx={{
fontWeight: "500",
fontSize: "18px",
color: "#4D4D4D",
mb: isMobile ? "10px" : "14px",
}}
>
2023-12-15 20:05:16 +00:00
Начальное значение
</Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"50"}
value={String(question.content.start)}
2024-02-16 14:10:25 +00:00
error={startError}
2023-12-15 20:05:16 +00:00
onChange={({ target }) => {
2024-02-16 14:10:25 +00:00
const newValue = Number(target.value);
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
question.content.start = newValue;
2023-12-15 20:05:16 +00:00
});
2024-02-16 14:10:25 +00:00
updateStartDebounced(newValue);
2023-12-15 20:05:16 +00:00
}}
2024-02-16 14:10:25 +00:00
onBlur={calculateValues}
2023-12-15 20:05:16 +00:00
/>
</Box>
<Box sx={{ width: "100%" }}>
<Typography
sx={{
fontWeight: "500",
fontSize: "18px",
color: "#4D4D4D",
mb: "10px",
}}
2023-09-22 07:26:07 +00:00
>
2023-12-15 20:05:16 +00:00
Шаг
</Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
2023-12-19 13:40:46 +00:00
min={Number(question.content.range.split("—")[0])}
max={Number(question.content.range.split("—")[1])}
2023-12-15 20:05:16 +00:00
placeholder={"1"}
error={stepError}
value={String(question.content.step)}
2023-12-27 08:28:37 +00:00
onChange={({ target, type }) => {
if (type === "blur") {
return;
}
2024-02-16 14:10:25 +00:00
const newValue = Number(target.value);
updateQuestion<QuizQuestionNumber>(question.id, (question) => {
question.content.step = newValue;
2023-12-15 20:05:16 +00:00
});
2024-02-16 14:10:25 +00:00
updateStepDebounced(newValue);
2023-12-15 20:05:16 +00:00
}}
2024-02-16 14:10:25 +00:00
onBlur={calculateValues}
2023-12-15 20:05:16 +00:00
/>
</Box>
</Box>
</Box>
2023-12-19 11:23:09 +00:00
<ButtonsOptions
switchState={switchState}
2024-02-16 14:10:25 +00:00
SSHC={setSwitchState}
2023-12-19 11:23:09 +00:00
question={question}
openBranchingPage={openBranchingPage}
setOpenBranchingPage={setOpenBranchingPage}
2023-12-19 11:23:09 +00:00
/>
2023-12-15 20:05:16 +00:00
<SwitchSlider switchState={switchState} question={question} />
</>
);
2023-08-24 11:09:47 +00:00
}