diff --git a/lib/api/quizRelase.ts b/lib/api/quizRelase.ts index f72ef9c..4312d11 100644 --- a/lib/api/quizRelase.ts +++ b/lib/api/quizRelase.ts @@ -75,8 +75,52 @@ export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestPara // Глобальные переменные для хранения состояния между вызовами let globalStatus: string | null = null; let isFirstRequest = true; +export async function getData({ quizId }: { quizId: string }): Promise<{ + data: GetQuizDataResponse | null; + isRecentlyCompleted: boolean; + error?: AxiosError; +}> { + try { + const { data, headers } = await axios( + domain + `/answer/v1.0.0/settings${window.location.search}`, + { + method: "POST", + headers: { + "X-Sessionkey": SESSIONS, + "Content-Type": "application/json", + DeviceType: DeviceType, + Device: Device, + OS: OSDevice, + Browser: userAgent, + }, + data: { + quiz_id: quizId, + limit: 100, + page: 0, + need_config: true, + }, + } + ); + const sessions = JSON.parse(localStorage.getItem("sessions") || "{}"); -export async function getData({ quizId, page }: { quizId: string; page?: number }): Promise<{ + //Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки + if (typeof sessions[quizId] === "number" && data.settings.cfg.includes('antifraud":true')) { + // unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше + if (Date.now() - sessions[quizId] < 86400000) { + return { data, isRecentlyCompleted: true }; + } + } + + SESSIONS = headers["x-sessionkey"] ? headers["x-sessionkey"] : SESSIONS; + + return { data, isRecentlyCompleted: false }; + } catch (nativeError) { + const error = nativeError as AxiosError; + + return { data: null, isRecentlyCompleted: false, error: error }; + } +} +export async function getDataSingle({ quizId, page }: { quizId: string; page?: number }): Promise<{ data: GetQuizDataResponse | null; isRecentlyCompleted: boolean; error?: AxiosError; @@ -231,7 +275,7 @@ export async function getQuizDataAI(quizId: string) { while (resultRetryCount < maxRetries) { try { console.log(`[getQuizDataAI] Attempt ${resultRetryCount + 1} for result questions, page: ${page}`); - const response = await getData({ quizId, page }); + const response = await getData({ quizId }); console.log("[getQuizDataAI] Response from getData:", response); if (response.error) { @@ -286,7 +330,7 @@ export async function getQuizDataAI(quizId: string) { try { console.log(`[getQuizDataAI] Empty items retry ${emptyRetryCount + 1}`); await new Promise((resolve) => setTimeout(resolve, 1000)); - const response = await getData({ quizId, page }); + const response = await getData({ quizId }); if (response.error) { console.error("[getQuizDataAI] Error in empty items check:", response.error); diff --git a/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx b/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx index 64d3317..21bee90 100644 --- a/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx +++ b/lib/components/ViewPublicationPage/ContactForm/ContactForm.tsx @@ -26,6 +26,7 @@ import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; import { isProduction } from "@/utils/defineDomain"; import { useQuizStore } from "@/stores/useQuizStore"; import { useTranslation } from "react-i18next"; +import { isNeftyanka } from "@/ui_kit/neftyankacrutch"; type Props = { currentQuestion: AnyTypedQuizQuestion; @@ -317,7 +318,7 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => { }, }} > - {settings.cfg.formContact?.button || t("Get results")} + {isNeftyanka ? t("neftyanka button") : settings.cfg.formContact?.button || t("Get results")} {show_badge && ( diff --git a/lib/components/ViewPublicationPage/ContactForm/ContactTextBlock/index.tsx b/lib/components/ViewPublicationPage/ContactForm/ContactTextBlock/index.tsx index 1240c71..62b441a 100644 --- a/lib/components/ViewPublicationPage/ContactForm/ContactTextBlock/index.tsx +++ b/lib/components/ViewPublicationPage/ContactForm/ContactTextBlock/index.tsx @@ -3,6 +3,7 @@ import { useRootContainerSize } from "@contexts/RootContainerWidthContext.ts"; import { QuizSettingsConfig } from "@model/settingsData.ts"; import { FC } from "react"; import { useTranslation } from "react-i18next"; +import { isNeftyanka } from "@/ui_kit/neftyankacrutch"; type ContactTextBlockProps = { settings: QuizSettingsConfig; @@ -47,7 +48,9 @@ export const ContactTextBlock: FC = ({ settings }) => { wordBreak: "break-word", }} > - {settings.cfg.formContact.title || t("Fill out the form to receive your test results")} + {isNeftyanka + ? t("neftyanka FK") + : settings.cfg.formContact.title || t("Fill out the form to receive your test results")} {settings.cfg.formContact.desc && ( ; // temporary fix ts(2590) + +interface TextSpecialProps { + currentQuestion: QuizQuestionText; + answer?: Answer; + stepNumber?: number | null; +} + +function highlightQuestions(text: string) { + // Регулярка с учётом возможной точки в конце + const regex = /(вопрос\s\d+[a-zA-Zа-яА-Я]\.?)/g; + + // Замена на с жирным текстом + return text.replace(regex, '$1'); +} + +export const TextNeftyanka = ({ currentQuestion, answer, stepNumber }: TextSpecialProps) => { + const { settings } = useQuizStore(); + const { updateAnswer } = useQuizViewStore((state) => state); + const isHorizontal = true; + const theme = useTheme(); + const isMobile = useRootContainerSize() < 650; + + const onInputChange = async ({ target }: ChangeEvent) => { + updateAnswer(currentQuestion.id, target.value, 0); + }; + + return ( + + + {isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && ( + event.preventDefault()} + > + + + )} + + {highlightQuestions(currentQuestion.title)} + + { + + } + + {!isHorizontal && currentQuestion.content.back && currentQuestion.content.back !== " " && ( + event.preventDefault()} + > + + + )} + + ); +}; diff --git a/lib/components/ViewPublicationPage/questions/Text/TextNormal.tsx b/lib/components/ViewPublicationPage/questions/Text/TextNormal.tsx index 9f40523..5a6a454 100644 --- a/lib/components/ViewPublicationPage/questions/Text/TextNormal.tsx +++ b/lib/components/ViewPublicationPage/questions/Text/TextNormal.tsx @@ -60,6 +60,7 @@ export const TextNormal = ({ currentQuestion, answer }: TextNormalProps) => { placeholder={currentQuestion.content.placeholder} value={answer || ""} onChange={onInputChange} + multiline={Boolean(currentQuestion.content?.multi)} sx={{ "& .MuiOutlinedInput-root": { background: settings.cfg.design diff --git a/lib/components/ViewPublicationPage/questions/Text/index.tsx b/lib/components/ViewPublicationPage/questions/Text/index.tsx index 081da54..6ecf3f2 100644 --- a/lib/components/ViewPublicationPage/questions/Text/index.tsx +++ b/lib/components/ViewPublicationPage/questions/Text/index.tsx @@ -5,6 +5,8 @@ import { TextSpecialHorisontal } from "./TextSpecialHorisontal"; import type { QuizQuestionText } from "@model/questionTypes/text"; import { useQuizStore } from "@/stores/useQuizStore"; +import { isNeftyanka } from "@/ui_kit/neftyankacrutch"; +import { TextNeftyanka } from "./TextNeftyanka"; type TextProps = { currentQuestion: QuizQuestionText; @@ -18,7 +20,16 @@ export const Text = ({ currentQuestion, stepNumber }: TextProps) => { const answers = useQuizViewStore((state) => state.answers); const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; - if (pathOnly === "/92ed5e3e-8e6a-491e-87d0-d3197682d0e3" || pathOnly === "/cc006b40-ccbd-4600-a1d3-f902f85aa0a0") + if (isNeftyanka) + return ( + + ); + + if (pathOnly === "/92ed5e3e-8e6a-491e-87d0-d3197682d0e3") return ( ; InputProps?: Partial; + multiline?: boolean; } export default function CustomTextField({ @@ -28,11 +29,16 @@ export default function CustomTextField({ onKeyDown, onBlur, InputProps, + multiline = false, }: CustomTextFieldProps) { const theme = useTheme(); return ( - + ); + root.render( + + ); }, };