Merge branch 'staging'
This commit is contained in:
commit
7367c35be1
@ -11,7 +11,6 @@ const getLanguageFromUrlFallback = (): string => {
|
||||
};
|
||||
|
||||
export const NameplateLogo: FC<SVGProps<SVGSVGElement>> = (props) => {
|
||||
console.log("props", props);
|
||||
let lang = "ru"; // fallback
|
||||
|
||||
try {
|
||||
|
||||
@ -51,12 +51,12 @@ function QuizAnswererInner({
|
||||
const yandexMetrics = useYandexMetricsGoals(quizSettings?.settings.cfg.yandexMetricsNumber);
|
||||
const r = useQuizStore();
|
||||
const { settings, questions } = useQuizStore();
|
||||
console.log("settings", settings);
|
||||
console.log("questions", questions);
|
||||
|
||||
useEffect(() => {
|
||||
addquizid(quizId);
|
||||
}, []);
|
||||
// Устанавливаем changeFaviconAndTitle в store
|
||||
useQuizStore.setState({ changeFaviconAndTitle });
|
||||
}, [changeFaviconAndTitle]);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
|
||||
@ -25,7 +25,7 @@ export const ApologyPage = ({ error }: Props) => {
|
||||
color: "text.primary",
|
||||
}}
|
||||
>
|
||||
{/* {t(message.toLowerCase())} */}
|
||||
{t(message.toLowerCase())}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@ -29,8 +29,9 @@ type InputsProps = {
|
||||
};
|
||||
};
|
||||
|
||||
const iscrutch = "/cc006b40-ccbd-4600-a1d3-f902f85aa0a0";
|
||||
const pathOnly = window.location.pathname;
|
||||
const iscrutch =
|
||||
pathOnly === "/cc006b40-ccbd-4600-a1d3-f902f85aa0a0" || pathOnly === "/28525cd7-9ddf-4c4a-a55b-e3d2f7d47583";
|
||||
|
||||
export const Inputs = ({
|
||||
name,
|
||||
@ -58,11 +59,7 @@ export const Inputs = ({
|
||||
<CustomInput
|
||||
onChange={({ target }) => setName(target.value)}
|
||||
id={name}
|
||||
title={
|
||||
pathOnly === iscrutch
|
||||
? "Введите имя и фамилию"
|
||||
: FC["name"].innerText || `${t("Enter")} ${t("Name").toLowerCase()}`
|
||||
}
|
||||
title={iscrutch ? "Введите имя и фамилию" : FC["name"].innerText || `${t("Enter")} ${t("Name").toLowerCase()}`}
|
||||
desc={FC["name"].text || t("Name")}
|
||||
Icon={NameIcon}
|
||||
/>
|
||||
|
||||
@ -76,7 +76,7 @@ const StandartLayout = ({ alignType, quizHeaderBlock, quizMainBlock, backgroundB
|
||||
{quizHeaderBlock}
|
||||
{quizMainBlock}
|
||||
</Box>
|
||||
{settings.cfg.startpage.background.desktop && (
|
||||
{(settings.cfg.startpage.background.desktop || settings.cfg.startpage.background.type === "video") && (
|
||||
<Box sx={{ width: "60%", overflow: "hidden" }}>
|
||||
<Box
|
||||
sx={{
|
||||
@ -195,7 +195,8 @@ const CenteredLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock }: Lay
|
||||
}}
|
||||
>
|
||||
{quizHeaderBlock}
|
||||
{backgroundBlock && settings.cfg.startpage.background.desktop && (
|
||||
{backgroundBlock &&
|
||||
(settings.cfg.startpage.background.desktop || settings.cfg.startpage.background.type === "video") && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
|
||||
@ -60,7 +60,7 @@ const StandartMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock
|
||||
}}
|
||||
>
|
||||
<Box sx={{ marginBottom: "13px" }}>{quizHeaderBlock}</Box>
|
||||
{settings.cfg.startpage.background.desktop && (
|
||||
{(settings.cfg.startpage.background.desktop || settings.cfg.startpage.background.type === "video") && (
|
||||
<Box sx={{ width: "100%", overflow: "hidden" }}>
|
||||
<Box
|
||||
sx={{
|
||||
@ -200,7 +200,7 @@ const CenteredMobileLayout = ({ quizHeaderBlock, quizMainBlock, backgroundBlock
|
||||
}}
|
||||
>
|
||||
{quizHeaderBlock}
|
||||
{settings.cfg.startpage.background.desktop && (
|
||||
{(settings.cfg.startpage.background.desktop || settings.cfg.startpage.background.type === "video") && (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
|
||||
@ -39,6 +39,15 @@ export const StartPageViewPublication = () => {
|
||||
yandexMetrics.phoneNumberOpened();
|
||||
};
|
||||
|
||||
console.log("------------------------------------------------");
|
||||
console.log("Background type:", settings.cfg.startpage.background.type);
|
||||
console.log("Is image type:", settings.cfg.startpage.background.type === "image");
|
||||
console.log("Is video type:", settings.cfg.startpage.background.type === "video");
|
||||
console.log("Video URL:", settings.cfg.startpage.background.video);
|
||||
console.log("Desktop background:", settings.cfg.startpage.background.desktop);
|
||||
console.log("Startpage type:", settings.cfg.startpageType);
|
||||
console.log("------------------------------------------------");
|
||||
|
||||
const background =
|
||||
settings.cfg.startpage.background.type === "image" ? (
|
||||
<img
|
||||
@ -56,6 +65,9 @@ export const StartPageViewPublication = () => {
|
||||
/>
|
||||
) : settings.cfg.startpage.background.type === "video" ? (
|
||||
settings.cfg.startpage.background.video ? (
|
||||
(() => {
|
||||
console.log("Rendering QuizVideo with URL:", settings.cfg.startpage.background.video);
|
||||
return (
|
||||
<QuizVideo
|
||||
videoUrl={settings.cfg.startpage.background.video}
|
||||
containerSX={{
|
||||
@ -75,6 +87,8 @@ export const StartPageViewPublication = () => {
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})()
|
||||
) : null
|
||||
) : null;
|
||||
|
||||
|
||||
@ -57,12 +57,20 @@ export default function ViewPublicationPage() {
|
||||
|
||||
useEffect(
|
||||
function setFaviconAndTitle() {
|
||||
if (!changeFaviconAndTitle) return;
|
||||
if (!changeFaviconAndTitle) {
|
||||
return;
|
||||
}
|
||||
|
||||
const link = document.querySelector('link[rel="icon"]');
|
||||
|
||||
// Для localhost:5173 устанавливаем фавиконку из настроек квиза
|
||||
if (window.location.hostname === "localhost" && window.location.port === "5173") {
|
||||
if (link && settings.cfg.startpage.favIcon) {
|
||||
link.setAttribute("href", settings.cfg.startpage.favIcon);
|
||||
}
|
||||
} else if (link && settings.cfg.startpage.favIcon) {
|
||||
link.setAttribute("href", settings.cfg.startpage.favIcon);
|
||||
}
|
||||
|
||||
document.title = settings.name;
|
||||
},
|
||||
@ -74,7 +82,6 @@ export default function ViewPublicationPage() {
|
||||
// Обработка noStartPage - обновляем состояние в store
|
||||
useEffect(() => {
|
||||
if (currentQuizStep === "startpage" && settings.cfg.noStartPage) {
|
||||
console.log("🔄 noStartPage: Setting currentQuizStep to 'question'");
|
||||
setCurrentQuizStep("question");
|
||||
}
|
||||
}, [currentQuizStep, settings.cfg.noStartPage, setCurrentQuizStep]);
|
||||
|
||||
@ -45,7 +45,8 @@ const OwnInput = ({ questionId, variant, largeCheck, ownPlaceholder }: OwnInputP
|
||||
const ownVariants = useQuizViewStore((state) => state.ownVariants);
|
||||
const { updateOwnVariant } = useQuizViewStore((state) => state);
|
||||
|
||||
const ownAnswer = ownVariants[ownVariants.findIndex((v: OwnVariant) => v.id === variant.id)]?.variant.answer || "";
|
||||
const ownVariantIndex = ownVariants.findIndex((v: OwnVariant) => v.id === variant.id);
|
||||
const ownAnswer = ownVariantIndex >= 0 ? ownVariants[ownVariantIndex]?.variant.answer || "" : "";
|
||||
|
||||
return largeCheck ? (
|
||||
<Box sx={{ overflow: "auto" }}>
|
||||
|
||||
@ -28,18 +28,12 @@ interface OwnInputProps {
|
||||
}
|
||||
const OwnInput = ({ questionId, variant, largeCheck, ownPlaceholder }: OwnInputProps) => {
|
||||
const theme = useTheme();
|
||||
console.log("здравствуй, я овн вопрос. Вот инфо обо мне: ");
|
||||
console.log("questionId ", questionId);
|
||||
console.log("variant", variant);
|
||||
console.log("largeCheck", largeCheck);
|
||||
console.log("ownPlaceholder", ownPlaceholder);
|
||||
console.log("--------------------------");
|
||||
|
||||
const ownVariants = useQuizViewStore((state) => state.ownVariants);
|
||||
const { updateOwnVariant } = useQuizViewStore((state) => state);
|
||||
|
||||
const ownAnswer = ownVariants[ownVariants.findIndex((v) => v.id === variant.id)]?.variant.answer || "";
|
||||
console.log("Вот каков стор в данный момент времени:", ownVariants);
|
||||
const ownVariantIndex = ownVariants.findIndex((v) => v.id === variant.id);
|
||||
const ownAnswer = ownVariantIndex >= 0 ? ownVariants[ownVariantIndex]?.variant.answer || "" : "";
|
||||
|
||||
return largeCheck ? (
|
||||
<TextareaAutosize
|
||||
@ -66,7 +60,6 @@ const OwnInput = ({ questionId, variant, largeCheck, ownPlaceholder }: OwnInputP
|
||||
value={ownAnswer}
|
||||
onClick={(e: React.MouseEvent<HTMLTextAreaElement>) => e.stopPropagation()}
|
||||
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
console.log("клик", e.target.value);
|
||||
updateOwnVariant(variant.id, e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -31,7 +31,8 @@ const OwnInput = ({ questionId, variant, largeCheck, ownPlaceholder }: OwnInputP
|
||||
const ownVariants = useQuizViewStore((state) => state.ownVariants);
|
||||
const { updateOwnVariant } = useQuizViewStore((state) => state);
|
||||
|
||||
const ownAnswer = ownVariants[ownVariants.findIndex((v) => v.id === variant.id)]?.variant.answer || "";
|
||||
const ownVariantIndex = ownVariants.findIndex((v) => v.id === variant.id);
|
||||
const ownAnswer = ownVariantIndex >= 0 ? ownVariants[ownVariantIndex]?.variant.answer || "" : "";
|
||||
|
||||
return largeCheck ? (
|
||||
<TextareaAutosize
|
||||
|
||||
@ -56,7 +56,11 @@ export const Select = ({
|
||||
<MuiSelect
|
||||
displayEmpty
|
||||
renderValue={(value) =>
|
||||
value ? items[Number(value)] : <Typography sx={{ color: colorPlaceholder }}>{placeholder}</Typography>
|
||||
value ? (
|
||||
<Typography sx={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>{items[Number(value)]}</Typography>
|
||||
) : (
|
||||
<Typography sx={{ color: colorPlaceholder }}>{placeholder}</Typography>
|
||||
)
|
||||
}
|
||||
id="display-select"
|
||||
variant="outlined"
|
||||
@ -123,7 +127,7 @@ export const Select = ({
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
color: colorPlaceholder,
|
||||
whiteSpace: "normal",
|
||||
whiteSpace: "pre-wrap",
|
||||
wordBreak: "break-word",
|
||||
}}
|
||||
>
|
||||
|
||||
@ -99,8 +99,6 @@ export const createQuizViewStore = () =>
|
||||
updateOwnVariant(id, answer, extendedText, originalImageUrl, localImageUrl) {
|
||||
set(
|
||||
(state) => {
|
||||
console.log("!!! STORE !!! ___ Случился вызов варианта свой ответ. Вот что я получил:");
|
||||
console.log(id, answer, extendedText, originalImageUrl, localImageUrl);
|
||||
const index = state.ownVariants.findIndex((variant) => variant.id === id);
|
||||
|
||||
if (index < 0) {
|
||||
@ -108,7 +106,7 @@ export const createQuizViewStore = () =>
|
||||
id,
|
||||
variant: {
|
||||
id: id,
|
||||
answer: answer === null ? state.ownVariants[index].variant.answer : answer,
|
||||
answer: answer || "",
|
||||
extendedText: extendedText || "",
|
||||
hints: "",
|
||||
originalImageUrl: originalImageUrl || "",
|
||||
|
||||
@ -11,10 +11,20 @@ type VideoIframeProps = {
|
||||
};
|
||||
|
||||
export default function QuizVideo({ videoUrl, containerSX }: VideoIframeProps) {
|
||||
console.log("=== QuizVideo component called ===");
|
||||
console.log("QuizVideo component called with URL:", videoUrl);
|
||||
console.log("ContainerSX:", containerSX);
|
||||
|
||||
const { data: videoData, error, isLoading } = useSWR(["video", videoUrl], (params) => getVideo(params[1]));
|
||||
|
||||
console.log("Video data:", videoData);
|
||||
console.log("Error:", error);
|
||||
console.log("Is loading:", isLoading);
|
||||
console.log("=== End QuizVideo component ===");
|
||||
|
||||
return (
|
||||
<Box
|
||||
id="test-video-container"
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
@ -28,7 +38,19 @@ export default function QuizVideo({ videoUrl, containerSX }: VideoIframeProps) {
|
||||
) : !videoData || error ? (
|
||||
<ApologyPage error={error ?? new Error()} />
|
||||
) : videoData.sourceName === "custom" || videoData.sourceName === "yandex" ? (
|
||||
<Box component="video" sx={{ width: "100%", height: "100%" }} autoPlay controls muted src={videoData.url} />
|
||||
<Box
|
||||
component="video"
|
||||
sx={{ width: "100%", height: "100%" }}
|
||||
autoPlay
|
||||
controls
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
onError={(e) => console.error("Video error:", e)}
|
||||
onLoadStart={() => console.log("Video load started")}
|
||||
onCanPlay={() => console.log("Video can play")}
|
||||
src={videoData.url}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
component="iframe"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
type SourceType = "youtube" | "short" | "vk" | "google" | "yandex" | "mail" | "tiktok" | "custom";
|
||||
type SourceType = "youtube" | "short" | "vk" | "google" | "yandex" | "mail" | "tiktok" | "s3" | "custom";
|
||||
|
||||
export type VideoUrlResult = {
|
||||
sourceName: SourceType;
|
||||
@ -68,6 +68,7 @@ const FILTER_SITES_REGEX: Record<Exclude<SourceType, "short" | "custom">, RegExp
|
||||
google: /^(https?:\/\/)?(www.)?drive\.google\..+$/,
|
||||
yandex: /^(https?:\/\/)?disk\.yandex\..+$/,
|
||||
mail: /^(https?:\/\/)?cloud\.mail\..+$/,
|
||||
s3: /^(https?:\/\/)?.*\.s3\..+$/,
|
||||
};
|
||||
|
||||
const EXTRACT_VIDEO_ID_REGEX: Record<Exclude<SourceType, "custom">, RegExp> = {
|
||||
@ -78,9 +79,12 @@ const EXTRACT_VIDEO_ID_REGEX: Record<Exclude<SourceType, "custom">, RegExp> = {
|
||||
yandex: /(?<=i\/)[\w-]+/,
|
||||
mail: /$/,
|
||||
tiktok: /(?<=video\/|\.com\/)[\w-]+/,
|
||||
s3: /$/,
|
||||
};
|
||||
|
||||
export const getVideo = async (videoUrl: string): Promise<VideoUrlResult> => {
|
||||
console.log("getVideo called with URL:", videoUrl);
|
||||
|
||||
if (videoUrl.match(FILTER_SITES_REGEX.youtube)?.[0]) {
|
||||
if (videoUrl.includes("youtube.com/shorts")) {
|
||||
const videoId = videoUrl.match(EXTRACT_VIDEO_ID_REGEX.short)?.[0];
|
||||
@ -161,5 +165,11 @@ export const getVideo = async (videoUrl: string): Promise<VideoUrlResult> => {
|
||||
return { sourceName: "mail", url: videoUrl };
|
||||
}
|
||||
|
||||
if (videoUrl.match(FILTER_SITES_REGEX.s3)) {
|
||||
console.log("S3 URL detected, returning as custom video");
|
||||
return { sourceName: "custom", url: videoUrl };
|
||||
}
|
||||
|
||||
console.log("No matching source found, returning custom:", videoUrl);
|
||||
return { sourceName: "custom", url: videoUrl };
|
||||
};
|
||||
|
||||
@ -15,14 +15,6 @@ export function useAIQuiz() {
|
||||
//Получаем инфо о квизе и список вопросов.
|
||||
const { settings, questions, quizId, cnt, quizStep, preview } = useQuizStore();
|
||||
|
||||
// Отладочная информация о настройках таймера
|
||||
console.log("🤖 AI Quiz settings:", {
|
||||
questionTimerEnabled: settings.questionTimerEnabled,
|
||||
time_of_passing: settings.cfg.time_of_passing,
|
||||
timerEnabled: Boolean(settings.questionTimerEnabled),
|
||||
timerSeconds: settings.cfg.time_of_passing ?? 0,
|
||||
});
|
||||
|
||||
//Список ответов на вопрос. Мы записываем ответы локально, параллельно отправляя на бек информацию о ответах
|
||||
const answers = useQuizViewStore((state) => state.answers);
|
||||
|
||||
@ -113,7 +105,6 @@ export function useAIQuiz() {
|
||||
preview,
|
||||
currentQuestion,
|
||||
onNext: () => {
|
||||
console.log("🤖 AI Quiz: Timer triggered moveToNextQuestion");
|
||||
moveToNextQuestion();
|
||||
},
|
||||
});
|
||||
|
||||
@ -12,18 +12,9 @@ import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoa
|
||||
import { useQuestionTimer } from "./useQuestionTimer";
|
||||
|
||||
export function useBranchingQuiz() {
|
||||
console.log("РАБОТАЮ Я, УПРАВЛЯТОР КВИЗА ВЕТВЛЕНИЯ");
|
||||
//Получаем инфо о квизе и список вопросов.
|
||||
const { settings, questions, quizId, cnt, preview } = useQuizStore();
|
||||
|
||||
// Отладочная информация о настройках таймера
|
||||
console.log("🌳 Branching Quiz settings:", {
|
||||
questionTimerEnabled: settings.questionTimerEnabled,
|
||||
time_of_passing: settings.cfg.time_of_passing,
|
||||
timerEnabled: Boolean(settings.questionTimerEnabled),
|
||||
timerSeconds: settings.cfg.time_of_passing ?? 0,
|
||||
});
|
||||
|
||||
//Когда квиз линейный, не ветвящийся, мы идём по вопросам по их порядковому номеру. Это их page.
|
||||
//За корректность page отвечает конструктор квизов. Интересный факт, если в конструкторе удалить из середины вопрос, то случится куча запросов изменения вопросов с изменением этого page
|
||||
const sortedQuestions = useMemo(() => {
|
||||
@ -58,16 +49,11 @@ export function useBranchingQuiz() {
|
||||
if (settings.cfg.haveRoot) {
|
||||
// Если есть ветвление, то settings.cfg.haveRoot будет заполнен
|
||||
//Если заполнен, то дерево растёт с root и это 1 вопрос :)
|
||||
console.log("Существует запись о корне: " + settings.cfg.haveRoot);
|
||||
const nextQuestion = sortedQuestions.find(
|
||||
//Функция ищет первое совпадение по массиву
|
||||
(question) => question.id === settings.cfg.haveRoot || question.content.id === settings.cfg.haveRoot
|
||||
);
|
||||
|
||||
console.log("___nextQuestion____");
|
||||
console.log(nextQuestion);
|
||||
console.log("___sortedQuestions____");
|
||||
console.log(sortedQuestions);
|
||||
if (!nextQuestion) return null;
|
||||
return nextQuestion.id;
|
||||
}
|
||||
@ -189,7 +175,6 @@ export function useBranchingQuiz() {
|
||||
preview,
|
||||
currentQuestion,
|
||||
onNext: () => {
|
||||
console.log("🌳 Branching Quiz: Timer triggered moveToNextQuestion");
|
||||
moveToNextQuestion();
|
||||
},
|
||||
});
|
||||
|
||||
@ -15,14 +15,6 @@ export function useLinearQuiz() {
|
||||
//Получаем инфо о квизе и список вопросов.
|
||||
const { settings, questions, quizId, cnt, preview } = useQuizStore();
|
||||
|
||||
// Отладочная информация о настройках таймера
|
||||
console.log("📏 Linear Quiz settings:", {
|
||||
questionTimerEnabled: settings.questionTimerEnabled,
|
||||
time_of_passing: settings.cfg.time_of_passing,
|
||||
timerEnabled: Boolean(settings.questionTimerEnabled),
|
||||
timerSeconds: settings.cfg.time_of_passing ?? 0,
|
||||
});
|
||||
|
||||
//Когда квиз линейный, не ветвящийся, мы идём по вопросам по их порядковому номеру. Это их page.
|
||||
//За корректность page отвечает конструктор квизов. Интересный факт, если в конструкторе удалить из середины вопрос, то случится куча запросов изменения вопросов с изменением этого page
|
||||
const sortedQuestions = useMemo(() => {
|
||||
@ -183,7 +175,6 @@ export function useLinearQuiz() {
|
||||
preview,
|
||||
currentQuestion,
|
||||
onNext: () => {
|
||||
console.log("📏 Linear Quiz: Timer triggered moveToNextQuestion");
|
||||
// Программный переход к следующему вопросу
|
||||
moveToNextQuestion();
|
||||
},
|
||||
|
||||
@ -20,44 +20,24 @@ export function useQuestionTimer({ enabled, seconds, quizId, preview, currentQue
|
||||
const isFirstQuestionRef = useRef<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("🕐 useQuestionTimer useEffect triggered", {
|
||||
enabled,
|
||||
seconds,
|
||||
quizId,
|
||||
preview,
|
||||
currentQuestionId: currentQuestion?.id,
|
||||
currentQuestionType: currentQuestion?.type,
|
||||
currentQuizStep,
|
||||
hasCurrentQuestion: !!currentQuestion,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
|
||||
if (!enabled) {
|
||||
console.log("❌ Timer disabled");
|
||||
return;
|
||||
}
|
||||
if (!seconds || seconds <= 0) {
|
||||
console.log("❌ Invalid seconds:", seconds);
|
||||
return;
|
||||
}
|
||||
if (!currentQuestion) {
|
||||
console.log("❌ No current question");
|
||||
return;
|
||||
}
|
||||
if (currentQuizStep !== "question") {
|
||||
console.log("❌ Not on question step:", currentQuizStep);
|
||||
return;
|
||||
}
|
||||
if (currentQuestion.type === "result") {
|
||||
console.log("❌ Question is result type");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("✅ Starting timer for", seconds, "seconds");
|
||||
|
||||
// Сбрасываем предыдущий таймер
|
||||
if (timeoutRef.current) {
|
||||
console.log("🔄 Clearing previous timer");
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
}
|
||||
@ -67,27 +47,21 @@ export function useQuestionTimer({ enabled, seconds, quizId, preview, currentQue
|
||||
const startDelay = isFirstQuestion ? 2000 : 100; // 2 секунды для первого вопроса, 100ms для остальных
|
||||
|
||||
if (isFirstQuestion) {
|
||||
console.log("🔄 First question detected, adding 2s delay to prevent navigation conflicts");
|
||||
isFirstQuestionRef.current = false;
|
||||
}
|
||||
|
||||
timeoutRef.current = window.setTimeout(
|
||||
async () => {
|
||||
console.log("⏰ Timer expired! Auto-advancing to next question");
|
||||
try {
|
||||
if (!preview) {
|
||||
console.log("📤 Sending empty answer for question:", currentQuestion.id);
|
||||
// Отправляем пустую строку в ответе (questionAnswer === undefined)
|
||||
await sendQuestionAnswer(quizId, currentQuestion, undefined, ownVariants);
|
||||
console.log("✅ Empty answer sent successfully");
|
||||
} else {
|
||||
console.log("👀 Preview mode - skipping answer send");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("❌ Error sending empty timed answer", e);
|
||||
enqueueSnackbar("Ошибка при отправке ответа по таймеру");
|
||||
} finally {
|
||||
console.log("➡️ Calling onNext()");
|
||||
onNext();
|
||||
}
|
||||
},
|
||||
@ -95,7 +69,6 @@ export function useQuestionTimer({ enabled, seconds, quizId, preview, currentQue
|
||||
);
|
||||
|
||||
return () => {
|
||||
console.log("🧹 Cleaning up timer");
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
timeoutRef.current = null;
|
||||
|
||||
@ -29,7 +29,6 @@ function analyicStatus({ status, haveRoot }: StatusData) {
|
||||
}
|
||||
|
||||
export const initDataManager = (data: StatusData) => {
|
||||
console.log("🔧 Initializing DataManager with:", data);
|
||||
analyicStatus(data);
|
||||
switch (statusOfQuiz) {
|
||||
case "line":
|
||||
@ -43,7 +42,6 @@ export const initDataManager = (data: StatusData) => {
|
||||
break;
|
||||
}
|
||||
isInitialized = true;
|
||||
console.log("✅ DataManager initialized with type:", statusOfQuiz);
|
||||
};
|
||||
|
||||
// Главный хук (интерфейс для потребителей)
|
||||
@ -52,7 +50,6 @@ export const useQuestionFlowControl = () => {
|
||||
// Попытка автоматической инициализации на основе текущих настроек
|
||||
const { settings } = useQuizStore.getState();
|
||||
if (settings && settings.status) {
|
||||
console.log("🔄 Auto-initializing DataManager with settings:", settings);
|
||||
initDataManager({
|
||||
status: settings.status,
|
||||
haveRoot: settings.cfg.haveRoot,
|
||||
@ -66,7 +63,6 @@ export const useQuestionFlowControl = () => {
|
||||
|
||||
// Функция для сброса состояния (полезна для HMR)
|
||||
export const resetDataManager = () => {
|
||||
console.log("🔄 Resetting DataManager");
|
||||
cachedManager = null as any;
|
||||
isInitialized = false;
|
||||
statusOfQuiz = null as any;
|
||||
|
||||
@ -11,7 +11,6 @@ export async function sendQuestionAnswer(
|
||||
ownVariants: OwnVariant[]
|
||||
) {
|
||||
if (!questionAnswer) {
|
||||
console.log("📤 sendQuestionAnswer: Sending empty answer for question", question.id);
|
||||
return sendAnswer({
|
||||
questionId: question.id,
|
||||
body: "",
|
||||
@ -101,9 +100,7 @@ export async function sendQuestionAnswer(
|
||||
return;
|
||||
}
|
||||
case "images": {
|
||||
console.log("Работает отправщик ответа для типа КАРТИНКИ");
|
||||
if (question.content.multi) {
|
||||
console.log("Этот вопрос есть МУЛЬТИ");
|
||||
const answer = questionAnswer.answer;
|
||||
const ownAnswer = Array.isArray(answer)
|
||||
? ownVariants[ownVariants.findIndex((variant) => answer.some((a: string) => a === variant.id))]?.variant
|
||||
@ -151,7 +148,6 @@ export async function sendQuestionAnswer(
|
||||
qid: quizId,
|
||||
});
|
||||
}
|
||||
console.log("Этот вопрос НЕ есть МУЛЬТИ");
|
||||
|
||||
const variant = question.content.variants.find((v) => v.id === questionAnswer.answer);
|
||||
|
||||
@ -160,9 +156,6 @@ export async function sendQuestionAnswer(
|
||||
// Берем fileId из ownVariants для own вариантов
|
||||
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
|
||||
|
||||
console.log("Был выбран вариант ", variant);
|
||||
console.log("Был выбран ownVariant ", ownVariantData);
|
||||
|
||||
let imageValue = variant.extendedText;
|
||||
if (variant.isOwn) {
|
||||
if (ownVariantData?.originalImageUrl) {
|
||||
@ -175,11 +168,6 @@ export async function sendQuestionAnswer(
|
||||
}
|
||||
}
|
||||
|
||||
console.log("В конечном итоге я планирую отправить вот эти данные: ", {
|
||||
Image: imageValue,
|
||||
Description: ownVariantData ? ownVariantData.answer : variant.answer,
|
||||
});
|
||||
|
||||
const body = {
|
||||
Image: imageValue,
|
||||
Description: ownVariantData ? ownVariantData.answer : variant.answer,
|
||||
|
||||
@ -20,7 +20,16 @@ const theme = createTheme({
|
||||
},
|
||||
components: {
|
||||
MuiCssBaseline: {
|
||||
styleOverrides: fontFaces,
|
||||
styleOverrides: {
|
||||
// Если fontFaces это CSSObject
|
||||
...(typeof fontFaces === "string" ? {} : fontFaces),
|
||||
// Добавляем стиль для Typography
|
||||
".MuiTypography-root": {
|
||||
whiteSpace: "pre-wrap !important",
|
||||
},
|
||||
// Если fontFaces это строка, добавляем её как @font-face
|
||||
...(typeof fontFaces === "string" ? { "@font-face": fontFaces } : {}),
|
||||
},
|
||||
},
|
||||
MuiScopedCssBaseline: {
|
||||
styleOverrides: {
|
||||
@ -28,6 +37,11 @@ const theme = createTheme({
|
||||
},
|
||||
},
|
||||
MuiTypography: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
whiteSpace: "pre-wrap",
|
||||
},
|
||||
},
|
||||
defaultProps: {
|
||||
variantMapping: {
|
||||
p1: "p",
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
"preview": "vite preview",
|
||||
"cypress:open": "cypress open",
|
||||
"prepublishOnly": "npm run build:package",
|
||||
"deploy": "echo '🚀 Начало процесса деплоя...' && docker login gitea.pena && if [ $? -eq 0 ]; then echo '✅ Успешный логин в Docker registry'; else echo '❌ Ошибка логина в Docker registry'; exit 1; fi && echo '🏗️ Сборка Docker образа...' && docker build -t gitea.pena/squiz/frontanswerer/$(git branch --show-current):latest . && if [ $? -eq 0 ]; then echo '✅ Docker образ успешно собран'; else echo '❌ Ошибка сборки Docker образа'; exit 1; fi && echo '📤 Пуш образа в registry...' && docker push gitea.pena/squiz/frontanswerer/$(git branch --show-current):latest && if [ $? -eq 0 ]; then echo '✅ Образ успешно загружен в registry'; echo '🎉 Деплой завершен успешно!'; else echo '❌ Ошибка загрузки образа в registry'; exit 1; fi",
|
||||
"deploy": "docker login gitea.pena && docker build -t gitea.pena/squiz/frontanswerer/$(git branch --show-current):latest . && docker push gitea.pena/squiz/frontanswerer/$(git branch --show-current):latest",
|
||||
"prepare": "husky",
|
||||
"test": "cypress open"
|
||||
},
|
||||
|
||||
@ -17,7 +17,10 @@ export default function App() {
|
||||
height: "100dvh",
|
||||
}}
|
||||
>
|
||||
<QuizAnswerer quizId={quizId || currentUrl || ""} />
|
||||
<QuizAnswerer
|
||||
quizId={quizId || currentUrl || ""}
|
||||
changeFaviconAndTitle={true}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ const widget = {
|
||||
create({
|
||||
selector,
|
||||
quizId,
|
||||
changeFaviconAndTitle = true,
|
||||
changeFaviconAndTitle = false,
|
||||
}: {
|
||||
selector: string;
|
||||
quizId: string;
|
||||
|
||||
@ -4,7 +4,13 @@ import { Dialog, IconButton, Slide, SlideProps, SxProps, Theme } from "@mui/mate
|
||||
import { forwardRef } from "react";
|
||||
|
||||
const SlideTransition = forwardRef<unknown, SlideProps>((props, ref) => {
|
||||
return <Slide direction="up" ref={ref} {...props} />;
|
||||
return (
|
||||
<Slide
|
||||
direction="up"
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
interface Props {
|
||||
@ -46,7 +52,11 @@ export default function QuizDialog({
|
||||
],
|
||||
}}
|
||||
>
|
||||
<QuizAnswerer quizId={quizId} changeFaviconAndTitle={false} disableGlobalCss />
|
||||
<QuizAnswerer
|
||||
quizId={quizId}
|
||||
changeFaviconAndTitle={false}
|
||||
disableGlobalCss
|
||||
/>
|
||||
<IconButton
|
||||
onClick={onClose}
|
||||
sx={{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user