frontPanel/src/pages/Questions/RatingOptions/RatingOptions.tsx

254 lines
8.3 KiB
TypeScript
Raw Normal View History

2023-09-27 07:55:11 +00:00
import { useState, useEffect, useRef } from "react";
2023-09-06 13:20:12 +00:00
import { useParams } from "react-router-dom";
2023-09-27 07:55:11 +00:00
import {
Box,
Typography,
TextField,
useMediaQuery,
useTheme,
} from "@mui/material";
import { useDebouncedCallback } from "use-debounce";
import { questionStore, updateQuestionsList } from "@root/questions";
import ButtonsOptions from "../ButtonsOptions";
import SwitchRating from "./switchRating";
2023-09-18 07:45:14 +00:00
import TropfyIcon from "../../../assets/icons/questionsPage/tropfyIcon";
import FlagIcon from "../../../assets/icons/questionsPage/FlagIcon";
import HeartIcon from "../../../assets/icons/questionsPage/heartIcon";
import LikeIcon from "../../../assets/icons/questionsPage/likeIcon";
import LightbulbIcon from "../../../assets/icons/questionsPage/lightbulbIcon";
import HashtagIcon from "../../../assets/icons/questionsPage/hashtagIcon";
import StarIconMini from "../../../assets/icons/questionsPage/StarIconMini";
2023-08-24 11:09:47 +00:00
interface Props {
totalIndex: number;
}
2023-09-18 07:45:14 +00:00
export type ButtonRatingFrom = {
name: string;
icon: JSX.Element;
};
2023-08-24 11:09:47 +00:00
export default function RatingOptions({ totalIndex }: Props) {
2023-09-06 06:47:23 +00:00
const [switchState, setSwitchState] = useState("setting");
2023-09-27 07:55:11 +00:00
const [negativeText, setNegativeText] = useState<string>("");
const [positiveText, setPositiveText] = useState<string>("");
const [negativeTextWidth, setNegativeTextWidth] = useState<number>(0);
const [positiveTextWidth, setPositiveTextWidth] = useState<number>(0);
2023-09-06 13:20:12 +00:00
const quizId = Number(useParams().quizId);
2023-09-06 06:47:23 +00:00
const { listQuestions } = questionStore();
2023-08-24 11:09:47 +00:00
const theme = useTheme();
2023-09-15 12:37:12 +00:00
const isMobile = useMediaQuery(theme.breakpoints.down(790));
2023-09-27 07:55:11 +00:00
const negativeRef = useRef<HTMLDivElement>(null);
const positiveRef = useRef<HTMLDivElement>(null);
const debounceNegativeDescription = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
ratingNegativeDescription: value.substring(0, 15),
},
});
}, 500);
const debouncePositiveDescription = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
ratingPositiveDescription: value.substring(0, 15),
},
});
}, 500);
useEffect(() => {
setNegativeText(
listQuestions[quizId][totalIndex].content.ratingNegativeDescription
);
setPositiveText(
listQuestions[quizId][totalIndex].content.ratingPositiveDescription
);
}, []);
useEffect(() => {
setNegativeTextWidth(negativeRef.current?.offsetWidth || 0);
}, [negativeText]);
useEffect(() => {
setPositiveTextWidth(positiveRef.current?.offsetWidth || 0);
}, [positiveText]);
2023-09-06 06:47:23 +00:00
2023-09-18 07:45:14 +00:00
const buttonRatingForm: ButtonRatingFrom[] = [
2023-09-26 21:11:27 +00:00
{ name: "star", icon: <StarIconMini width={"50px"} color={theme.palette.grey2.main} /> },
2023-09-18 07:45:14 +00:00
{ name: "trophie", icon: <TropfyIcon color={theme.palette.grey2.main} /> },
{ name: "flag", icon: <FlagIcon color={theme.palette.grey2.main} /> },
{ name: "heart", icon: <HeartIcon color={theme.palette.grey2.main} /> },
{ name: "like", icon: <LikeIcon color={theme.palette.grey2.main} /> },
{
name: "bubble",
icon: <LightbulbIcon color={theme.palette.grey2.main} />,
},
{ name: "hashtag", icon: <HashtagIcon color={theme.palette.grey2.main} /> },
];
2023-08-24 11:09:47 +00:00
const SSHC = (data: string) => {
setSwitchState(data);
};
2023-09-06 06:47:23 +00:00
2023-08-24 11:09:47 +00:00
return (
<>
<Box
sx={{
2023-09-21 12:15:49 +00:00
width: isMobile
? "auto"
2023-09-28 06:38:22 +00:00
: `${
listQuestions[quizId][totalIndex].content.steps * 44 >
negativeTextWidth + positiveTextWidth
? listQuestions[quizId][totalIndex].content.steps * 44
: negativeTextWidth + positiveTextWidth + 20
}px`,
2023-09-27 07:55:11 +00:00
minWidth: "300px",
2023-09-21 12:15:49 +00:00
maxWidth: "440px",
2023-08-24 11:09:47 +00:00
display: "flex",
2023-09-26 21:11:27 +00:00
px: "20px",
2023-08-24 11:09:47 +00:00
flexDirection: "column",
gap: "20px",
}}
>
2023-09-27 07:55:11 +00:00
<Box
sx={{
display: "flex",
justifyContent: "space-between",
padding: "0 10px",
gap: isMobile ? "10px" : "15px",
}}
>
2023-09-18 07:45:14 +00:00
{Array.from(
{ length: listQuestions[quizId][totalIndex].content.steps },
(_, index) => index
).map((itemNumber) => (
2023-09-27 07:55:11 +00:00
<Box key={itemNumber} sx={{ transform: "scale(1.5)" }}>
2023-09-18 07:45:14 +00:00
{
buttonRatingForm.find(
({ name }) =>
listQuestions[quizId][totalIndex].content.form === name
)?.icon
}
</Box>
))}
2023-09-12 09:56:15 +00:00
</Box>
2023-08-24 11:09:47 +00:00
<Box
sx={{
2023-09-26 21:11:27 +00:00
mb: "20px",
2023-08-24 11:09:47 +00:00
display: "flex",
alignItems: "center",
justifyContent: "space-between",
2023-09-26 21:11:27 +00:00
maxWidth: isMobile ? "303px" : "290px",
width: "100%",
2023-08-24 11:09:47 +00:00
}}
>
<Typography
2023-09-27 07:55:11 +00:00
ref={negativeRef}
2023-08-24 11:09:47 +00:00
sx={{
2023-09-27 07:55:11 +00:00
position: "absolute",
opacity: 0,
zIndex: "-100",
whiteSpace: "nowrap",
2023-08-24 11:09:47 +00:00
fontSize: "16px",
}}
>
2023-09-27 07:55:11 +00:00
{negativeText}
2023-08-24 11:09:47 +00:00
</Typography>
2023-09-27 07:55:11 +00:00
<TextField
defaultValue={
listQuestions[quizId][totalIndex].content
.ratingNegativeDescription
}
value={negativeText}
placeholder="Негативно"
onChange={({ target }) => {
if (target.value.length <= 15) {
setNegativeText(target.value);
debounceNegativeDescription(target.value);
}
}}
onBlur={({ target }) => debounceNegativeDescription(target.value)}
sx={{
width: negativeTextWidth + 10 + "px",
background: "transparent",
fontSize: "18px",
minWidth: "95px",
maxWidth: "230px",
transition: "0.2s",
"& .MuiInputBase-root": {
"& .MuiInputBase-input": {
color: theme.palette.grey2.main,
fontSize: "16px",
padding: "0 3px",
borderRadius: "3px",
border: "1px solid",
borderColor: "transparent",
"&:hover, &:focus": {
borderColor: theme.palette.grey2.main,
2023-09-12 09:56:15 +00:00
},
2023-09-27 07:55:11 +00:00
},
"& .MuiOutlinedInput-notchedOutline": {
outline: "none",
border: "none",
},
},
}}
/>
2023-08-24 11:09:47 +00:00
<Typography
2023-09-27 07:55:11 +00:00
ref={positiveRef}
2023-08-24 11:09:47 +00:00
sx={{
2023-09-27 07:55:11 +00:00
position: "absolute",
opacity: 0,
zIndex: "-100",
whiteSpace: "nowrap",
2023-08-24 11:09:47 +00:00
fontSize: "16px",
}}
>
2023-09-27 07:55:11 +00:00
{positiveText}
2023-08-24 11:09:47 +00:00
</Typography>
2023-09-27 07:55:11 +00:00
<TextField
value={positiveText}
placeholder="Позитивно"
onChange={({ target }) => {
if (target.value.length <= 15) {
setPositiveText(target.value);
debouncePositiveDescription(target.value);
}
}}
onBlur={({ target }) => debouncePositiveDescription(target.value)}
sx={{
width: positiveTextWidth + 10 + "px",
background: "transparent",
fontSize: "18px",
minWidth: "95px",
maxWidth: "230px",
transition: "0.2s",
"& .MuiInputBase-root": {
"& .MuiInputBase-input": {
color: theme.palette.grey2.main,
fontSize: "16px",
padding: "0 3px",
borderRadius: "3px",
border: "1px solid",
borderColor: "transparent",
"&:hover, &:focus": {
borderColor: theme.palette.grey2.main,
2023-09-12 09:56:15 +00:00
},
2023-09-27 07:55:11 +00:00
},
"& .MuiOutlinedInput-notchedOutline": {
outline: "none",
border: "none",
},
},
}}
/>
</Box>
2023-08-24 11:09:47 +00:00
</Box>
2023-09-26 21:11:27 +00:00
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
2023-08-24 11:09:47 +00:00
<SwitchRating switchState={switchState} totalIndex={totalIndex} />
</>
);
}