frontPanel/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx

161 lines
5.9 KiB
TypeScript
Raw Normal View History

2023-10-09 12:33:45 +00:00
import { Box, Button, LinearProgress, Paper, Typography } from "@mui/material";
2023-11-20 17:22:13 +00:00
import { useQuestionsStore } from "@root/questions/store";
2023-10-17 13:24:37 +00:00
import {
2023-11-13 18:04:51 +00:00
decrementCurrentQuestionIndex,
incrementCurrentQuestionIndex,
useQuizPreviewStore,
2023-10-17 13:24:37 +00:00
} from "@root/quizPreview";
2023-11-29 13:49:52 +00:00
import { AnyTypedQuizQuestion, UntypedQuizQuestion } from "model/questionTypes/shared";
2023-11-13 18:04:51 +00:00
import { useEffect } from "react";
2023-10-09 12:33:45 +00:00
import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft";
import Date from "./QuizPreviewQuestionTypes/Date";
2023-10-09 16:04:12 +00:00
import Emoji from "./QuizPreviewQuestionTypes/Emoji";
2023-10-09 12:33:45 +00:00
import File from "./QuizPreviewQuestionTypes/File";
2023-10-09 16:04:12 +00:00
import Images from "./QuizPreviewQuestionTypes/Images";
import Number from "./QuizPreviewQuestionTypes/Number";
2023-10-09 12:33:45 +00:00
import Page from "./QuizPreviewQuestionTypes/Page";
import Rating from "./QuizPreviewQuestionTypes/Rating";
2023-10-09 16:04:12 +00:00
import Select from "./QuizPreviewQuestionTypes/Select";
import Text from "./QuizPreviewQuestionTypes/Text";
import Variant from "./QuizPreviewQuestionTypes/Variant";
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
2023-11-20 17:22:13 +00:00
import { notReachable } from "../../utils/notReachable";
2023-10-09 12:33:45 +00:00
export default function QuizPreviewLayout() {
2023-11-20 17:22:13 +00:00
const questions = useQuestionsStore(state => state.questions);
2023-11-13 18:04:51 +00:00
const currentQuizStep = useQuizPreviewStore(
(state) => state.currentQuestionIndex
);
2023-10-09 12:33:45 +00:00
2023-11-20 17:22:13 +00:00
const nonDeletedQuizQuestions = questions.filter(
2023-11-13 18:04:51 +00:00
(question) => !question.deleted
);
const maxCurrentQuizStep =
nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0;
const currentProgress = Math.floor(
(currentQuizStep / maxCurrentQuizStep) * 100
);
2023-10-09 16:04:12 +00:00
2023-11-13 18:04:51 +00:00
const currentQuestion = nonDeletedQuizQuestions[currentQuizStep];
2023-10-09 12:33:45 +00:00
2023-11-13 18:04:51 +00:00
useEffect(
function resetCurrentQuizStep() {
if (currentQuizStep > maxCurrentQuizStep) {
decrementCurrentQuestionIndex();
}
},
[currentQuizStep, maxCurrentQuizStep]
);
2023-10-09 12:33:45 +00:00
2023-11-13 18:04:51 +00:00
return (
<Paper
className="quiz-preview-draghandle"
data-cy="quiz-preview-layout"
sx={{
height: "100%",
display: "flex",
flexDirection: "column",
flexGrow: 1,
borderRadius: "12px",
pointerEvents: "auto",
}}
2023-10-17 13:24:37 +00:00
>
2023-11-13 18:04:51 +00:00
<Box
sx={{
p: "16px",
whiteSpace: "break-spaces",
overflowY: "auto",
flexGrow: 1,
"&::-webkit-scrollbar": { width: 0 },
}}
>
<QuestionPreviewComponent question={currentQuestion} />
</Box>
<Box
sx={{
mt: "auto",
p: "16px",
display: "flex",
borderTop: "1px solid #E3E3E3",
alignItems: "center",
}}
>
<Box
sx={{
flexGrow: 1,
display: "flex",
flexDirection: "column",
gap: 1,
}}
>
<Typography>
{nonDeletedQuizQuestions.length > 0
? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length
}`
: "Нет вопросов"}
</Typography>
{nonDeletedQuizQuestions.length > 0 && (
<LinearProgress
variant="determinate"
value={currentProgress}
sx={{
"&.MuiLinearProgress-colorPrimary": {
backgroundColor: "fadePurple.main",
},
"& .MuiLinearProgress-barColorPrimary": {
backgroundColor: "brightPurple.main",
},
}}
/>
)}
</Box>
<Box
sx={{
ml: 2,
display: "flex",
gap: 1,
}}
>
<Button
variant="outlined"
onClick={decrementCurrentQuestionIndex}
disabled={currentQuizStep === 0}
sx={{ px: 1, minWidth: 0 }}
>
<ArrowLeft />
</Button>
<Button
variant="contained"
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
disabled={currentQuizStep >= maxCurrentQuizStep}
>
Далее
</Button>
</Box>
</Box>
</Paper>
);
}
function QuestionPreviewComponent({ question }: {
2023-11-29 13:49:52 +00:00
question: AnyTypedQuizQuestion | UntypedQuizQuestion;
2023-11-13 18:04:51 +00:00
}) {
2023-11-29 13:49:52 +00:00
if (question.type === null) return null;
2023-11-13 18:04:51 +00:00
switch (question.type) {
case "variant": return <Variant question={question} />;
case "images": return <Images question={question} />;
case "varimg": return <Varimg question={question} />;
case "emoji": return <Emoji question={question} />;
case "text": return <Text question={question} />;
case "select": return <Select question={question} />;
case "date": return <Date question={question} />;
case "number": return <Number question={question} />;
case "file": return <File question={question} />;
case "page": return <Page question={question} />;
case "rating": return <Rating question={question} />;
2023-11-20 17:22:13 +00:00
default: notReachable(question);
2023-11-13 18:04:51 +00:00
}
2023-10-09 12:33:45 +00:00
}