make quiz view store component store
move design list to separate file
This commit is contained in:
parent
73e6a95902
commit
979d0e7138
@ -16,6 +16,7 @@ import { ErrorBoundary } from "react-error-boundary";
|
||||
import useSWR from "swr";
|
||||
import { ApologyPage } from "./ViewPublicationPage/ApologyPage";
|
||||
import ViewPublicationPage from "./ViewPublicationPage/ViewPublicationPage";
|
||||
import { QuizViewContext, createQuizViewStore } from "@/stores/quizView";
|
||||
|
||||
|
||||
moment.locale("ru");
|
||||
@ -28,6 +29,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export default function QuizAnswerer({ quizSettings, quizId, preview = false }: Props) {
|
||||
const [quizViewStore] = useState(createQuizViewStore);
|
||||
const [rootContainerWidth, setRootContainerWidth] = useState<number>(() => window.innerWidth);
|
||||
const rootContainerRef = useRef<HTMLDivElement>(null);
|
||||
const { data, error, isLoading } = useSWR(quizSettings ? null : ["quizData", quizId], params => getQuizData(params[1]), {
|
||||
@ -61,6 +63,7 @@ export default function QuizAnswerer({ quizSettings, quizId, preview = false }:
|
||||
if (!quizSettings) throw new Error("Quiz data is null");
|
||||
|
||||
return (
|
||||
<QuizViewContext.Provider value={quizViewStore}>
|
||||
<RootContainerWidthContext.Provider value={rootContainerWidth}>
|
||||
<QuizDataContext.Provider value={{ ...quizSettings, quizId, preview }}>
|
||||
<LocalizationProvider dateAdapter={AdapterMoment} adapterLocale="ru" localeText={localeText}>
|
||||
@ -89,5 +92,6 @@ export default function QuizAnswerer({ quizSettings, quizId, preview = false }:
|
||||
</LocalizationProvider>
|
||||
</QuizDataContext.Provider>
|
||||
</RootContainerWidthContext.Provider>
|
||||
</QuizViewContext.Provider>
|
||||
);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import {quizThemes} from "@utils/themes/Publication/themePublication";
|
||||
import {enqueueSnackbar} from "notistack";
|
||||
import {useRootContainerSize} from "../../contexts/RootContainerWidthContext";
|
||||
import {useQuizData} from "@contexts/QuizDataContext";
|
||||
import {DESIGN_LIST} from "@/components/ViewPublicationPage/Question";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
|
||||
const TextField = MuiTextField as unknown as FC<TextFieldProps>; // temporary fix ts(2590)
|
||||
|
@ -21,19 +21,8 @@ import { NameplateLogoFQDark } from "@icons/NameplateLogoFQDark";
|
||||
import { notReachable } from "@utils/notReachable";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
|
||||
import Desgin1 from "@icons/designs/design1.jpg";
|
||||
import Desgin2 from "@icons/designs/design2.jpg";
|
||||
import Desgin3 from "@icons/designs/design3.jpg";
|
||||
import Desgin4 from "@icons/designs/design4.jpg";
|
||||
import Desgin5 from "@icons/designs/design5.jpg";
|
||||
import Desgin6 from "@icons/designs/design6.jpg";
|
||||
import Desgin7 from "@icons/designs/design7.jpg";
|
||||
import Desgin8 from "@icons/designs/design8.jpg";
|
||||
import Desgin9 from "@icons/designs/design9.jpg";
|
||||
import Desgin10 from "@icons/designs/design10.jpg";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import type { QuizTheme } from "@model/settingsData";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
type Props = {
|
||||
currentQuestion: RealTypedQuizQuestion;
|
||||
@ -42,30 +31,6 @@ type Props = {
|
||||
prevButton: ReactNode;
|
||||
};
|
||||
|
||||
export const DESIGN_LIST: Record<QuizTheme, string> = {
|
||||
Design1: Desgin1,
|
||||
Design2: Desgin2,
|
||||
Design3: Desgin3,
|
||||
Design4: Desgin4,
|
||||
Design5: Desgin5,
|
||||
Design6: Desgin6,
|
||||
Design7: Desgin7,
|
||||
Design8: Desgin8,
|
||||
Design9: Desgin9,
|
||||
Design10: Desgin10,
|
||||
StandardTheme: "",
|
||||
StandardDarkTheme: "",
|
||||
PinkTheme: "",
|
||||
PinkDarkTheme: "",
|
||||
BlackWhiteTheme: "",
|
||||
OliveTheme: "",
|
||||
YellowTheme: "",
|
||||
GoldDarkTheme: "",
|
||||
PurpleTheme: "",
|
||||
BlueTheme: "",
|
||||
BlueDarkTheme: "",
|
||||
};
|
||||
|
||||
export const Question = ({
|
||||
currentQuestion,
|
||||
currentQuestionStepNumber,
|
||||
@ -78,6 +43,7 @@ export const Question = ({
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
height: "100%",
|
||||
backgroundPosition: "center",
|
||||
backgroundSize: "cover",
|
||||
backgroundImage: settings.cfg.design
|
||||
@ -87,6 +53,7 @@ export const Question = ({
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
height: "100%",
|
||||
background: settings.cfg.design
|
||||
? quizThemes[settings.cfg.theme].isLight
|
||||
? "transparent"
|
||||
|
@ -12,8 +12,8 @@ import {useQuizData} from "@contexts/QuizDataContext";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
import { useRootContainerSize } from "../../contexts/RootContainerWidthContext";
|
||||
import type { QuizQuestionResult } from "../../model/questionTypes/result";
|
||||
import {setCurrentQuizStep} from "@stores/quizView";
|
||||
import {DESIGN_LIST} from "@/components/ViewPublicationPage/Question";
|
||||
import { useQuizViewStore } from "@/stores/quizView";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
type ResultFormProps = {
|
||||
resultQuestion: QuizQuestionResult;
|
||||
@ -24,8 +24,9 @@ export const ResultForm = ({resultQuestion}: ResultFormProps) => {
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const isTablet = useRootContainerSize() < 1000;
|
||||
const { settings, show_badge, quizId } = useQuizData();
|
||||
const spec = settings.cfg.spec
|
||||
console.log(quizThemes[settings.cfg.theme].isLight)
|
||||
const setCurrentQuizStep = useQuizViewStore(state => state.setCurrentQuizStep);
|
||||
const spec = settings.cfg.spec;
|
||||
console.log(quizThemes[settings.cfg.theme].isLight);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@ -234,7 +235,7 @@ export const ResultForm = ({resultQuestion}: ResultFormProps) => {
|
||||
p:
|
||||
(
|
||||
settings.cfg.resultInfo.showResultForm === "before" &&
|
||||
!Boolean(settings.cfg.score)
|
||||
!settings.cfg.score
|
||||
) ||
|
||||
(
|
||||
settings.cfg.resultInfo.showResultForm === "after" &&
|
||||
@ -243,7 +244,7 @@ export const ResultForm = ({resultQuestion}: ResultFormProps) => {
|
||||
? "20px" : "0",
|
||||
}}
|
||||
>
|
||||
{settings.cfg.resultInfo.showResultForm === "before" && !Boolean(settings.cfg.score) && (
|
||||
{settings.cfg.resultInfo.showResultForm === "before" && !settings.cfg.score && (
|
||||
<Button
|
||||
onClick={() => setCurrentQuizStep("contactform")}
|
||||
variant="contained"
|
||||
|
@ -5,12 +5,12 @@ import { useQuizData } from "@contexts/QuizDataContext";
|
||||
|
||||
import { notReachable } from "@utils/notReachable";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
import { DESIGN_LIST } from "@/components/ViewPublicationPage/Question";
|
||||
|
||||
import type {
|
||||
QuizStartpageAlignType,
|
||||
QuizStartpageType,
|
||||
} from "@model/settingsData";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
type StartPageDesktopProps = {
|
||||
quizHeaderBlock: JSX.Element;
|
||||
@ -42,11 +42,14 @@ const StandartLayout = ({
|
||||
backgroundImage: settings.cfg.design
|
||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
||||
: null,
|
||||
"&::-webkit-scrollbar": { width: 0 },
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "40%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
@ -86,6 +89,8 @@ const ExpandedLayout = ({
|
||||
: alignType === "left"
|
||||
? "0"
|
||||
: "0 0 0 auto",
|
||||
"&::-webkit-scrollbar": { width: 0 },
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
@ -143,6 +148,7 @@ const CenteredLayout = ({
|
||||
? `url(${DESIGN_LIST[settings.cfg.theme]})`
|
||||
: null,
|
||||
"&::-webkit-scrollbar": { width: 0 },
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
{quizHeaderBlock}
|
||||
|
@ -4,9 +4,9 @@ import { useQuizData } from "@contexts/QuizDataContext";
|
||||
|
||||
import { notReachable } from "@utils/notReachable";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
import { DESIGN_LIST } from "@/components/ViewPublicationPage/Question";
|
||||
|
||||
import type { QuizStartpageType } from "@model/settingsData";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
type StartPageMobileProps = {
|
||||
quizHeaderBlock: JSX.Element;
|
||||
|
@ -13,19 +13,20 @@ import YoutubeEmbedIframe from "../tools/YoutubeEmbedIframe";
|
||||
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
import { useRootContainerSize } from "@contexts/RootContainerWidthContext";
|
||||
import { setCurrentQuizStep } from "@stores/quizView";
|
||||
|
||||
import { useUADevice } from "@utils/hooks/useUADevice";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
|
||||
import { DESIGN_LIST } from "../Question";
|
||||
|
||||
import { NameplateLogo } from "@icons/NameplateLogo";
|
||||
import { useQuizViewStore } from "@/stores/quizView";
|
||||
import { DESIGN_LIST } from "@/utils/designList";
|
||||
|
||||
export const StartPageViewPublication = () => {
|
||||
const theme = useTheme();
|
||||
const { settings, show_badge, quizId } = useQuizData();
|
||||
const { isMobileDevice } = useUADevice();
|
||||
const setCurrentQuizStep = useQuizViewStore(state => state.setCurrentQuizStep);
|
||||
|
||||
const isMobile = useRootContainerSize() < 700;
|
||||
const isTablet = useRootContainerSize() < 800;
|
||||
|
||||
|
@ -16,7 +16,7 @@ import PrevButton from "./tools/PrevButton";
|
||||
|
||||
export default function ViewPublicationPage() {
|
||||
const { settings, recentlyCompleted, quizId, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
let currentQuizStep = useQuizViewStore((state) => state.currentQuizStep);
|
||||
const {
|
||||
currentQuestion,
|
||||
|
@ -2,8 +2,6 @@ import moment from "moment";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { Box, Typography, useTheme } from "@mui/material";
|
||||
|
||||
import { useQuizViewStore, updateAnswer } from "@stores/quizView";
|
||||
|
||||
import type { QuizQuestionDate } from "../../../model/questionTypes/date";
|
||||
import CalendarIcon from "@icons/CalendarIcon";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
@ -12,6 +10,7 @@ import { sendAnswer } from "@api/quizRelase";
|
||||
import { quizThemes } from "@utils/themes/Publication/themePublication";
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
import { useState } from "react";
|
||||
import { useQuizViewStore } from "@/stores/quizView";
|
||||
|
||||
type DateProps = {
|
||||
currentQuestion: QuizQuestionDate;
|
||||
@ -20,7 +19,8 @@ type DateProps = {
|
||||
export const Date = ({ currentQuestion }: DateProps) => {
|
||||
const theme = useTheme();
|
||||
const { settings, quizId, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const answer = answers.find(
|
||||
({ questionId }) => questionId === currentQuestion.id
|
||||
)?.answer as string;
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
|
||||
import { deleteAnswer, updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import RadioCheck from "@ui_kit/RadioCheck";
|
||||
import RadioIcon from "@ui_kit/RadioIcon";
|
||||
@ -31,9 +31,10 @@ type EmojiProps = {
|
||||
export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
||||
const theme = useTheme();
|
||||
const { quizId, settings, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const { answer } =
|
||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
Typography,
|
||||
useTheme
|
||||
} from "@mui/material";
|
||||
import { updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import CloseBold from "@icons/CloseBold";
|
||||
import UploadIcon from "@icons/UploadIcon";
|
||||
@ -29,7 +29,8 @@ type FileProps = {
|
||||
|
||||
export const File = ({ currentQuestion }: FileProps) => {
|
||||
const theme = useTheme();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const { quizId, preview } = useQuizData();
|
||||
const [modalWarningType, setModalWarningType] = useState<ModalWarningType>(null);
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
@ -43,8 +44,8 @@ export const File = ({ currentQuestion }: FileProps) => {
|
||||
const uploadFile = async (file: File | undefined) => {
|
||||
if (isSending) return;
|
||||
if (!file) return;
|
||||
console.log(file.size)
|
||||
console.log(MAX_FILE_SIZE)
|
||||
console.log(file.size);
|
||||
console.log(MAX_FILE_SIZE);
|
||||
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
||||
|
||||
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP[currentQuestion.content.type].some(
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
|
||||
import { deleteAnswer, updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
import RadioCheck from "@ui_kit/RadioCheck";
|
||||
import RadioIcon from "@ui_kit/RadioIcon";
|
||||
|
||||
@ -25,7 +25,9 @@ type ImagesProps = {
|
||||
|
||||
export const Images = ({ currentQuestion }: ImagesProps) => {
|
||||
const { quizId, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const theme = useTheme();
|
||||
const answer = answers.find(
|
||||
({ questionId }) => questionId === currentQuestion.id
|
||||
|
@ -5,7 +5,7 @@ import { useDebouncedCallback } from "use-debounce";
|
||||
import { CustomSlider } from "@ui_kit/CustomSlider";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
|
||||
import { updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import { sendAnswer } from "@api/quizRelase";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
@ -31,7 +31,9 @@ export const Number = ({ currentQuestion }: NumberProps) => {
|
||||
const [reversedMaxRange, setReversedMaxRange] =
|
||||
useState<string>("100000000000");
|
||||
const theme = useTheme();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
useTheme
|
||||
} from "@mui/material";
|
||||
|
||||
import { updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import FlagIcon from "@icons/questionsPage/FlagIcon";
|
||||
import StarIconMini from "@icons/questionsPage/StarIconMini";
|
||||
@ -59,7 +59,8 @@ const buttonRatingForm = [
|
||||
|
||||
export const Rating = ({ currentQuestion }: RatingProps) => {
|
||||
const { quizId, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const theme = useTheme();
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const isTablet = useRootContainerSize() < 750;
|
||||
|
@ -2,7 +2,7 @@ import { Box, Typography, useTheme } from "@mui/material";
|
||||
|
||||
import { Select as SelectComponent } from "../tools//Select";
|
||||
|
||||
import { deleteAnswer, updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import { sendAnswer } from "@api/quizRelase";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
@ -19,7 +19,9 @@ export const Select = ({ currentQuestion }: SelectProps) => {
|
||||
const theme = useTheme();
|
||||
const { quizId, settings, preview } = useQuizData();
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
const { answer } =
|
||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
|
||||
import { updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import { sendAnswer } from "@api/quizRelase";
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
@ -54,12 +54,10 @@ const Orientation = [
|
||||
];
|
||||
|
||||
export const Text = ({ currentQuestion, stepNumber }: TextProps) => {
|
||||
const theme = useTheme();
|
||||
const { settings, preview } = useQuizData();
|
||||
const spec = settings.cfg.spec;
|
||||
const { quizId } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const { answer } =
|
||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
@ -125,6 +123,7 @@ const TextNormal = ({ currentQuestion, answer, inputHC }: Props) => {
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const theme = useTheme();
|
||||
const { settings } = useQuizData();
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
@ -198,6 +197,7 @@ const TextSpecial = ({
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const isHorizontal = Orientation[Number(stepNumber) - 1].horizontal;
|
||||
const { settings } = useQuizData();
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
@ -13,9 +13,6 @@ import {
|
||||
import { FC, useEffect, useState } from "react";
|
||||
|
||||
import {
|
||||
deleteAnswer,
|
||||
updateAnswer,
|
||||
updateOwnVariant,
|
||||
useQuizViewStore,
|
||||
} from "@stores/quizView";
|
||||
|
||||
@ -42,7 +39,10 @@ type VariantProps = {
|
||||
export const Variant = ({ currentQuestion }: VariantProps) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const { answers, ownVariants } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const ownVariants = useQuizViewStore(state => state.ownVariants);
|
||||
const updateOwnVariant = useQuizViewStore(state => state.updateOwnVariant);
|
||||
|
||||
const { answer } =
|
||||
answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
|
||||
const ownVariant = ownVariants.find(
|
||||
@ -162,6 +162,8 @@ const VariantItem = ({
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { settings, quizId, preview } = useQuizData();
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
|
||||
return (
|
||||
<FormControlLabel
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { deleteAnswer, updateAnswer, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
|
||||
import RadioCheck from "@ui_kit/RadioCheck";
|
||||
import RadioIcon from "@ui_kit/RadioIcon";
|
||||
@ -26,7 +26,10 @@ type VarimgProps = {
|
||||
|
||||
export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
||||
const { settings, quizId, preview } = useQuizData();
|
||||
const { answers } = useQuizViewStore();
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const deleteAnswer = useQuizViewStore(state => state.deleteAnswer);
|
||||
const updateAnswer = useQuizViewStore(state => state.updateAnswer);
|
||||
|
||||
const theme = useTheme();
|
||||
const isMobile = useRootContainerSize() < 650;
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { QuestionVariant } from "@model/questionTypes/shared";
|
||||
import { produce } from "immer";
|
||||
import { nanoid } from "nanoid";
|
||||
import { create } from "zustand";
|
||||
import { devtools } from "zustand/middleware";
|
||||
import type { Moment } from "moment";
|
||||
import { QuizStep } from "@model/settingsData";
|
||||
import type { Moment } from "moment";
|
||||
import { nanoid } from "nanoid";
|
||||
import { createContext, useContext } from "react";
|
||||
import { createStore, useStore } from "zustand";
|
||||
import { immer } from "zustand/middleware/immer";
|
||||
|
||||
type QuestionAnswer = {
|
||||
questionId: string;
|
||||
@ -24,43 +24,33 @@ interface QuizViewStore {
|
||||
currentQuizStep: QuizStep;
|
||||
}
|
||||
|
||||
export const useQuizViewStore = create<QuizViewStore>()(
|
||||
devtools(
|
||||
interface QuizViewActions {
|
||||
updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
|
||||
deleteAnswer: (questionId: string) => void;
|
||||
updateOwnVariant: (id: string, answer: string) => void;
|
||||
deleteOwnVariant: (id: string) => void;
|
||||
setCurrentQuizStep: (step: QuizStep) => void;
|
||||
}
|
||||
|
||||
export const QuizViewContext = createContext<ReturnType<typeof createQuizViewStore> | null>(null);
|
||||
|
||||
export function useQuizViewStore<U>(selector: (state: QuizViewStore & QuizViewActions) => U): U {
|
||||
const context = useContext(QuizViewContext);
|
||||
if (!context) throw new Error("QuizViewStore context is null");
|
||||
|
||||
return useStore(context, selector);
|
||||
}
|
||||
|
||||
export const createQuizViewStore = () => createStore<QuizViewStore & QuizViewActions>()(
|
||||
immer(
|
||||
(set, get) => ({
|
||||
answers: [],
|
||||
ownVariants: [],
|
||||
points: {},
|
||||
pointsSum: 0,
|
||||
currentQuizStep: "startpage",
|
||||
}),
|
||||
{
|
||||
name: "quizView",
|
||||
enabled: import.meta.env.DEV,
|
||||
trace: import.meta.env.DEV,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
function setProducedState<A extends string | { type: string; }>(
|
||||
recipe: (state: QuizViewStore) => void,
|
||||
action?: A,
|
||||
) {
|
||||
useQuizViewStore.setState(state => produce(state, recipe), false, action);
|
||||
}
|
||||
|
||||
const calcPoints = () => {
|
||||
const storePoints = useQuizViewStore.getState().points;
|
||||
let sum = Object.values(storePoints).reduce((accumulator, currentValue) => accumulator + currentValue)
|
||||
console.log("сумма ", sum)
|
||||
useQuizViewStore.setState({ pointsSum: sum })
|
||||
}
|
||||
|
||||
export const updateAnswer = (
|
||||
questionId: string,
|
||||
answer: string | string[] | Moment,
|
||||
points: number
|
||||
) => {
|
||||
setProducedState(state => {
|
||||
updateAnswer(questionId, answer, points) {
|
||||
set(state => {
|
||||
const index = state.answers.findIndex(answer => questionId === answer.questionId);
|
||||
|
||||
if (index < 0) {
|
||||
@ -68,24 +58,19 @@ export const updateAnswer = (
|
||||
} else {
|
||||
state.answers[index] = { questionId, answer };
|
||||
}
|
||||
}, {
|
||||
type: "updateAnswer",
|
||||
questionId,
|
||||
answer
|
||||
})
|
||||
const storePoints = useQuizViewStore.getState().points;
|
||||
useQuizViewStore.setState({ points: { ...storePoints, ...{ [questionId]: points } } })
|
||||
calcPoints()
|
||||
};
|
||||
|
||||
export const deleteAnswer = (questionId: string) => useQuizViewStore.setState(state => ({
|
||||
answers: state.answers.filter(answer => questionId !== answer.questionId)
|
||||
}), false, {
|
||||
type: "deleteAnswer",
|
||||
questionId
|
||||
state.points = { ...state.points, ...{ [questionId]: points } };
|
||||
|
||||
state.pointsSum = Object.values(state.points).reduce((sum, value) => sum + value);
|
||||
});
|
||||
|
||||
export const updateOwnVariant = (id: string, answer: string) => setProducedState(state => {
|
||||
},
|
||||
deleteAnswer(questionId) {
|
||||
set(state => {
|
||||
state.answers = state.answers.filter(answer => questionId !== answer.questionId);
|
||||
});
|
||||
},
|
||||
updateOwnVariant(id, answer) {
|
||||
set(state => {
|
||||
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
||||
|
||||
if (index < 0) {
|
||||
@ -102,22 +87,16 @@ export const updateOwnVariant = (id: string, answer: string) => setProducedState
|
||||
} else {
|
||||
state.ownVariants[index].variant.answer = answer;
|
||||
}
|
||||
}, {
|
||||
type: "updateOwnVariant",
|
||||
id,
|
||||
answer
|
||||
});
|
||||
|
||||
export const deleteOwnVariant = (id: string) => useQuizViewStore.setState(state => ({
|
||||
ownVariants: state.ownVariants.filter((variant) => variant.id !== id)
|
||||
}), false, {
|
||||
type: "deleteOwnVariant",
|
||||
id
|
||||
});
|
||||
|
||||
export const setCurrentQuizStep = (currentQuizStep: QuizStep) => useQuizViewStore.setState({
|
||||
currentQuizStep
|
||||
}, false, {
|
||||
type: "setCurrentQuizStep",
|
||||
currentQuizStep
|
||||
},
|
||||
deleteOwnVariant(id) {
|
||||
set(state => {
|
||||
state.ownVariants = state.ownVariants.filter((variant) => variant.id !== id);
|
||||
});
|
||||
},
|
||||
setCurrentQuizStep(step) {
|
||||
set({ currentQuizStep: step });
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
|
36
lib/utils/designList.ts
Normal file
36
lib/utils/designList.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import type { QuizTheme } from "@model/settingsData";
|
||||
import Desgin1 from "@icons/designs/design1.jpg";
|
||||
import Desgin2 from "@icons/designs/design2.jpg";
|
||||
import Desgin3 from "@icons/designs/design3.jpg";
|
||||
import Desgin4 from "@icons/designs/design4.jpg";
|
||||
import Desgin5 from "@icons/designs/design5.jpg";
|
||||
import Desgin6 from "@icons/designs/design6.jpg";
|
||||
import Desgin7 from "@icons/designs/design7.jpg";
|
||||
import Desgin8 from "@icons/designs/design8.jpg";
|
||||
import Desgin9 from "@icons/designs/design9.jpg";
|
||||
import Desgin10 from "@icons/designs/design10.jpg";
|
||||
|
||||
|
||||
export const DESIGN_LIST: Record<QuizTheme, string> = {
|
||||
Design1: Desgin1,
|
||||
Design2: Desgin2,
|
||||
Design3: Desgin3,
|
||||
Design4: Desgin4,
|
||||
Design5: Desgin5,
|
||||
Design6: Desgin6,
|
||||
Design7: Desgin7,
|
||||
Design8: Desgin8,
|
||||
Design9: Desgin9,
|
||||
Design10: Desgin10,
|
||||
StandardTheme: "",
|
||||
StandardDarkTheme: "",
|
||||
PinkTheme: "",
|
||||
PinkDarkTheme: "",
|
||||
BlackWhiteTheme: "",
|
||||
OliveTheme: "",
|
||||
YellowTheme: "",
|
||||
GoldDarkTheme: "",
|
||||
PurpleTheme: "",
|
||||
BlueTheme: "",
|
||||
BlueDarkTheme: "",
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||
import { setCurrentQuizStep, useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
import { useCallback, useDebugValue, useMemo, useState } from "react";
|
||||
import { isResultQuestionEmpty } from "../../components/ViewPublicationPage/tools/checkEmptyData";
|
||||
import moment from "moment";
|
||||
@ -10,8 +10,9 @@ import { enqueueSnackbar } from "notistack";
|
||||
export function useQuestionFlowControl() {
|
||||
const { settings, questions } = useQuizData();
|
||||
const [currentQuestion, setCurrentQuestion] = useState<AnyTypedQuizQuestion>(getFirstQuestion);
|
||||
const { answers, pointsSum } = useQuizViewStore(state => state);
|
||||
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const pointsSum = useQuizViewStore(state => state.pointsSum);
|
||||
const setCurrentQuizStep = useQuizViewStore(state => state.setCurrentQuizStep);
|
||||
|
||||
const linearQuestionIndex = questions.every(({ content }) => content.rule.parentId !== "root") // null when branching enabled
|
||||
? questions.indexOf(currentQuestion)
|
||||
@ -72,7 +73,7 @@ export function useQuestionFlowControl() {
|
||||
})?.id;
|
||||
};
|
||||
const calculateNextQuestionId = useMemo(() => {
|
||||
if (Boolean(settings.cfg.score)) {
|
||||
if (settings.cfg.score) {
|
||||
return nextQuestionIdPointsLogic();
|
||||
}
|
||||
return nextQuestionIdMainLogic();
|
||||
@ -100,7 +101,7 @@ export function useQuestionFlowControl() {
|
||||
let next;
|
||||
console.log(11111111111);
|
||||
//Искать можно двумя логиками. Основной и балловой
|
||||
if (Boolean(settings.cfg.score)) {
|
||||
if (settings.cfg.score) {
|
||||
//Балловая
|
||||
console.log(222222222);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@frontend/squzanswerer",
|
||||
"version": "1.0.16",
|
||||
"version": "1.0.17",
|
||||
"type": "module",
|
||||
"main": "./dist-package/index.js",
|
||||
"module": "./dist-package/index.js",
|
||||
|
Loading…
Reference in New Issue
Block a user