diff --git a/package.json b/package.json index 253beb58..276fca67 100755 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", "@frontend/kitui": "^1.0.74", - "@frontend/squzanswerer": "^1.0.22", + "@frontend/squzanswerer": "^1.0.36", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", "@mui/x-charts": "^6.19.5", diff --git a/src/model/quizSettings.ts b/src/model/quizSettings.ts index f33d87d9..6f1cdced 100644 --- a/src/model/quizSettings.ts +++ b/src/model/quizSettings.ts @@ -70,6 +70,7 @@ export type QuizTheme = | "Design10"; export interface QuizConfig { + spec: undefined | true; type: QuizType; noStartPage: boolean; startpageType: QuizStartpageType; @@ -140,6 +141,7 @@ export type FieldSettingsDrawerState = { }; export const defaultQuizConfig: QuizConfig = { + spec: undefined, type: null, noStartPage: false, startpageType: null, diff --git a/src/pages/ViewPublicationPage.tsx b/src/pages/ViewPublicationPage.tsx index c4432546..67a1d0e1 100644 --- a/src/pages/ViewPublicationPage.tsx +++ b/src/pages/ViewPublicationPage.tsx @@ -78,6 +78,7 @@ export default function ViewPublicationPage() { rep: quiz.repeatable, cfg: quiz.config, }, + show_badge: true, }} quizId={quizId} preview diff --git a/src/stores/quizPreview.ts b/src/stores/quizPreview.ts index 69f6f0a8..17f0150b 100644 --- a/src/stores/quizPreview.ts +++ b/src/stores/quizPreview.ts @@ -3,14 +3,12 @@ import { devtools } from "zustand/middleware"; interface QuizPreviewStore { isPreviewShown: boolean; - currentQuestionIndex: number; } export const useQuizPreviewStore = create()( devtools( (set, get) => ({ isPreviewShown: false, - currentQuestionIndex: 0, }), { name: "quizPreview", @@ -29,18 +27,3 @@ export const toggleQuizPreview = () => useQuizPreviewStore.setState((state) => ({ isPreviewShown: !state.isPreviewShown, })); - -export const setCurrentQuestionIndex = (step: number) => - useQuizPreviewStore.setState((state) => ({ - currentQuestionIndex: (state.currentQuestionIndex = step), - })); - -export const incrementCurrentQuestionIndex = (maxStep: number) => - useQuizPreviewStore.setState((state) => ({ - currentQuestionIndex: Math.min(state.currentQuestionIndex + 1, maxStep), - })); - -export const decrementCurrentQuestionIndex = () => - useQuizPreviewStore.setState((state) => ({ - currentQuestionIndex: Math.max(state.currentQuestionIndex - 1, 0), - })); diff --git a/src/ui_kit/QuizPreview/QuizPreview.tsx b/src/ui_kit/QuizPreview/QuizPreview.tsx index 67fc24c8..232a543a 100644 --- a/src/ui_kit/QuizPreview/QuizPreview.tsx +++ b/src/ui_kit/QuizPreview/QuizPreview.tsx @@ -1,16 +1,13 @@ -import { Box, IconButton, ThemeProvider } from "@mui/material"; -import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview"; +import { QuizAnswerer } from "@frontend/squzanswerer"; +import ResizeIcon from "@icons/ResizeIcon"; +import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; +import { Box, ThemeProvider } from "@mui/material"; +import { useQuestionsStore } from "@root/questions/store"; +import { useQuizPreviewStore } from "@root/quizPreview"; +import { useCurrentQuiz } from "@root/quizes/hooks"; +import { themesPublication } from "@utils/themes/Publication/themePublication"; import { useLayoutEffect, useRef } from "react"; import { Rnd } from "react-rnd"; -import { useWindowSize } from "../../utils/hooks/useWindowSize"; -import QuizPreviewLayout from "./QuizPreviewLayout"; -import ResizeIcon from "@icons/ResizeIcon"; -import { themesPublication } from "@utils/themes/Publication/themePublication"; -import { useCurrentQuiz } from "@root/quizes/hooks"; - -const DRAG_PARENT_MARGIN = 0; -const NAVBAR_HEIGHT = 0; -const DRAG_PARENT_BOTTOM_MARGIN = 0; interface RndPositionAndSize { x: number; @@ -23,6 +20,9 @@ export default function QuizPreview() { const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown); const rndParentRef = useRef(null); const quiz = useCurrentQuiz(); + const questions = useQuestionsStore((state) => state.questions).filter( + (q): q is AnyTypedQuizQuestion => q.type !== null, + ); const rndRef = useRef(null); const rndPositionAndSizeRef = useRef({ x: 0, @@ -32,6 +32,8 @@ export default function QuizPreview() { }); const isFirstShowRef = useRef(true); + if (!quiz) return null; + useLayoutEffect( function stickPreviewToBottomRight() { const rnd = rndRef.current; @@ -68,8 +70,8 @@ export default function QuizPreview() { data-cy="quiz-preview-container" sx={{ position: "fixed", - top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN, - left: DRAG_PARENT_MARGIN, + top: 0, + left: 0, bottom: 70, right: 70, // backgroundColor: "rgba(0, 100, 0, 0.2)", @@ -119,10 +121,31 @@ export default function QuizPreview() { overflow: "hidden", pointerEvents: "auto", boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)", + backgroundColor: "white", }} cancel=".cancel" > - + )} diff --git a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx b/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx deleted file mode 100644 index f2df0e5d..00000000 --- a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx +++ /dev/null @@ -1,298 +0,0 @@ -import { - Box, - Button, - LinearProgress, - Paper, - Typography, - FormControl, - Select as MuiSelect, - MenuItem, - useTheme, -} from "@mui/material"; -import { useQuestionsStore } from "@root/questions/store"; -import { - decrementCurrentQuestionIndex, - incrementCurrentQuestionIndex, - useQuizPreviewStore, - setCurrentQuestionIndex, -} from "@root/quizPreview"; -import { - AnyTypedQuizQuestion, - UntypedQuizQuestion, -} from "model/questionTypes/shared"; -import { useEffect, useRef, useState } from "react"; -import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft"; -import Date from "./QuizPreviewQuestionTypes/Date"; -import Emoji from "./QuizPreviewQuestionTypes/Emoji"; -import File from "./QuizPreviewQuestionTypes/File"; -import Images from "./QuizPreviewQuestionTypes/Images"; -import Number from "./QuizPreviewQuestionTypes/Number"; -import Page from "./QuizPreviewQuestionTypes/Page"; -import Rating from "./QuizPreviewQuestionTypes/Rating"; -import Select, { ArrowDownTheme } from "./QuizPreviewQuestionTypes/Select"; -import Text from "./QuizPreviewQuestionTypes/Text"; -import Variant from "./QuizPreviewQuestionTypes/Variant"; -import Varimg from "./QuizPreviewQuestionTypes/Varimg"; -import { notReachable } from "../../utils/notReachable"; -import ArrowDownIcon from "@icons/ArrowDownIcon"; - -export default function QuizPreviewLayout() { - const theme = useTheme(); - const questions = useQuestionsStore((state) => state.questions); - const currentQuizStep = useQuizPreviewStore( - (state) => state.currentQuestionIndex, - ); - const [widthPreview, setWidthPreview] = useState(null); - const nonDeletedQuizQuestions = questions.filter( - (question) => !question.deleted && question.type !== "result", - ); - const maxCurrentQuizStep = - nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0; - const currentProgress = Math.floor( - (currentQuizStep / maxCurrentQuizStep) * 100, - ); - const PreviewWin = useRef(0); - const currentQuestion = nonDeletedQuizQuestions[currentQuizStep]; - - useEffect( - function resetCurrentQuizStep() { - if (currentQuizStep > maxCurrentQuizStep) { - decrementCurrentQuestionIndex(); - } - }, - [currentQuizStep, maxCurrentQuizStep], - ); - - const observer = useRef( - new ResizeObserver((entries) => { - const { width } = entries[0].contentRect; - setWidthPreview(width); - }), - ); - - useEffect(() => { - observer.current.observe(PreviewWin.current); - }, [PreviewWin, observer]); - - return ( - - - - - - - - - setCurrentQuestionIndex(window.Number(target.value)) - } - sx={{ - height: "48px", - borderRadius: "8px", - "& .MuiOutlinedInput-notchedOutline": { - border: `1px solid ${theme.palette.primary.main} !important`, - }, - "& .MuiSelect-icon": { - color: theme.palette.primary.main, - }, - }} - MenuProps={{ - PaperProps: { - sx: { - mt: "8px", - p: "4px", - borderRadius: "8px", - border: "1px solid #EEE4FC", - boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)", - backgroundColor: theme.palette.background.default, - }, - }, - MenuListProps: { - sx: { - py: 0, - display: "flex", - flexDirection: "column", - gap: "8px", - maxWidth: "330px", - "& .Mui-selected": { - backgroundColor: theme.palette.background.default, - color: theme.palette.primary.main, - }, - }, - }, - }} - inputProps={{ - sx: { - color: theme.palette.primary.main, - display: "block", - px: "9px", - gap: "20px", - width: "87%", - overflow: "hidden", - textOverflow: "ellipsis", - }, - }} - IconComponent={ArrowDownTheme} - > - {Object.values(questions.filter((q) => q.type !== "result")).map( - ({ id, title }, index) => ( - - {`${index + 1}. ${title}`} - - ), - )} - - - - - - - {nonDeletedQuizQuestions.length > 0 - ? `Вопрос ${currentQuizStep + 1} из ${ - nonDeletedQuizQuestions.length - }` - : "Нет вопросов"} - - {nonDeletedQuizQuestions.length > 0 && ( - - )} - - - - - - - - - ); -} - -function QuestionPreviewComponent({ - question, - widthPreview, -}: { - question: AnyTypedQuizQuestion | UntypedQuizQuestion | undefined; - widthPreview?: number; -}) { - if (!question || question.type === null) return null; - - switch (question.type) { - case "variant": - return ; - case "images": - return ; - case "varimg": - return ; - case "emoji": - return ; - case "text": - return ; - case "select": - return