fix: preview block
This commit is contained in:
parent
afdf281631
commit
8c125e4d21
@ -1,16 +1,14 @@
|
||||
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
||||
import { Box, IconButton } from "@mui/material";
|
||||
import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview";
|
||||
import { useLayoutEffect, useRef } from "react";
|
||||
import { Rnd } from "react-rnd";
|
||||
import QuizPreviewLayout from "./QuizPreviewLayout";
|
||||
import ResizeIcon from "./ResizeIcon";
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||
|
||||
|
||||
const DRAG_PARENT_MARGIN = 25;
|
||||
const NAVBAR_HEIGHT = 81;
|
||||
const DRAG_PARENT_BOTTOM_MARGIN = 65;
|
||||
const DRAG_PARENT_MARGIN = 0;
|
||||
const NAVBAR_HEIGHT = 0;
|
||||
const DRAG_PARENT_BOTTOM_MARGIN = 0;
|
||||
|
||||
interface RndPositionAndSize {
|
||||
x: number;
|
||||
@ -20,16 +18,28 @@ interface RndPositionAndSize {
|
||||
}
|
||||
|
||||
export default function QuizPreview() {
|
||||
const isPreviewShown = useQuizPreviewStore(state => state.isPreviewShown);
|
||||
const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown);
|
||||
const rndParentRef = useRef<HTMLDivElement>(null);
|
||||
const rndRef = useRef<Rnd | null>(null);
|
||||
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({ x: 0, y: 0, width: "340", height: "480" });
|
||||
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: "340",
|
||||
height: "480",
|
||||
});
|
||||
const isFirstShowRef = useRef<boolean>(true);
|
||||
|
||||
useLayoutEffect(function stickPreviewToBottomRight() {
|
||||
useLayoutEffect(
|
||||
function stickPreviewToBottomRight() {
|
||||
const rnd = rndRef.current;
|
||||
const rndSelfElement = rnd?.getSelfElement();
|
||||
if (!rnd || !rndSelfElement || !rndParentRef.current || !isFirstShowRef.current) return;
|
||||
if (
|
||||
!rnd ||
|
||||
!rndSelfElement ||
|
||||
!rndParentRef.current ||
|
||||
!isFirstShowRef.current
|
||||
)
|
||||
return;
|
||||
|
||||
const rndParentRect = rndParentRef.current.getBoundingClientRect();
|
||||
const rndRect = rndSelfElement.getBoundingClientRect();
|
||||
@ -42,7 +52,9 @@ export default function QuizPreview() {
|
||||
rndPositionAndSizeRef.current.y = y;
|
||||
|
||||
isFirstShowRef.current = false;
|
||||
}, [isPreviewShown]);
|
||||
},
|
||||
[isPreviewShown]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -58,10 +70,10 @@ export default function QuizPreview() {
|
||||
zIndex: 100,
|
||||
}}
|
||||
>
|
||||
{isPreviewShown &&
|
||||
{isPreviewShown && (
|
||||
<Rnd
|
||||
minHeight={300}
|
||||
minWidth={340}
|
||||
minHeight={20}
|
||||
minWidth={20}
|
||||
bounds="parent"
|
||||
ref={rndRef}
|
||||
dragHandleClassName="quiz-preview-draghandle"
|
||||
@ -69,7 +81,7 @@ export default function QuizPreview() {
|
||||
x: rndPositionAndSizeRef.current.x,
|
||||
y: rndPositionAndSizeRef.current.y,
|
||||
width: rndPositionAndSizeRef.current.width,
|
||||
height: rndPositionAndSizeRef.current.height
|
||||
height: rndPositionAndSizeRef.current.height,
|
||||
}}
|
||||
onResizeStop={(e, direction, ref, delta, position) => {
|
||||
rndPositionAndSizeRef.current.x = position.x;
|
||||
@ -88,32 +100,22 @@ export default function QuizPreview() {
|
||||
topLeft: isPreviewShown,
|
||||
}}
|
||||
resizeHandleComponent={{
|
||||
topLeft: <ResizeIcon />
|
||||
topLeft: <ResizeIcon />,
|
||||
}}
|
||||
resizeHandleStyles={{
|
||||
topLeft: {
|
||||
top: "-1px",
|
||||
left: "-1px",
|
||||
}
|
||||
},
|
||||
}}
|
||||
style={{
|
||||
overflow: "hidden",
|
||||
pointerEvents: "auto",
|
||||
}}
|
||||
>
|
||||
<QuizPreviewLayout />
|
||||
<IconButton
|
||||
className="quiz-preview-draghandle"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: -54,
|
||||
right: 46,
|
||||
cursor: "move",
|
||||
}}
|
||||
>
|
||||
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px" }} />
|
||||
</IconButton>
|
||||
</Rnd>
|
||||
}
|
||||
)}
|
||||
<IconButton
|
||||
onClick={toggleQuizPreview}
|
||||
sx={{
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import { Box, Button, LinearProgress, Paper, Typography } from "@mui/material";
|
||||
import { questionStore } from "@root/questions";
|
||||
import { decrementCurrentQuestionIndex, incrementCurrentQuestionIndex, useQuizPreviewStore } from "@root/quizPreview";
|
||||
import {
|
||||
decrementCurrentQuestionIndex,
|
||||
incrementCurrentQuestionIndex,
|
||||
useQuizPreviewStore,
|
||||
} from "@root/quizPreview";
|
||||
import { DefiniteQuestionType } from "model/questionTypes/shared";
|
||||
import { FC, useEffect } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
@ -17,7 +21,6 @@ import Text from "./QuizPreviewQuestionTypes/Text";
|
||||
import Variant from "./QuizPreviewQuestionTypes/Variant";
|
||||
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
|
||||
|
||||
|
||||
const QuestionPreviewComponentByType: Record<DefiniteQuestionType, FC<any>> = {
|
||||
variant: Variant,
|
||||
images: Images,
|
||||
@ -34,66 +37,89 @@ const QuestionPreviewComponentByType: Record<DefiniteQuestionType, FC<any>> = {
|
||||
|
||||
export default function QuizPreviewLayout() {
|
||||
const quizId = useParams().quizId ?? 0;
|
||||
const listQuestions = questionStore(state => state.listQuestions);
|
||||
const currentQuizStep = useQuizPreviewStore(state => state.currentQuestionIndex);
|
||||
const listQuestions = questionStore((state) => state.listQuestions);
|
||||
const currentQuizStep = useQuizPreviewStore(
|
||||
(state) => state.currentQuestionIndex
|
||||
);
|
||||
|
||||
const quizQuestions = listQuestions[quizId] ?? [];
|
||||
const nonDeletedQuizQuestions = quizQuestions.filter(question => !question.deleted);
|
||||
const maxCurrentQuizStep = nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0;
|
||||
const currentProgress = Math.floor((currentQuizStep / maxCurrentQuizStep) * 100);
|
||||
const nonDeletedQuizQuestions = quizQuestions.filter(
|
||||
(question) => !question.deleted
|
||||
);
|
||||
const maxCurrentQuizStep =
|
||||
nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0;
|
||||
const currentProgress = Math.floor(
|
||||
(currentQuizStep / maxCurrentQuizStep) * 100
|
||||
);
|
||||
|
||||
const currentQuestion = nonDeletedQuizQuestions[currentQuizStep];
|
||||
const QuestionComponent = currentQuestion
|
||||
? QuestionPreviewComponentByType[currentQuestion.type as DefiniteQuestionType]
|
||||
? QuestionPreviewComponentByType[
|
||||
currentQuestion.type as DefiniteQuestionType
|
||||
]
|
||||
: null;
|
||||
|
||||
const questionElement = QuestionComponent
|
||||
? <QuestionComponent key={currentQuestion.id} question={currentQuestion} />
|
||||
: null;
|
||||
const questionElement = QuestionComponent ? (
|
||||
<QuestionComponent key={currentQuestion.id} question={currentQuestion} />
|
||||
) : null;
|
||||
|
||||
useEffect(function resetCurrentQuizStep() {
|
||||
useEffect(
|
||||
function resetCurrentQuizStep() {
|
||||
if (currentQuizStep > maxCurrentQuizStep) {
|
||||
decrementCurrentQuestionIndex();
|
||||
}
|
||||
}, [currentQuizStep, maxCurrentQuizStep]);
|
||||
},
|
||||
[currentQuizStep, maxCurrentQuizStep]
|
||||
);
|
||||
|
||||
return (
|
||||
<Paper sx={{
|
||||
<Paper
|
||||
className="quiz-preview-draghandle"
|
||||
sx={{
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flexGrow: 1,
|
||||
borderRadius: "12px",
|
||||
pointerEvents: "auto",
|
||||
}}>
|
||||
<Box sx={{
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
p: "16px",
|
||||
whiteSpace: "break-spaces",
|
||||
overflowY: "auto",
|
||||
flexGrow: 1,
|
||||
}}>
|
||||
"&::-webkit-scrollbar": { width: 0 },
|
||||
}}
|
||||
>
|
||||
{questionElement}
|
||||
</Box>
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
mt: "auto",
|
||||
p: "16px",
|
||||
display: "flex",
|
||||
borderTop: "1px solid #E3E3E3",
|
||||
alignItems: "center",
|
||||
}}>
|
||||
<Box sx={{
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Typography>
|
||||
{nonDeletedQuizQuestions.length > 0
|
||||
? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length}`
|
||||
: "Нет вопросов"
|
||||
}
|
||||
? `Вопрос ${currentQuizStep + 1} из ${
|
||||
nonDeletedQuizQuestions.length
|
||||
}`
|
||||
: "Нет вопросов"}
|
||||
</Typography>
|
||||
{nonDeletedQuizQuestions.length > 0 &&
|
||||
{nonDeletedQuizQuestions.length > 0 && (
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={currentProgress}
|
||||
@ -106,13 +132,15 @@ export default function QuizPreviewLayout() {
|
||||
},
|
||||
}}
|
||||
/>
|
||||
}
|
||||
)}
|
||||
</Box>
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
ml: 2,
|
||||
display: "flex",
|
||||
gap: 1,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={decrementCurrentQuestionIndex}
|
||||
@ -125,7 +153,9 @@ export default function QuizPreviewLayout() {
|
||||
variant="contained"
|
||||
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
|
||||
disabled={currentQuizStep >= maxCurrentQuizStep}
|
||||
>Далее</Button>
|
||||
>
|
||||
Далее
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user