Merge branch 'ball' into dev

This commit is contained in:
Nastya 2024-10-26 18:00:54 +03:00
commit c7ac1dbc93
9 changed files with 173 additions and 48 deletions

@ -252,3 +252,40 @@ export function sendFC({ questionId, body, qid, preview }: SendFCParams) {
method: "POST",
});
}
//форма контактов
export type SendResultParams = {
questionId: string;
pointsSum: number;
qid: string;
preview: boolean;
};
export function sendResult({ questionId, pointsSum, qid, preview }: SendResultParams) {
if (preview) return;
const formData = new FormData();
// const keysBody = Object.keys(body)
// const content:any = {}
// fields.forEach((key) => {
// if (keysBody.includes(key)) content[key] = body.key
// })
const answers = [
{
question_id: questionId,
content: pointsSum.toString(),
result: false,
qid,
},
];
formData.append("answers", JSON.stringify(answers));
formData.append("qid", qid);
return publicationMakeRequest({
url: domain + `/answer/v1.0.0/answer`,
body: formData,
method: "POST",
});
}

@ -24,11 +24,14 @@ import { NameplateLogo } from "@icons/NameplateLogo";
import type { FormContactFieldData, FormContactFieldName } from "@model/settingsData";
import type { QuizQuestionResult } from "@model/questionTypes/result";
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { isProduction } from "@/utils/defineDomain";
type Props = {
currentQuestion: AnyTypedQuizQuestion;
onShowResult: () => void;
};
//Костыль для особого квиза. Для него не нужно показывать email адрес
const isDisableEmail = window.location.pathname.includes("/377c7570-1bee-4320-ac1e-d731b6223ce8");
export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
const theme = useTheme();
@ -114,7 +117,8 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
async function handleShowResultsClick() {
const FC = settings.cfg.formContact.fields;
if (FC["email"].used !== EMAIL_REGEXP.test(email)) {
if (!isDisableEmail && FC["email"].used !== EMAIL_REGEXP.test(email)) {
return enqueueSnackbar("введена некорректная почта");
}
@ -250,6 +254,9 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
setText={setText}
adress={adress}
setAdress={setAdress}
crutch={{
disableEmail: isDisableEmail,
}}
/>
</Box>
<Box
@ -315,9 +322,7 @@ export const ContactForm = ({ currentQuestion, onShowResult }: Props) => {
<Box
component={Link}
target={"_blank"}
href={`https://${
window.location.hostname[0] === "s" ? "s" : ""
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
href={`https://${isProduction ? "" : "s"}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
sx={{
display: "flex",
alignItems: "center",

@ -19,6 +19,9 @@ type InputsProps = {
setText: Dispatch<SetStateAction<string>>;
adress: string;
setAdress: Dispatch<SetStateAction<string>>;
crutch: {
disableEmail: boolean;
};
};
export const Inputs = ({
@ -32,6 +35,7 @@ export const Inputs = ({
setText,
adress,
setAdress,
crutch,
}: InputsProps) => {
const { settings } = useQuizSettings();
const FC = settings.cfg.formContact.fields;
@ -95,7 +99,7 @@ export const Inputs = ({
return (
<>
{FC["name"].used ? Name : <></>}
{FC["email"].used ? Email : <></>}
{FC["email"].used && !crutch.disableEmail ? Email : <></>}
{FC["phone"].used ? Phone : <></>}
{FC["text"].used ? Text : <></>}
{FC["address"].used ? Adress : <></>}

@ -7,7 +7,6 @@ import { AnyTypedQuizQuestion, QuizQuestionVariant } from "@/index";
export const PointSystemResultList = () => {
const theme = useTheme();
const { questions } = useQuizSettings();
const answers = useQuizViewStore((state) => state.answers);
@ -20,7 +19,6 @@ export const PointSystemResultList = () => {
let currentVariants = currentQuestion.content.variants;
const currentAnswer = answers.find((a) => a.questionId === currentQuestion.id);
const answeredVariant = currentVariants.find((v, i) => {
if (v.id === currentAnswer?.answer) {
answerIndex = i;
@ -55,14 +53,20 @@ export const PointSystemResultList = () => {
>
{currentQuestion.page + 1}.
</Typography>
<Typography>{currentQuestion.title || "Вопрос без названия"}</Typography>
<Typography
sx={{
color: theme.palette.text.primary,
}}
>
{currentQuestion.title || "Вопрос без названия"}
</Typography>
</Box>
<Typography
sx={{
color: answeredVariant?.points ? "inherit" : theme.palette.grey[500],
color: answeredVariant?.points ? theme.palette.primary.main : theme.palette.grey[500],
}}
>
{answeredVariant?.points || "0"}/1
{answeredVariant?.points || "0"}
</Typography>
</Box>
<Box

@ -22,7 +22,8 @@ import { notReachable } from "@utils/notReachable";
import { quizThemes } from "@utils/themes/Publication/themePublication";
import { DESIGN_LIST } from "@/utils/designList";
import type { ReactNode } from "react";
import { type ReactNode } from "react";
import { isProduction } from "@/utils/defineDomain";
type Props = {
currentQuestion: RealTypedQuizQuestion;
@ -95,7 +96,7 @@ export const Question = ({
{show_badge && (
<Link
target="_blank"
href={`https://${window.location.hostname.includes("s") ? "s" : ""}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
href={`https://${isProduction ? "" : "s"}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
sx={{
mt: "20px",
alignSelf: "end",
@ -123,7 +124,11 @@ export const Question = ({
</Box>
</Box>
{questionSelect}
<Footer stepNumber={currentQuestionStepNumber} prevButton={prevButton} nextButton={nextButton} />
<Footer
stepNumber={currentQuestionStepNumber}
prevButton={prevButton}
nextButton={nextButton}
/>
</Box>
</Box>
);
@ -140,7 +145,12 @@ function QuestionByType({ question, stepNumber }: { question: RealTypedQuizQuest
case "emoji":
return <Emoji currentQuestion={question} />;
case "text":
return <Text currentQuestion={question} stepNumber={stepNumber} />;
return (
<Text
currentQuestion={question}
stepNumber={stepNumber}
/>
);
case "select":
return <Select currentQuestion={question} />;
case "date":

@ -16,6 +16,9 @@ import type { QuizQuestionResult } from "@/model/questionTypes/result";
import QuizVideo from "@/ui_kit/VideoIframe/VideoIframe";
import { TextAccordion } from "./tools/TextAccordion";
import { PointSystemResultList } from "./PointSystemResultList";
import { enqueueSnackbar } from "notistack";
import { sendFC, sendResult } from "@/api/quizRelase";
import { isProduction } from "@/utils/defineDomain";
type ResultFormProps = {
resultQuestion: QuizQuestionResult;
@ -25,8 +28,10 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
const theme = useTheme();
const isMobile = useRootContainerSize() < 650;
const isTablet = useRootContainerSize() < 1000;
const { settings, show_badge, quizId } = useQuizSettings();
const { settings, show_badge, quizId, questions, preview } = useQuizSettings();
const setCurrentQuizStep = useQuizViewStore((state) => state.setCurrentQuizStep);
//Список засчитанных баллов для балловых квизов
const pointsSum = useQuizViewStore((state) => state.pointsSum);
const spec = settings.cfg.spec;
const vkMetrics = useVkMetricsGoals(settings.cfg.vkMetricsNumber);
const yandexMetrics = useYandexMetricsGoals(settings.cfg.yandexMetricsNumber);
@ -36,6 +41,41 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
yandexMetrics.resultIdShown(resultQuestion.id);
}, [resultQuestion.id, vkMetrics, yandexMetrics]);
useEffect(() => {
(async () => {
if (!settings.cfg.showfc) {
try {
await sendFC({
questionId: resultQuestion.id,
body: {},
qid: quizId,
preview,
});
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
localStorage.setItem("sessions", JSON.stringify({ ...sessions, [quizId]: new Date().getTime() }));
} catch (e) {
enqueueSnackbar("Заявка не может быть отправлена");
}
}
if (Boolean(settings.cfg.score)) {
try {
await sendResult({
questionId: resultQuestion.id,
pointsSum,
qid: quizId,
preview,
});
const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");
localStorage.setItem("sessions", JSON.stringify({ ...sessions, [quizId]: new Date().getTime() }));
} catch (e) {
enqueueSnackbar("Количество баллов не может быть отправлено");
}
}
})();
}, []);
return (
<Box
sx={{
@ -188,32 +228,53 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
</Typography>
)}
{settings.cfg?.score && (
<TextAccordion
headerText={
<Typography
sx={{
color: theme.palette.primary.main,
"&:hover": {
color: theme.palette.primary.dark,
},
}}
>
Посмотреть ответы
</Typography>
}
sx={{
mt: "60px",
width: "100%",
}}
>
<Box
<>
<Typography
sx={{
mt: "25px",
color: theme.palette.primary.main,
fontSize: "30px",
m: "30px 0",
fontWeight: 600,
}}
>
<PointSystemResultList />
</Box>
</TextAccordion>
Ваши баллы
</Typography>
<Typography
sx={{
color: theme.palette.primary.main,
fontSize: "30px",
fontWeight: 600,
}}
>
{pointsSum} из {questions.filter((e) => e.type != "result").length}
</Typography>
<TextAccordion
headerText={
<Typography
sx={{
color: theme.palette.primary.main,
"&:hover": {
color: theme.palette.primary.dark,
},
}}
>
Посмотреть ответы
</Typography>
}
sx={{
mt: "60px",
width: "100%",
}}
>
<Box
sx={{
mt: "25px",
}}
>
<PointSystemResultList />
</Box>
</TextAccordion>
</>
)}
</Box>
</Box>
@ -221,9 +282,7 @@ export const ResultForm = ({ resultQuestion }: ResultFormProps) => {
<Box
component={Link}
target={"_blank"}
href={`https://${
window.location.hostname.includes("s") ? "s" : ""
}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
href={`https://${isProduction ? "" : "s"}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
sx={{
display: "flex",
alignItems: "center",

@ -16,6 +16,8 @@ import { useVkMetricsGoals } from "@/utils/hooks/metrics/useVkMetricsGoals";
import { useYandexMetricsGoals } from "@/utils/hooks/metrics/useYandexMetricsGoals";
import QuizVideo from "@/ui_kit/VideoIframe/VideoIframe";
import { isProduction } from "@/utils/defineDomain";
export const StartPageViewPublication = () => {
const theme = useTheme();
const { settings, show_badge, quizId, questions } = useQuizSettings();
@ -135,8 +137,7 @@ export const StartPageViewPublication = () => {
<Box
component={Link}
target={"_blank"}
href={`https://${window.location.hostname[0] === "s" ? "s" : ""
}quiz.pena.digital/squiz/quiz/logo?q=${quizId}`}
href={`https://${isProduction ? "" : "s"}quiz.pena.digital/answer/v1.0.0/logo?q=${quizId}`}
sx={{
display: "flex",
alignItems: "center",

@ -5,8 +5,13 @@
let domain = "https://hbpn.link";
const currentDomain = location.hostname;
//туризм больше не в исключениях
if (currentDomain === "s.hbpn.link" || currentDomain.includes("localhost") || currentDomain.includes("127.0.0.1"))
domain = "https://s.hbpn.link";
const isProduction = !(
currentDomain === "s.hbpn.link" ||
currentDomain.includes("localhost") ||
currentDomain.includes("127.0.0.1")
);
export { domain };
//туризм больше не в исключениях
if (!isProduction) domain = "https://s.hbpn.link";
export { domain, isProduction };

@ -127,6 +127,7 @@ export function useQuestionFlowControl() {
//Анализ результата по количеству баллов
const findResultPointsLogic = useCallback(() => {
//Отбираем из массива только тип резулт И результы с информацией о ожидаемых баллах И те результы, чьи суммы баллов меньше или равны насчитанным баллам юзера
const results = sortedQuestions.filter(
(e) => e.type === "result" && e.content.rule.minScore !== undefined && e.content.rule.minScore <= pointsSum
);
@ -136,7 +137,6 @@ export function useQuestionFlowControl() {
);
//Извлекаем самое большое число
const indexOfNext = Math.max(...numbers);
//Отдаём индекс нужного нам результата
return results[numbers.indexOf(indexOfNext)];
}, [pointsSum, sortedQuestions]);