Merge branch 'dev' into 'main'

стр результатов проверяет наличие линейного резулта + выход со стр резултов...

See merge request frontend/squiz!110
This commit is contained in:
Nastya 2024-01-05 14:55:23 +00:00
commit e81eb16c73
16 changed files with 128 additions and 58 deletions

@ -18,7 +18,7 @@ import { ResultCard, checkEmptyData } from "./cards/ResultCard";
import { EmailSettingsCard } from "./cards/EmailSettingsCard"; import { EmailSettingsCard } from "./cards/EmailSettingsCard";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { deleteQuestion } from "@root/questions/actions"; import { createResult, deleteQuestion } from "@root/questions/actions";
import { QuizQuestionResult } from "@model/questionTypes/result"; import { QuizQuestionResult } from "@model/questionTypes/result";
import IconPlus from "@icons/IconPlus"; import IconPlus from "@icons/IconPlus";
@ -57,6 +57,13 @@ export const ResultSettings = () => {
); );
useEffect(() => { useEffect(() => {
//Всегда должен существовать хоть 1 резулт - "line"
if (
!questions?.find( (q) => (q.type === "result" && q.content.rule.parentId === "line"))
) {
createResult(quiz?.backendId, "line");
console.log("Я не нашёл линейный резулт и собираюсь создать новый");
}
return () => { return () => {
if (!isReadyToLeaveRef.current && window.location.pathname !== "/edit") { if (!isReadyToLeaveRef.current && window.location.pathname !== "/edit") {
setOpenNotificationModal(true); setOpenNotificationModal(true);

@ -15,7 +15,7 @@ import {
Typography, Typography,
useMediaQuery, useMediaQuery,
useTheme, useTheme,
IconButton IconButton,
} from "@mui/material"; } from "@mui/material";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { Tariff, getMessageFromFetchError } from "@frontend/kitui"; import { Tariff, getMessageFromFetchError } from "@frontend/kitui";
@ -58,8 +58,8 @@ function TariffPage() {
setUser(user); setUser(user);
setTariffs(tariffs); setTariffs(tariffs);
setDiscounts(discounts.Discounts); setDiscounts(discounts.Discounts);
let c = currencyFormatter.format(Number(user.wallet.cash) / 100) let c = currencyFormatter.format(Number(user.wallet.cash) / 100);
setCash(c) setCash(c);
}; };
get(); get();
}, []); }, []);
@ -85,9 +85,8 @@ function TariffPage() {
method: "POST", method: "POST",
url: "https://squiz.pena.digital/customer/cart/pay", url: "https://squiz.pena.digital/customer/cart/pay",
}); });
setCash(currencyFormatter.format(Number(data.wallet.cash) / 100)) setCash(currencyFormatter.format(Number(data.wallet.cash) / 100));
enqueueSnackbar("Тариф успешно приобретён"); enqueueSnackbar("Тариф успешно приобретён");
} catch (e) { } catch (e) {
enqueueSnackbar("Произошла ошибка. Попробуйте позже"); enqueueSnackbar("Произошла ошибка. Попробуйте позже");
} }
@ -98,8 +97,9 @@ function TariffPage() {
// history.pushState({}, null, "https://hub.pena.digital/wallet?action=squizpay"); // history.pushState({}, null, "https://hub.pena.digital/wallet?action=squizpay");
var link = document.createElement("a"); var link = document.createElement("a");
link.href = `https://hub.pena.digital/payment?action=squizpay&dif=${(price - Number(user.wallet.cash)) * 100 link.href = `https://hub.pena.digital/payment?action=squizpay&dif=${
}`; (price - Number(user.wallet.cash)) * 100
}`;
document.body.appendChild(link); document.body.appendChild(link);
// link.click(); // link.click();
} }
@ -179,8 +179,9 @@ function TariffPage() {
display: "grid", display: "grid",
gap: "40px", gap: "40px",
p: "20px", p: "20px",
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px" gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${
}))`, isTablet ? "436px" : "360px"
}))`,
}} }}
> >
{createTariffElements( {createTariffElements(
@ -231,7 +232,7 @@ export const Tariffs = withErrorBoundary(TariffPage, {
Ошибка загрузки тарифов Ошибка загрузки тарифов
</Typography> </Typography>
), ),
onError: () => { }, onError: () => {},
}); });
const LoadingPage = () => ( const LoadingPage = () => (
@ -269,7 +270,7 @@ export const inCart = () => {
} }
}); });
} else { } else {
localStorage.setItem("saveCart", "[]") localStorage.setItem("saveCart", "[]");
} }
}; };
const outCart = (cart: string[]) => { const outCart = (cart: string[]) => {

@ -114,8 +114,6 @@ export const ContactForm = ({
borderRadius: "4px", borderRadius: "4px",
overflow: "auto", overflow: "auto",
height: "90vh", height: "90vh",
boxShadow:
"rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px",
}} }}
> >
<Box> <Box>
@ -133,6 +131,7 @@ export const ContactForm = ({
{quiz?.config.formContact.desc && ( {quiz?.config.formContact.desc && (
<Typography <Typography
sx={{ sx={{
color: theme.palette.text.primary,
textAlign: "center", textAlign: "center",
m: "20px 0", m: "20px 0",
fontSize: "18px", fontSize: "18px",
@ -199,7 +198,7 @@ export const ContactForm = ({
checked={ready} checked={ready}
colorIcon={theme.palette.primary.main} colorIcon={theme.palette.primary.main}
/> />
<Typography> <Typography sx={{ color: theme.palette.text.primary }}>
С&ensp; С&ensp;
<Link> Положением об обработке персональных данных </Link> <Link> Положением об обработке персональных данных </Link>
&ensp;и&ensp; &ensp;и&ensp;
@ -328,7 +327,9 @@ const CustomInput = ({ title, desc, Icon }: any) => {
const isMobile = useMediaQuery(theme.breakpoints.down(600)); const isMobile = useMediaQuery(theme.breakpoints.down(600));
return ( return (
<Box m="15px 0"> <Box m="15px 0">
<Typography mb="7px">{title}</Typography> <Typography mb="7px" color={theme.palette.text.primary}>
{title}
</Typography>
<TextField <TextField
sx={{ sx={{
width: isMobile ? "300px" : "350px", width: isMobile ? "300px" : "350px",

@ -109,6 +109,7 @@ export const Footer = ({
}, [question, answers]); }, [question, answers]);
const showResult = (nextQuestion) => { const showResult = (nextQuestion) => {
console.log("Следующий результат будет вот такой", nextQuestion);
if (nextQuestion && quiz?.config.resultInfo.when === "email") { if (nextQuestion && quiz?.config.resultInfo.when === "email") {
setShowContactForm(true); setShowContactForm(true);
return; return;
@ -241,6 +242,7 @@ export const Footer = ({
}; };
const followNextStep = () => { const followNextStep = () => {
console.log(" Я понимаю что нахожусь в линейном опроснике" + linear);
if (linear) { if (linear) {
setStepNumber((q) => q + 1); setStepNumber((q) => q + 1);
const questionIndex = questions.findIndex(({ id }) => id === question.id); const questionIndex = questions.findIndex(({ id }) => id === question.id);

@ -90,15 +90,17 @@ export const Question = ({ questions }: QuestionProps) => {
}} }}
> >
<QuestionComponent currentQuestion={currentQuestion} /> <QuestionComponent currentQuestion={currentQuestion} />
{mode[quiz.config.theme] ? ( <Box>
<NameplateLogoFQ {mode[quiz.config.theme] ? (
style={{ fontSize: "34px", width: "200px", height: "auto" }} <NameplateLogoFQ
/> style={{ fontSize: "34px", width: "200px", height: "auto" }}
) : ( />
<NameplateLogoFQDark ) : (
style={{ fontSize: "34px", width: "200px", height: "auto" }} <NameplateLogoFQDark
/> style={{ fontSize: "34px", width: "200px", height: "auto" }}
)} />
)}
</Box>
</Box> </Box>
)} )}
{showResultForm && quiz?.config.resultInfo.when === "before" && ( {showResultForm && quiz?.config.resultInfo.when === "before" && (

@ -1,4 +1,10 @@
import { Box, Typography, Button } from "@mui/material"; import {
Box,
Typography,
Button,
useMediaQuery,
useTheme,
} from "@mui/material";
import { getQuestionByContentId } from "@root/questions/actions"; import { getQuestionByContentId } from "@root/questions/actions";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
@ -24,16 +30,33 @@ export const ResultForm = ({
}: ResultFormProps) => { }: ResultFormProps) => {
const quiz = useCurrentQuiz(); const quiz = useCurrentQuiz();
const mode = modes; const mode = modes;
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const { questions } = useQuestionsStore(); const { questions } = useQuestionsStore();
const resultQuestion = (questions.find(
(question) => const searchResult = () => {
question.type === "result" && if (Boolean(quiz?.config.haveRoot)) {
question.content.rule.parentId === currentQuestion.content.id, //ищём для ветвления
) || return (questions.find(
questions.find( (question) =>
(question) => question.type === "result" &&
question.type === "result" && question.content.rule.parentId === "line", question.content.rule.parentId === currentQuestion.content.id,
)) as AnyTypedQuizQuestion; ) ||
questions.find(
(question) =>
question.type === "result" &&
question.content.rule.parentId === "line",
)) as AnyTypedQuizQuestion;
} else {
return questions.find(
(question) =>
question.type === "result" &&
question.content.rule.parentId === "line",
) as AnyTypedQuizQuestion;
}
};
const resultQuestion = searchResult();
const followNextForm = () => { const followNextForm = () => {
setShowResultForm(false); setShowResultForm(false);
@ -41,6 +64,7 @@ export const ResultForm = ({
}; };
if (resultQuestion === undefined) return <></>; if (resultQuestion === undefined) return <></>;
console.log("Я форма показа резултата и он такой ", resultQuestion);
return ( return (
<Box <Box
sx={{ sx={{
@ -58,15 +82,16 @@ export const ResultForm = ({
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
width: "490px", width: isMobile ? "100%" : "490px",
padding: isMobile ? "0 16px" : undefined,
}} }}
> >
{!resultQuestion?.content.useImage && resultQuestion.content.video && ( {!resultQuestion?.content.useImage && resultQuestion.content.video && (
<YoutubeEmbedIframe <YoutubeEmbedIframe
videoUrl={resultQuestion.content.video} videoUrl={resultQuestion.content.video}
containerSX={{ containerSX={{
width: "490px", width: isMobile ? "100%" : "490px",
height: "280px", height: isMobile ? "100%" : "280px",
}} }}
/> />
)} )}
@ -75,10 +100,10 @@ export const ResultForm = ({
component="img" component="img"
src={resultQuestion.content.back} src={resultQuestion.content.back}
sx={{ sx={{
width: "490px", width: isMobile ? "100%" : "490px",
height: "280px", height: isMobile ? "100%" : "280px",
}} }}
></Box> />
)} )}
{resultQuestion.description !== "" && {resultQuestion.description !== "" &&
resultQuestion.description !== " " && ( resultQuestion.description !== " " && (
@ -87,6 +112,7 @@ export const ResultForm = ({
fontSize: "23px", fontSize: "23px",
fontWeight: 700, fontWeight: 700,
m: "20px 0", m: "20px 0",
color: theme.palette.text.primary,
}} }}
> >
{resultQuestion.description} {resultQuestion.description}
@ -97,6 +123,7 @@ export const ResultForm = ({
<Typography <Typography
sx={{ sx={{
m: "20px 0", m: "20px 0",
color: theme.palette.text.primary,
}} }}
> >
{resultQuestion.title} {resultQuestion.title}
@ -109,6 +136,7 @@ export const ResultForm = ({
sx={{ sx={{
fontSize: "18px", fontSize: "18px",
m: "20px 0", m: "20px 0",
color: theme.palette.text.primary,
}} }}
> >
{resultQuestion.content.text} {resultQuestion.content.text}
@ -130,9 +158,15 @@ export const ResultForm = ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
mt: "15px", mt: "15px",
gap: "10px",
}} }}
> >
<NameplateLogo style={{ fontSize: "34px" }} /> <NameplateLogo
style={{
fontSize: "34px",
color: mode[quiz.config.theme] ? "#000000" : "#F5F7FF",
}}
/>
<Typography <Typography
sx={{ sx={{
fontSize: "20px", fontSize: "20px",

@ -26,6 +26,7 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
const mode = modes; const mode = modes;
const { isMobileDevice } = useUADevice(); const { isMobileDevice } = useUADevice();
const isMobile = useMediaQuery(theme.breakpoints.down(650)); const isMobile = useMediaQuery(theme.breakpoints.down(650));
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
if (!quiz) return null; if (!quiz) return null;
@ -100,7 +101,6 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
? "linear-gradient(180deg,transparent,#272626)" ? "linear-gradient(180deg,transparent,#272626)"
: "linear-gradient(270deg,#272626,transparent)" : "linear-gradient(270deg,#272626,transparent)"
: theme.palette.background.default, : theme.palette.background.default,
color: quiz.config.startpageType === "expanded" ? "white" : "black", color: quiz.config.startpageType === "expanded" ? "white" : "black",
}} }}
> >
@ -197,6 +197,10 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
quiz.config.startpageType === "centered" quiz.config.startpageType === "centered"
? "center" ? "center"
: "-moz-initial", : "-moz-initial",
color:
quiz.config.startpageType === "expanded" && !isMobile
? "white"
: theme.palette.text.primary,
}} }}
> >
{quiz.config.startpage.description} {quiz.config.startpage.description}
@ -229,10 +233,10 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
sx={{ sx={{
mt: "46px", mt: "46px",
display: "flex", display: "flex",
alignItems: "center", alignItems: isTablet ? "start" : "center",
justifyContent: "space-between", justifyContent: "space-between",
width: "100%", width: "100%",
flexDirection: isMobile ? "column" : "row", flexDirection: isTablet ? "column" : "row",
}} }}
> >
<Box sx={{ maxWidth: "300px" }}> <Box sx={{ maxWidth: "300px" }}>
@ -272,7 +276,11 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
width: "100%", width: "100%",
overflowWrap: "break-word", overflowWrap: "break-word",
fontSize: "12px", fontSize: "12px",
textAlign: "end", textAlign: isTablet ? "start" : "end",
color:
quiz.config.startpageType === "expanded" && !isMobile
? "white"
: theme.palette.text.primary,
}} }}
> >
{quiz.config.info.law} {quiz.config.info.law}

@ -9,6 +9,7 @@ import {
Checkbox, Checkbox,
TextField, TextField,
useTheme, useTheme,
useMediaQuery,
} from "@mui/material"; } from "@mui/material";
import { import {
@ -43,6 +44,7 @@ type VariantItemProps = {
export const Variant = ({ currentQuestion }: VariantProps) => { export const Variant = ({ currentQuestion }: VariantProps) => {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const { answers, ownVariants } = useQuizViewStore(); const { answers, ownVariants } = useQuizViewStore();
const { answer } = const { answer } =
answers.find( answers.find(
@ -65,7 +67,13 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
<Typography variant="h5" color={theme.palette.text.primary}> <Typography variant="h5" color={theme.palette.text.primary}>
{currentQuestion.title} {currentQuestion.title}
</Typography> </Typography>
<Box sx={{ display: "flex" }}> <Box
sx={{
display: "flex",
gap: "20px",
flexDirection: isMobile ? "column-reverse" : undefined,
}}
>
<Group <Group
name={currentQuestion.id} name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex( value={currentQuestion.content.variants.findIndex(

@ -234,7 +234,7 @@ export default function Main({ sidebar, header, footer, Page }: Props) {
<LinkSimple /> <LinkSimple />
</Box> </Box>
)} )}
{currentStep === 1 && ( {currentStep <= 1 && (
<Box sx={{ textAlign: "end", width: "100%" }}> <Box sx={{ textAlign: "end", width: "100%" }}>
<IconButton <IconButton
onClick={toggleQuizPreview} onClick={toggleQuizPreview}

@ -54,13 +54,12 @@ export default function EditPage({
const { editQuizId } = useQuizStore(); const { editQuizId } = useQuizStore();
const { questions } = useQuestionsStore(); const { questions } = useQuestionsStore();
console.log(questions); console.log(questions);
const { whyCantCreatePublic, showConfirmLeaveModal } = useUiTools(); const { whyCantCreatePublic, showConfirmLeaveModal, nextStep } = useUiTools();
const theme = useTheme(); const theme = useTheme();
const navigate = useNavigate(); const navigate = useNavigate();
const currentStep = useQuizStore((state) => state.currentStep); const currentStep = useQuizStore((state) => state.currentStep);
const isBranchingLogic = useMediaQuery(theme.breakpoints.down(1100)); const isBranchingLogic = useMediaQuery(theme.breakpoints.down(1100));
const isMobile = useMediaQuery(theme.breakpoints.down(660)); const isMobile = useMediaQuery(theme.breakpoints.down(660));
const [nextStep, setNextStep] = useState<number>(0);
const quizConfig = quiz?.config; const quizConfig = quiz?.config;
// const [openBranchingPage, setOpenBranchingPage] = useState<boolean>(false); // const [openBranchingPage, setOpenBranchingPage] = useState<boolean>(false);

@ -40,3 +40,6 @@ export const setShowConfirmLeaveModal = (showConfirmLeaveModal: boolean) =>
export const updateSomeWorkBackend = (someWorkBackend: boolean) => export const updateSomeWorkBackend = (someWorkBackend: boolean) =>
useUiTools.setState({ someWorkBackend }); useUiTools.setState({ someWorkBackend });
export const updateNextStep = (nextStep: number) =>
useUiTools.setState({ nextStep });

@ -12,6 +12,7 @@ export type UiTools = {
deleteNodeId: string | null; deleteNodeId: string | null;
showConfirmLeaveModal: boolean; showConfirmLeaveModal: boolean;
someWorkBackend: boolean; someWorkBackend: boolean;
nextStep: number
}; };
export type WhyCantCreatePublic = { export type WhyCantCreatePublic = {
@ -30,6 +31,7 @@ const initialState: UiTools = {
deleteNodeId: null, deleteNodeId: null,
showConfirmLeaveModal: false, showConfirmLeaveModal: false,
someWorkBackend: false, someWorkBackend: false,
nextStep: -1
}; };
export const useUiTools = create<UiTools>()( export const useUiTools = create<UiTools>()(

@ -131,7 +131,6 @@ export const Header = ({ setMobileSidebar }: HeaderProps) => {
/> />
) : ( ) : (
<> <>
<ToTariffsButton />
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -139,6 +138,7 @@ export const Header = ({ setMobileSidebar }: HeaderProps) => {
gap: "15px", gap: "15px",
}} }}
> >
<ToTariffsButton color={"#7e2aea"} />
<LogoutButton onClick={handleLogoutClick} /> <LogoutButton onClick={handleLogoutClick} />
</Box> </Box>
</> </>

@ -58,7 +58,7 @@ export default function HeaderFull() {
<Logotip width={124} /> <Logotip width={124} />
</Link> </Link>
<Box sx={{ display: "flex", ml: "auto" }}> <Box sx={{ display: "flex", ml: "auto" }}>
<ToTariffsButton /> <ToTariffsButton color={"#7e2aea"} />
<LogoutButton <LogoutButton
onClick={handleLogoutClick} onClick={handleLogoutClick}
sx={{ sx={{

@ -11,6 +11,7 @@ import MenuItem from "../MenuItem";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import { setCurrentStep } from "@root/quizes/actions"; import { setCurrentStep } from "@root/quizes/actions";
import { updateNextStep } from "@root/uiTools/actions";
const quizSettingsMenuItems = [ const quizSettingsMenuItems = [
[TagIcon, "Дополнения"], [TagIcon, "Дополнения"],
@ -37,6 +38,7 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) {
navigate("/edit"); navigate("/edit");
} }
updateNextStep(index)
changePage(index); changePage(index);
}; };
@ -106,9 +108,9 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) {
key={index} key={index}
text={menuItem.sidebarText} text={menuItem.sidebarText}
isCollapsed={isMenuCollapsed} isCollapsed={isMenuCollapsed}
isActive={currentStep === index} isActive={currentStep === index && pathname.startsWith("/edit")}
disabled={ disabled={
index === 0 pathname.startsWith("/edit")
? false ? false
: quiz === undefined : quiz === undefined
? true ? true
@ -117,7 +119,7 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) {
icon={ icon={
<Icon <Icon
color={ color={
currentStep === index currentStep === index && pathname.startsWith("/edit")
? theme.palette.brightPurple.main ? theme.palette.brightPurple.main
: isMenuCollapsed : isMenuCollapsed
? "white" ? "white"
@ -154,9 +156,9 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) {
}} }}
text={"Дизайн"} text={"Дизайн"}
isCollapsed={isMenuCollapsed} isCollapsed={isMenuCollapsed}
isActive={currentStep === 6} isActive={pathname.startsWith("/design")}
disabled={ disabled={
currentStep === 6 pathname.startsWith("/design")
? false ? false
: quiz === undefined : quiz === undefined
? true ? true
@ -165,7 +167,7 @@ export default function Sidebar({ changePage, disableCollapse }: SidebarProps) {
icon={ icon={
<PencilCircleIcon <PencilCircleIcon
color={ color={
currentStep === 6 pathname.startsWith("/design")
? theme.palette.brightPurple.main ? theme.palette.brightPurple.main
: isMenuCollapsed : isMenuCollapsed
? "white" ? "white"

@ -123,6 +123,7 @@ export const StartPagePreview = () => {
overflow: "hidden", overflow: "hidden",
pointerEvents: "auto", pointerEvents: "auto",
borderRadius: "5px", borderRadius: "5px",
boxShadow: "0px 5px 10px 2px rgba(34, 60, 80, 0.2)",
}} }}
> >
<QuizPreviewLayout /> <QuizPreviewLayout />