frontPanel/src/pages/Questions/SliderOptions/SliderOptions.tsx
2023-12-27 11:28:37 +03:00

282 lines
8.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useState } from "react";
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
import { useDebouncedCallback } from "use-debounce";
import CustomNumberField from "@ui_kit/CustomNumberField";
import ButtonsOptions from "../ButtonsOptions";
import SwitchSlider from "./switchSlider";
import { updateQuestion } from "@root/questions/actions";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
interface Props {
question: QuizQuestionNumber;
}
export default function SliderOptions({ question }: Props) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const [switchState, setSwitchState] = useState("setting");
const [stepError, setStepError] = useState("");
const [startError, setStartError] = useState<boolean>(false);
const [minError, setMinError] = useState<boolean>(false);
const [maxError, setMaxError] = useState<boolean>(false);
const startValueDebounce = useDebouncedCallback((value) => {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.start = value;
});
}, 2000);
useEffect(() => {
const min = Number(question.content.range.split("—")[0]);
const max = Number(question.content.range.split("—")[1]);
const start = Number(question.content.start);
if (start < min) {
setStartError(true);
startValueDebounce(min);
return;
}
if (start > max && min < max) {
setStartError(true);
startValueDebounce(max);
return;
}
if (start >= min && start <= max) {
setStartError(false);
}
}, [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);
};
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",
}}
>
<Typography
sx={{ fontWeight: "500", fontSize: "18px", color: "#4D4D4D" }}
>
Выбор значения из диапазона
</Typography>
<Box
sx={{
width: "100%",
display: "flex",
alignItems: "center",
gap: isMobile ? "9px" : "20px",
}}
>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"0"}
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;
question.content.range = `${target.value}${
question.content.range.split("—")[1]
}`;
});
if (min >= max) {
setMinError(true);
} else {
setMinError(false);
setMaxError(false);
}
}}
/>
<Typography></Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"100"}
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;
question.content.range = `${
question.content.range.split("—")[0]
}${target.value}`;
});
if (max <= min) {
setMaxError(true);
} else {
setMaxError(false);
setMinError(false);
}
}}
onBlur={({ target }) => {
const step = question.content.step;
const min = Number(question.content.range.split("—")[0]);
const max = Number(target.value);
if (step > max) {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.step = min;
});
}
}}
/>
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
flexDirection: isMobile ? "column-reverse" : "",
gap: isMobile ? "15px" : "50px",
}}
>
<Box sx={{ width: "100%" }}>
<Typography
sx={{
fontWeight: "500",
fontSize: "18px",
color: "#4D4D4D",
mb: isMobile ? "10px" : "14px",
}}
>
Начальное значение
</Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
placeholder={"50"}
value={String(question.content.start)}
emptyError={startError}
onChange={({ target }) => {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.start = Number(target.value);
});
}}
/>
</Box>
<Box sx={{ width: "100%" }}>
<Typography
sx={{
fontWeight: "500",
fontSize: "18px",
color: "#4D4D4D",
mb: "10px",
}}
>
Шаг
</Typography>
<CustomNumberField
sx={{ maxWidth: "310px", width: "100%" }}
min={Number(question.content.range.split("—")[0])}
max={Number(question.content.range.split("—")[1])}
placeholder={"1"}
error={stepError}
value={String(question.content.step)}
onChange={({ target, type }) => {
if (type === "blur") {
return;
}
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.step = Number(target.value);
});
}}
onBlur={({ target }) => {
const min = Number(question.content.range.split("—")[0]);
const max = Number(question.content.range.split("—")[1]);
const step = Number(target.value);
const range = max - min;
if (step > max) {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.step = max;
});
}
if (range % step) {
updateQuestion(question.id, (question) => {
if (question.type !== "number") return;
question.content.step = 1;
});
}
}}
/>
</Box>
</Box>
</Box>
<ButtonsOptions
switchState={switchState}
SSHC={SSHC}
question={question}
/>
<SwitchSlider switchState={switchState} question={question} />
</>
);
}