frontAnswerer/lib/components/QuizAnswerer.tsx
Nastya 2e3358eb2c
All checks were successful
Deploy / CreateImage (push) Successful in 4m41s
Deploy / DeployService (push) Successful in 27s
отладка
2025-07-01 16:49:30 +03:00

188 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuizData } from "@/api/hooks";
import { QuizViewContext, createQuizViewStore } from "@/stores/quizView";
import LoadingSkeleton from "@/ui_kit/LoadingSkeleton";
import { useVkMetricsGoals } from "@/utils/hooks/metrics/useVkMetricsGoals";
import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoals";
import { RootContainerWidthContext } from "@contexts/RootContainerWidthContext";
import type { QuizSettings } from "@model/settingsData";
import { Box, CssBaseline, ScopedCssBaseline, ThemeProvider } from "@mui/material";
import { LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
import { ruRU } from "@mui/x-date-pickers/locales";
import { handleComponentError } from "@utils/handleComponentError";
import lightTheme from "@utils/themes/light";
import moment from "moment";
import { SnackbarProvider } from "notistack";
import { startTransition, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { ApologyPage } from "./ViewPublicationPage/ApologyPage";
import ViewPublicationPage from "./ViewPublicationPage/ViewPublicationPage";
import { HelmetProvider } from "react-helmet-async";
import "moment/dist/locale/ru";
import { useQuizStore, setQuizData, addquizid } from "@/stores/useQuizStore";
import { initDataManager, statusOfQuiz } from "@/utils/hooks/useQuestionFlowControl";
moment.locale("ru");
const localeText = ruRU.components.MuiLocalizationProvider.defaultProps.localeText;
type Props = {
quizSettings?: QuizSettings;
quizId: string;
preview?: boolean;
changeFaviconAndTitle?: boolean;
className?: string;
disableGlobalCss?: boolean;
};
function QuizAnswererInner({
quizSettings,
quizId,
preview = false,
changeFaviconAndTitle = true,
className,
disableGlobalCss = false,
}: Props) {
const [quizViewStore] = useState(createQuizViewStore);
const [rootContainerWidth, setRootContainerWidth] = useState<number>(() => window.innerWidth);
const rootContainerRef = useRef<HTMLDivElement>(null);
const { data, error, isLoading } = useQuizData(quizId, preview);
const vkMetrics = useVkMetricsGoals(quizSettings?.settings.cfg.vkMetricsNumber);
const yandexMetrics = useYandexMetricsGoals(quizSettings?.settings.cfg.yandexMetricsNumber);
const r = useQuizStore();
const { settings, questions } = useQuizStore();
useEffect(() => {
addquizid(quizId);
}, []);
useEffect(() => {
console.log(settings);
console.log(questions);
console.log("r");
console.log(r);
}, [questions, settings]);
useEffect(() => {
setTimeout(() => {
vkMetrics.quizOpened();
yandexMetrics.quizOpened();
}, 4000);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
//Хук на случай если данные переданы нам сразу, а не "нам нужно их запросить"
if (quizSettings !== undefined) {
console.log("QuizAnswerer: calling setQuizData with quizSettings");
setQuizData(quizSettings);
initDataManager({
status: quizSettings.settings.status,
haveRoot: quizSettings.settings.cfg.haveRoot,
});
}
}, [quizSettings]);
useLayoutEffect(() => {
if (rootContainerRef.current) setRootContainerWidth(rootContainerRef.current.clientWidth);
}, []);
useEffect(() => {
const handleWindowResize = () => {
startTransition(() => {
if (rootContainerRef.current) setRootContainerWidth(rootContainerRef.current.clientWidth);
});
};
window.addEventListener("resize", handleWindowResize);
return () => {
window.removeEventListener("resize", handleWindowResize);
};
}, []);
console.log("settings");
console.log(settings);
if (isLoading && !questions.length) return <LoadingSkeleton />;
console.log("error");
console.log(error);
if (error) return <ApologyPage error={error} />;
if (Object.keys(settings).length == 0) return <ApologyPage error={new Error("quiz data is null")} />;
if (questions.length === 0) return <ApologyPage error={new Error("No questions found")} />;
if (questions.length === 1 && settings.cfg.noStartPage && statusOfQuiz != "ai")
return <ApologyPage error={new Error("quiz is empty")} />;
if (!quizId) return <ApologyPage error={new Error("no quiz id")} />;
const quizContainer = (
<Box
ref={rootContainerRef}
className={className}
sx={{
width: "100%",
height: "100%",
position: "relative",
}}
>
<ErrorBoundary
FallbackComponent={ApologyPage}
onError={handleComponentError}
>
<ViewPublicationPage />
</ErrorBoundary>
</Box>
);
return (
<QuizViewContext.Provider value={quizViewStore}>
<RootContainerWidthContext.Provider value={rootContainerWidth}>
{disableGlobalCss ? (
<ScopedCssBaseline
sx={{
height: "100%",
width: "100%",
backgroundColor: "transparent",
}}
>
{quizContainer}
</ScopedCssBaseline>
) : (
<CssBaseline>{quizContainer}</CssBaseline>
)}
</RootContainerWidthContext.Provider>
</QuizViewContext.Provider>
);
}
export default function QuizAnswerer(props: Props) {
return (
<HelmetProvider>
<LocalizationProvider
dateAdapter={AdapterMoment}
adapterLocale="ru"
localeText={localeText}
>
<ThemeProvider theme={lightTheme}>
<SnackbarProvider
preventDuplicate={true}
style={{ backgroundColor: lightTheme.palette.brightPurple.main }}
>
<Box
id="hideoverlay"
sx={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
background: "black",
zIndex: 999,
opacity: 0,
pointerEvents: "auto",
}}
/>
<QuizAnswererInner {...props} />
</SnackbarProvider>
</ThemeProvider>
</LocalizationProvider>
</HelmetProvider>
);
}