добавлены темы

This commit is contained in:
Nastya 2023-12-29 03:58:19 +03:00
parent 3a1c519919
commit 1eda324705
30 changed files with 1236 additions and 551 deletions

@ -2,7 +2,7 @@ import { makeRequest } from "@frontend/kitui";
export function getData(quizId: string) {
return makeRequest<any>({
url: `https://squiz.pena.digital/answer/settings`,
url: `https://hbpn.link/answer/settings`,
body: {
quiz_id: quizId,
limit: 100,
@ -25,7 +25,7 @@ export function sendAnswer({ questionId, body, qid }: any) {
formData.append("qid", qid);
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
url: `https://hbpn.link/answer/answer`,
body: formData,
method: "POST",
});
@ -47,7 +47,7 @@ export function sendFile({ questionId, body, qid }: any) {
formData.append("qid", qid);
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
url: `https://hbpn.link/answer/answer`,
body: formData,
method: "POST",
});
@ -91,8 +91,8 @@ export function sendFC({ questionId, body, qid }: any) {
formData.append("qid", qid);
return makeRequest<FormData, { [key: string]: string; }>({
url: `https://squiz.pena.digital/answer/answer`,
url: `https://hbpn.link/answer/answer`,
body: formData,
method: "POST",
});
}
}

@ -1,7 +1,12 @@
import { Box, useTheme } from "@mui/material";
import {Box, SxProps, Theme, useTheme} from "@mui/material";
export default function ArrowDownIcon(props: any) {
interface Color{
color?: string
}
export default function ArrowDownIcon(
props: any,
{color = "#7E2AEA"}: Color
) {
const theme = useTheme();
return (
@ -17,7 +22,7 @@ export default function ArrowDownIcon(props: any) {
}}
>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M19.5 9L12 16.5L4.5 9" stroke={theme.palette.brightPurple.main} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
<path d="M19.5 9L12 16.5L4.5 9" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</Box>
);

@ -2,9 +2,10 @@ import { Box, useTheme } from "@mui/material";
type CheckboxIconProps = {
checked?: boolean;
color?: string;
};
export const CheckboxIcon = ({ checked = false }: CheckboxIconProps) => {
export const CheckboxIcon = ({ checked = false, color = "#7E2AEA", }: CheckboxIconProps) => {
const theme = useTheme();
return (
@ -17,9 +18,9 @@ export const CheckboxIcon = ({ checked = false }: CheckboxIconProps) => {
justifyContent: "center",
alignItems: "center",
backgroundColor: checked
? theme.palette.brightPurple.main
: theme.palette.background.default,
border: `1px solid ${theme.palette.grey2.main}`,
? color
: "#F2F3F7",
border: `1px solid #9A9AAF`,
}}
>
{checked && (

File diff suppressed because one or more lines are too long

@ -1,7 +1,10 @@
import { Box, useTheme } from "@mui/material";
interface Props{
color?: string
}
export default function UploadIcon() {
export default function UploadIcon({color= "#9A9AAF"}: Props) {
const theme = useTheme();
return (
@ -15,9 +18,9 @@ export default function UploadIcon() {
}}
>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M10.75 10.25L16 5L21.25 10.25" stroke={theme.palette.grey2.main} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M16 19V5" stroke={theme.palette.grey2.main} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M27 19V26C27 26.2652 26.8946 26.5196 26.7071 26.7071C26.5196 26.8946 26.2652 27 26 27H6C5.73478 27 5.48043 26.8946 5.29289 26.7071C5.10536 26.5196 5 26.2652 5 26V19" stroke={theme.palette.grey2.main} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M10.75 10.25L16 5L21.25 10.25" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M16 19V5" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M27 19V26C27 26.2652 26.8946 26.5196 26.7071 26.7071C26.5196 26.8946 26.2652 27 26 27H6C5.73478 27 5.48043 26.8946 5.29289 26.7071C5.10536 26.5196 5 26.2652 5 26V19" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</Box>
);

@ -33,6 +33,7 @@ export interface QuizConfig {
startpageType: QuizStartpageType;
results: QuizResultsType;
haveRoot: string | null;
theme: "StandardTheme" | "StandardDarkTheme" | "PinkTheme" | "PinkDarkTheme" | "BlackWhiteTheme" | "OliveTheme" | "YellowTheme" | "GoldDarkTheme" | "PurpleTheme" | "BlueTheme" | "BlueDarkTheme";
resultInfo: {
when: 'before' | 'after' | 'email',
share: true | false,
@ -92,6 +93,7 @@ export const defaultQuizConfig: QuizConfig = {
startpageType: null,
results: null,
haveRoot: null,
theme: "StandardTheme",
resultInfo: {
when: 'after',
share: false,

@ -59,6 +59,7 @@ export interface QuizConfig {
startpageType: QuizStartpageType;
results: QuizResultsType;
haveRoot: string;
theme: "StandardTheme" | "StandardDarkTheme" | "PinkTheme" | "PinkDarkTheme" | "BlackWhiteTheme" | "OliveTheme" | "YellowTheme" | "GoldDarkTheme" | "PurpleTheme" | "BlueTheme" | "BlueDarkTheme";
resultInfo: {
when: QuizResultInfoWhen;
share: boolean;

@ -1,4 +1,4 @@
import { Box, Typography, Button, Paper, TextField, Link, InputAdornment } from "@mui/material";
import { Box, Typography, Button, Paper, TextField, Link, InputAdornment, useTheme } from "@mui/material";
import NameIcon from "@icons/ContactFormIcon/NameIcon";
import EmailIcon from "@icons/ContactFormIcon/EmailIcon";
import PhoneIcon from "@icons/ContactFormIcon/PhoneIcon";
@ -15,9 +15,10 @@ import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
import { enqueueSnackbar } from "notistack";
import { sendFC } from "@api/quizRelase";
import { NameplateLogo } from "@icons/NameplateLogo";
import {modes} from "../../utils/themes/Publication/themePublication";
type ContactFormProps = {
currentQuestion: AnyTypedQuizQuestion;
currentQuestion: any;
showResultForm: boolean;
setShowContactForm: (show: boolean) => void;
setShowResultForm: (show: boolean) => void;
@ -50,7 +51,9 @@ export const ContactForm = ({
setShowContactForm(false);
setShowResultForm(true);
};
const theme = useTheme();
const mode = modes;
//@ts-ignore
const resultQuestion = items.find((question) => {
if (settings?.cfg.haveRoot) { //ветвимся
return (
@ -104,6 +107,7 @@ export const ContactForm = ({
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.palette.background.default,
height: "100vh"
}}
>
@ -118,7 +122,8 @@ export const ContactForm = ({
sx={{
textAlign: "center",
m: "20px 0",
fontSize: "28px"
fontSize: "28px",
color: theme.palette.text.primary
}}
>
{settings?.cfg.formContact.title || "Заполните форму, чтобы получить результаты теста"}
@ -145,6 +150,7 @@ export const ContactForm = ({
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
backgroundColor: theme.palette.background.default,
p: "30px"
}}>
@ -155,17 +161,13 @@ export const ContactForm = ({
my: "20px"
}}
>
<Inputs
name={name} setName={setName}
email={email} setEmail={setEmail}
phone={phone} setPhone={setPhone}
text={text} setText={setText}
adress={adress} setAdress={setAdress}
/>
<Inputs />
</Box>
{
// resultQuestion &&
// settings?.cfg.resultInfo.when === "after" &&
(
<Button
disabled={!ready}
@ -187,8 +189,9 @@ export const ContactForm = ({
enqueueSnackbar("повторите попытку позже")
}
}
}}>
{settings.cfg.formContact?.button || "Получить результаты"}
}}
>
{settings?.cfg.formContact?.button || "Получить результаты"}
</Button>
)}
@ -199,28 +202,33 @@ export const ContactForm = ({
width: "450px",
}}
>
<CustomCheckbox label="" handleChange={({ target }) => { setReady(target.checked) }} checked={ready} />
<CustomCheckbox label="" handleChange={({ target }) => { setReady(target.checked) }} checked={ready} colorIcon={theme.palette.primary.main}/>
<Typography>
С
<Link> Положением об обработке персональных данных </Link>
и
<Link> Политикой конфиденциальности </Link>
ознакомлен
С&ensp;
<Link> Положением об обработке персональных данных </Link>
&ensp;и&ensp;
<Link> Политикой конфиденциальности </Link>
&ensp;ознакомлен
</Typography>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
mt: "20px"
mt: "20px",
gap: "15px"
}}
>
<NameplateLogo style={{ fontSize: "34px" }} />
<Typography sx={{ fontSize: "20px", color: "#4D4D4D", whiteSpace: "nowrap" }}>Сделано на PenaQuiz</Typography>
<NameplateLogo style={{ fontSize: "34px",
//@ts-ignore
color: mode[settings.cfg.theme] ? "#151515" : "#FFFFFF" }} />
<Typography sx={{ fontSize: "20px",
//@ts-ignore
color: mode[settings.cfg.theme] ? "#4D4D4D" : "#F5F7FF", whiteSpace: "nowrap" }}>
Сделано на Penasettings
</Typography>
</Box>
</Paper>
</Box >
</Box >

@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
import { Box, Button, Typography, useTheme } from "@mui/material";
import { Box, Button, Typography, useMediaQuery, useTheme } from "@mui/material";
import type { AnyTypedQuizQuestion, QuizQuestionBase } from "../../model/questionTypes/shared";
import { useQuestionsStore } from "@root/quizData/store";
@ -7,6 +7,9 @@ import { getQuestionById } from "@root/quizData/actions";
import { useQuizViewStore } from "@root/quizView/store";
import { enqueueSnackbar } from "notistack";
import { NameplateLogoFQ } from "@icons/NameplateLogoFQ";
import { NameplateLogoFQDark } from "@icons/NameplateLogoFQDark";
import { modes } from "../../utils/themes/Publication/themePublication";
import { checkEmptyData } from "./tools/checkEmptyData";
type FooterProps = {
@ -22,10 +25,13 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
const { settings, items } = useQuestionsStore();
const { answers } = useQuizViewStore();
const mode = modes;
const [stepNumber, setStepNumber] = useState(1);
const [disablePreviousButton, setDisablePreviousButton] = useState<boolean>(false);
const [disableNextButton, setDisableNextButton] = useState<boolean>(false);
const isMobileMini = useMediaQuery(theme.breakpoints.down(382));
const linear = !items.find(({ content }) => content.rule.parentId === "root");
useEffect(() => {
@ -86,24 +92,24 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
}
const isEmpty = checkEmptyData({ resultData: nextQuestion })
if (nextQuestion) {
if (nextQuestion && settings?.cfg.resultInfo.when === "before") {
if (isEmpty) {
setShowContactForm(true); //до+пустая = кидать на ФК
} else {
setShowResultForm(true); //до+заполнена = показать
}
}
if (nextQuestion && settings?.cfg.resultInfo.when === "after") {
if (isEmpty) {
setShowContactForm(true); //после+пустая
} else {
setShowContactForm(true); //после+заполнена = показать ФК
}
}
}
@ -111,10 +117,14 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
};
const getNextQuestionId = () => {
console.log("net")
console.log(question)
let readyBeNextQuestion = "";
//вопрос обязателен, анализируем ответ и условия ветвления
if (answers.length) {
const answer = answers.find(({ questionId }) => questionId === question.id);
let readyBeNextQuestion = "";
(question as QuizQuestionBase).content.rule.main.forEach(({ next, rules }) => {
let longerArray = Math.max(
@ -141,10 +151,35 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
}
});
return readyBeNextQuestion;
if (readyBeNextQuestion) return readyBeNextQuestion;
}
if (!question.required) {//вопрос не обязателен и не нашли совпадений между ответами и условиями ветвления
console.log("вопрос не обязателен ищем дальше")
const defaultQ = question.content.rule.default
if (defaultQ) return defaultQ
//Вопросы типа страница, ползунок, своё поле для ввода и дата не могут иметь больше 1 ребёнка. Пользователь не может настроить там дефолт
//Кинуть на ребёнка надо даже если там нет дефолта
if (
(question?.type === "date" ||
question?.type === "text" ||
question?.type === "number" ||
question?.type === "page") && question.content.rule.children.length === 1
) return question.content.rule.children[0]
}
//ничё не нашли, ищем резулт
console.log("ничё не нашли, ищем резулт ")
return items.find(q => {
console.log('q.type === "result"', q.type === "result")
console.log('q.content.rule.parentId === question.content.id', q.content.rule.parentId === question.id)
return q.type === "result" && q.content.rule.parentId === question.id
})?.id
};
const followPreviousStep = () => {
if (linear) {
setStepNumber(q => q - 1)
@ -192,21 +227,18 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
if (nextQuestionId) {
const nextQuestion = getQuestionById(nextQuestionId);
console.log(nextQuestion)
if (nextQuestion?.type && nextQuestion.type !== "result") {
setCurrentQuestion(nextQuestion);
return;
if (nextQuestion?.type && nextQuestion.type === "result") {
showResult(nextQuestion);
} else {
enqueueSnackbar("не могу получить последующий вопрос");
//@ts-ignore
setCurrentQuestion(nextQuestion);
}
} else {
const nextQuestion = getQuestionById(question.content.rule.default);
if (nextQuestion?.type && nextQuestion.type !== "result") {
setCurrentQuestion(nextQuestion);
} else {
showResult(nextQuestion);
}
enqueueSnackbar("не могу получить последующий вопрос");
}
};
return (
@ -216,6 +248,7 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
padding: "15px 0",
borderTop: `1px solid ${theme.palette.grey[400]}`,
height: '75px',
display: "flex"
}}
>
@ -230,7 +263,11 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
gap: "10px",
}}
>
<NameplateLogoFQ style={{ fontSize: "34px", width: "200px", height: "auto" }} />
{/*{mode[settings.cfg.theme] ? (*/}
{/* <NameplateLogoFQ style={{ fontSize: "34px", width:"200px", height:"auto" }} />*/}
{/*):(*/}
{/* <NameplateLogoFQDark style={{ fontSize: "34px", width:"200px", height:"auto" }} />*/}
{/*)}*/}
{linear &&
<>
<Box
@ -239,7 +276,7 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
alignItems: "center",
gap: "10px",
marginRight: "auto",
color: theme.palette.grey1.main,
color: theme.palette.text.primary,
}}
>
<Typography>Шаг</Typography>
@ -253,7 +290,7 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
width: "30px",
height: "30px",
color: "#FFF",
background: theme.palette.brightPurple.main,
background: theme.palette.primary.main,
}}
>
{stepNumber}
@ -272,17 +309,43 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
alignItems: "center",
gap: "10px",
marginRight: "auto",
color: theme.palette.grey1.main,
// color: theme.palette.grey1.main,
}}
>
{/* <Typography>Шаг</Typography>
<Typography
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
fontWeight: "bold",
borderRadius: "50%",
width: "30px",
height: "30px",
color: "#FFF",
background: theme.palette.brightPurple.main,
}}
>
{stepNumber} */}
{/* </Typography> */}
{/* <Typography>Из</Typography>
<Typography sx={{ fontWeight: "bold" }}>
{questions.length}
</Typography> */}
</Box>
<Button
disabled={disablePreviousButton}
variant="contained"
sx={{ fontSize: "16px", padding: "10px 15px" }}
sx={{ fontSize: "16px", padding: "10px 15px",}}
onClick={followPreviousStep}
>
Назад
{isMobileMini ? (
"←"
) : (
"← Назад"
)}
</Button>
<Button
disabled={disableNextButton}
@ -295,4 +358,5 @@ export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setSh
</Box>
</Box>
);
};

@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
import { Box } from "@mui/material";
import { Box, useTheme } from "@mui/material";
import { useQuestionsStore } from "@root/quizData/store"
import { getQuestionById } from "@root/quizData/actions";
@ -22,6 +22,10 @@ import { ResultForm } from "./ResultForm";
import type { QuestionType } from "@model/questionTypes/shared";
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
import {NameplateLogoFQ} from "@icons/NameplateLogoFQ";
import {NameplateLogoFQDark} from "@icons/NameplateLogoFQDark";
import {modes} from "../../utils/themes/Publication/themePublication";
type QuestionProps = {
questions: AnyTypedQuizQuestion[];
};
@ -41,11 +45,12 @@ const QUESTIONS_MAP: any = {
};
export const Question = ({ questions }: QuestionProps) => {
const { settings, cnt, items } = useQuestionsStore()
const { settings } = useQuestionsStore()
const [currentQuestion, setCurrentQuestion] = useState<AnyTypedQuizQuestion>();
const [showContactForm, setShowContactForm] = useState<boolean>(false);
const [showResultForm, setShowResultForm] = useState<boolean>(false);
const mode = modes;
console.log("currentQuestion ", currentQuestion)
useEffect(() => {
if (settings?.cfg.haveRoot) {//ветвимся
@ -66,22 +71,35 @@ export const Question = ({ questions }: QuestionProps) => {
const QuestionComponent =
QUESTIONS_MAP[currentQuestion.type as Exclude<QuestionType, "nonselected">];
const theme = useTheme();
return (
<Box
sx={{
backgroundColor: theme.palette.background.default
}}
height="100vh"
>
{!showContactForm && !showResultForm && (
<Box
sx={{
minHeight: "calc(100vh - 75px)",
height: "calc(100vh - 75px)",
width: "100%",
maxWidth: "1440px",
padding: "40px 25px 20px",
margin: "0 auto",
overflow: "auto",
display: "flex",
flexDirection: "column",
justifyContent: "space-between"
}}
>
<QuestionComponent currentQuestion={currentQuestion} />
{mode[settings?.cfg.theme] ? (
<NameplateLogoFQ style={{ fontSize: "34px", width: "200px", height: "auto" }} />
) : (
<NameplateLogoFQDark style={{ fontSize: "34px", width: "200px", height: "auto" }} />
)}
</Box>
)}
{showResultForm && settings?.cfg.resultInfo.when === "before" && (
@ -118,4 +136,5 @@ export const Question = ({ questions }: QuestionProps) => {
)}
</Box>
);
};

@ -5,6 +5,7 @@ import { useQuestionsStore } from "@root/quizData/store"
import type { QuizQuestionResult } from "@model/questionTypes/result";
import YoutubeEmbedIframe from "./tools/YoutubeEmbedIframe"
import { NameplateLogo } from "@icons/NameplateLogo";
import { modes } from "../../utils/themes/Publication/themePublication";
type ResultFormProps = {
currentQuestion: any;
@ -21,11 +22,17 @@ export const ResultForm = ({
}: ResultFormProps) => {
const { settings, items } = useQuestionsStore()
const resultQuestion = items.find(
const resultQuestion = (items.find(
(question) =>
question.type === "result" &&
(question.content.rule.parentId === "line" || currentQuestion.id)
);
)) ||
items.find(
(question) =>
question.type === "result" && question.content.rule.parentId === "line"
)
const mode = modes;
const followNextForm = () => {
setShowResultForm(false);
@ -48,10 +55,9 @@ export const ResultForm = ({
justifyContent: "space-between",
height: "100vh",
width: "100vw",
pt: "28px"
pt: "28px",
}}
>
<Box
sx={{
display: "flex",
@ -62,57 +68,65 @@ export const ResultForm = ({
>
{
//@ts-ignore
!resultQuestion?.content.useImage &&
//@ts-ignore
resultQuestion.content.video &&
<YoutubeEmbedIframe
//@ts-ignore
videoUrl={resultQuestion.content.video}
containerSX={{
width: "490px",
height: "280px"
}}
/>
}
!resultQuestion?.content.useImage && resultQuestion.content.video && (
<YoutubeEmbedIframe
//@ts-ignore
videoUrl={resultQuestion.content.video}
containerSX={{
width: "490px",
height: "280px",
}}
/>
)}
{
//@ts-ignore
resultQuestion?.content.useImage &&
resultQuestion.content.back &&
<Box
component='img'
src={resultQuestion.content.back}
sx={{
width: "490px",
height: "280px"
}}
>
</Box>
}
{resultQuestion.description !== "" && resultQuestion.description !== " " && <Typography
sx={{
fontSize: "23px",
fontWeight: 700,
m: "20px 0"
}}
>{resultQuestion.description}</Typography>}
resultQuestion?.content.useImage && resultQuestion.content.back && (
<Box
component="img"
src={resultQuestion.content.back}
sx={{
width: "490px",
height: "280px",
}}
></Box>
)}
{resultQuestion.description !== "" &&
resultQuestion.description !== " " && (
<Typography
sx={{
fontSize: "23px",
fontWeight: 700,
m: "20px 0",
}}
>
{resultQuestion.description}
</Typography>
)}
<Typography
sx={{
m: "20px 0"
m: "20px 0",
}}
>{resultQuestion.title || "Форма результатов"}
>
{resultQuestion.title || "Форма результатов"}
</Typography>
{
//@ts-ignore
resultQuestion.content.text !== "" && resultQuestion.content.text !== " " && <Typography
sx={{
fontSize: "18px",
m: "20px 0"
}}
>{
resultQuestion.content.text !== "" &&
//@ts-ignore
resultQuestion.content.text}</Typography>}
resultQuestion.content.text !== " " && (
<Typography
sx={{
fontSize: "18px",
m: "20px 0",
}}
>
{
//@ts-ignore
resultQuestion.content.text}
</Typography>
)}
</Box>
<Box width="100%">
@ -121,50 +135,60 @@ export const ResultForm = ({
display: "flex",
width: "100%",
justifyContent: "end",
px: "20px"
px: "20px",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
mt: "15px"
mt: "15px",
}}
>
<NameplateLogo style={{ fontSize: "34px" }} />
<Typography sx={{ fontSize: "20px", color: "#4D4D4D", whiteSpace: "nowrap" }}>Сделано на PenaQuiz</Typography>
</Box>
</Box>
{
settings?.cfg.resultInfo.when === "before" &&
<Box
sx={{
height: "100px",
boxShadow: "0 0 15px 0 rgba(0,0,0,.08)",
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
<Button
onClick={followNextForm}
variant="contained"
<Typography
sx={{
p: "10px 20px",
width: "210px",
height: "50px"
fontSize: "20px",
//@ts-ignore
color: mode[settings.cfg.theme] ? "#4D4D4D" : "#F5F7FF",
whiteSpace: "nowrap",
}}
>
{resultQuestion.content.hint.text || "Узнать подробнее"}
</Button>
Сделано на PenaQuiz
</Typography>
</Box>
}
</Box>
{settings?.cfg.resultInfo.when === "before" && (
<>
<Box
sx={{
boxShadow: "0 0 15px 0 rgba(0,0,0,.08)",
width: "100%",
flexDirection: "column",
display: "flex",
justifyContent: "center",
alignItems: "center",
p: "20px",
}}
>
<Button
onClick={followNextForm}
variant="contained"
sx={{
p: "10px 20px",
width: "210px",
height: "50px",
}}
>
{resultQuestion.content.hint.text || "Узнать подробнее"}
</Button>
</Box>
</>
)}
</Box>
</Box>
);
}
};

@ -5,6 +5,8 @@ import { notReachable } from "../../utils/notReachable";
import { useUADevice } from "../../utils/hooks/useUADevice";
import { useQuestionsStore } from "@root/quizData/store";
import { NameplateLogo } from "@icons/NameplateLogo";
import {modes} from "../../utils/themes/Publication/themePublication";
interface Props {
setVisualStartPage: (a: boolean) => void;
@ -12,21 +14,24 @@ interface Props {
export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
const theme = useTheme();
const { settings } = useQuestionsStore()
const mode = modes;
const { isMobileDevice } = useUADevice();
const { settings } = useQuestionsStore();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
if (!settings) return null;
console.log(settings);
const handleCopyNumber = () => {
navigator.clipboard.writeText(settings?.cfg.info.phonenumber);
navigator.clipboard.writeText(settings.cfg.info.phonenumber);
};
const background =
settings?.cfg.startpage.background.type === "image" ? (
settings?.cfg.startpage.background.desktop ? (
settings.cfg.startpage.background.type === "image" ? (
settings.cfg.startpage.background.desktop ? (
<img
src={settings?.cfg.startpage.background.desktop}
src={settings.cfg.startpage.background.desktop}
alt=""
style={{
width: "100%",
@ -36,32 +41,32 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
}}
/>
) : null
) : settings?.cfg.startpage.background.type === "video" ? (
settings?.cfg.startpage.background.video ? (
) : settings.cfg.startpage.background.type === "video" ? (
settings.cfg.startpage.background.video ? (
<YoutubeEmbedIframe
videoUrl={settings?.cfg.startpage.background.video}
videoUrl={settings.cfg.startpage.background.video}
containerSX={{
width:
settings?.cfg.startpageType === "centered"
settings.cfg.startpageType === "centered"
? "550px"
: settings?.cfg.startpageType === "expanded"
: settings.cfg.startpageType === "expanded"
? "100vw"
: "100%",
height:
settings?.cfg.startpageType === "centered"
settings.cfg.startpageType === "centered"
? "275px"
: settings?.cfg.startpageType === "expanded"
: settings.cfg.startpageType === "expanded"
? "100vh"
: "100%",
borderRadius: settings?.cfg.startpageType === "centered" ? "10px" : "0",
borderRadius: settings.cfg.startpageType === "centered" ? "10px" : "0",
overflow: "hidden",
"& iframe": {
width: "100%",
height: "100%",
transform:
settings?.cfg.startpageType === "centered"
settings.cfg.startpageType === "centered"
? ""
: settings?.cfg.startpageType === "expanded"
: settings.cfg.startpageType === "expanded"
? "scale(1.5)"
: "scale(2.4)",
},
@ -72,23 +77,25 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
return (
<Paper
className="quiz-preview-draghandle"
className="settings-preview-draghandle"
sx={{
height: "100vh",
background:
settings?.cfg.startpageType === "expanded"
? settings?.cfg.startpage.position === "left"
? "linear-gradient(90deg,#272626,transparent)"
: settings?.cfg.startpage.position === "center"
? "linear-gradient(180deg,transparent,#272626)"
: "linear-gradient(270deg,#272626,transparent)"
: "",
color: settings?.cfg.startpageType === "expanded" ? "white" : "black",
width: "100vw",
background:
settings.cfg.startpageType === "expanded" && !isMobile
? settings.cfg.startpage.position === "left"
? "linear-gradient(90deg,#272626,transparent)"
: settings.cfg.startpage.position === "center"
? "linear-gradient(180deg,transparent,#272626)"
: "linear-gradient(270deg,#272626,transparent)"
: theme.palette.background.default,
color: settings.cfg.startpageType === "expanded" ? "white" : "black",
}}
>
<QuizPreviewLayoutByType
quizHeaderBlock={
<Box p={settings?.cfg.startpageType === "standard" ? "" : "16px"}>
<Box p={settings.cfg.startpageType === "standard" ? "" : "16px"}>
<Box
sx={{
display: "flex",
@ -97,9 +104,9 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
mb: "7px",
}}
>
{settings?.cfg.startpage.logo && (
{settings.cfg.startpage.logo && (
<img
src={settings?.cfg.startpage.logo}
src={settings.cfg.startpage.logo}
style={{
height: "37px",
maxWidth: "43px",
@ -108,11 +115,11 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
alt=""
/>
)}
<Typography sx={{ fontSize: "14px" }}>{settings?.cfg.info.orgname}</Typography>
<Typography sx={{ fontSize: "14px", color: settings.cfg.startpageType === "expanded" && !isMobile ? "white" : theme.palette.text.primary}}>{settings.cfg.info.orgname}</Typography>
</Box>
<Link mb="16px" href={settings?.cfg.info.site}>
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{settings?.cfg.info.site}
<Link mb="16px" href={settings.cfg.info.site}>
<Typography sx={{ fontSize: "16px", color: theme.palette.primary.main }}>
{settings.cfg.info.site}
</Typography>
</Link>
</Box>
@ -125,10 +132,10 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
flexDirection: "column",
justifyContent: "center",
alignItems:
settings?.cfg.startpageType === "centered"
settings.cfg.startpageType === "centered"
? "center"
: settings?.cfg.startpageType === "expanded"
? settings?.cfg.startpage.position === "center"
: settings.cfg.startpageType === "expanded"
? settings.cfg.startpage.position === "center"
? "center"
: "start"
: "start",
@ -143,6 +150,10 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
fontStyle: "normal",
fontStretch: "normal",
lineHeight: "1.2",
overflowWrap: "break-word",
width: "100%",
textAlign: settings.cfg.startpageType === "centered" ? "center" : "-moz-initial",
color: settings.cfg.startpageType === "expanded" && !isMobile ? "white" : theme.palette.text.primary
}}
>
{settings.name}
@ -151,57 +162,72 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
sx={{
fontSize: "16px",
m: "16px 0",
overflowWrap: "break-word",
width: "100%",
textAlign: settings.cfg.startpageType === "centered" ? "center" : "-moz-initial",
}}
>
{settings?.cfg.startpage.description}
{settings.cfg.startpage.description}
</Typography>
<Box width={settings?.cfg.startpageType === "standard" ? "100%" : "auto"}>
<Box width={settings.cfg.startpageType === "standard" ? "100%" : "auto"}>
<Button
variant="contained"
sx={{
fontSize: "16px",
padding: "10px 15px",
width: settings?.cfg.startpageType === "standard" ? "100%" : "auto",
width: settings.cfg.startpageType === "standard" ? "100%" : "auto",
}}
onClick={() => setVisualStartPage(false)}
>
{settings?.cfg.startpage.button.trim() ? settings?.cfg.startpage.button : "Пройти тест"}
{settings.cfg.startpage.button.trim() ? settings.cfg.startpage.button : "Пройти тест"}
</Button>
</Box>
</Box>
<Box
sx={{ mt: "46px", display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%" }}
sx={{
mt: "46px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
flexDirection: isMobile ? "column" : "row"
}}
>
<Box>
{settings?.cfg.info.clickable ? (
<Box sx={{ maxWidth: "300px" }}>
{settings.cfg.info.clickable ? (
isMobileDevice ? (
<Link href={`tel:${settings?.cfg.info.phonenumber}`}>
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{settings?.cfg.info.phonenumber}
<Link href={`tel:${settings.cfg.info.phonenumber}`}>
<Typography sx={{ fontSize: "16px", color: theme.palette.primary.main }}>
{settings.cfg.info.phonenumber}
</Typography>
</Link>
) : (
<ButtonBase onClick={handleCopyNumber}>
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{settings?.cfg.info.phonenumber}
<Typography sx={{ fontSize: "16px", color: theme.palette.primary.main }}>
{settings.cfg.info.phonenumber}
</Typography>
</ButtonBase>
)
) : (
<Typography sx={{ fontSize: "16px", color: theme.palette.brightPurple.main }}>
{settings?.cfg.info.phonenumber}
<Typography sx={{ fontSize: "16px", color: theme.palette.primary.main }}>
{settings.cfg.info.phonenumber}
</Typography>
)}
<Typography sx={{ fontSize: "12px", textAlign: "end" }}>{settings?.cfg.info.law}</Typography>
<Typography sx={{ width: "100%", overflowWrap: "break-word", fontSize: "12px", textAlign: "end" }}>
{settings.cfg.info.law}
</Typography>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "15px"
}}
>
<NameplateLogo style={{ fontSize: "34px" }} />
<Typography sx={{ fontSize: "20px", color: "#4D4D4D", whiteSpace: "nowrap" }}>
<NameplateLogo style={{ fontSize: "34px", color: settings.cfg.startpageType === "expanded" && !isMobile ? "#FFFFFF" : (mode[settings.cfg.theme] ? "#151515" : "#FFFFFF") }} />
<Typography sx={{ fontSize: "20px", color: settings.cfg.startpageType === "expanded" && !isMobile ? "#F5F7FF" : (mode[settings.cfg.theme] ? "#4D4D4D" : "#F5F7FF"), whiteSpace: "nowrap", }}>
Сделано на PenaQuiz
</Typography>
</Box>
@ -209,13 +235,14 @@ export const StartPageViewPublication = ({ setVisualStartPage }: Props) => {
</>
}
backgroundBlock={background}
startpageType={settings?.cfg.startpageType}
alignType={settings?.cfg.startpage.position}
startpageType={settings.cfg.startpageType}
alignType={settings.cfg.startpage.position}
/>
</Paper>
);
};
function QuizPreviewLayoutByType({
quizHeaderBlock,
quizMainBlock,
@ -230,106 +257,191 @@ function QuizPreviewLayoutByType({
alignType: QuizStartpageAlignType;
}) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(630));
const isMobile = useMediaQuery(theme.breakpoints.down(650));
function StartPageMobile() {
return(
<Box
sx={{
display: "flex",
flexDirection: "column-reverse",
flexGrow: 1,
justifyContent: "flex-end",
height: "100vh",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: "flex-start",
p: "25px",
height: "80%"
}}
>
{quizHeaderBlock}
<Box
sx={{
height: "80%",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
width: "100%"
}}
>
{quizMainBlock}
</Box>
</Box>
<Box
sx={{
width: "100%",
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
</Box>
)
}
switch (startpageType) {
case null:
case "standard": {
return (
<Box
sx={{
display: "flex",
flexDirection: alignType === "left" ? "row" : "row-reverse",
flexGrow: 1,
height: "100vh",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: !isTablet ? "40%" : "100%",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: !isTablet ? "flex-start" : "center",
p: "25px",
}}
>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box
sx={{
width: "60%",
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
</Box>
<>
{isMobile ? (
<StartPageMobile/>
) : (
<Box
sx={{
display: "flex",
flexDirection: alignType === "left" ? (isMobile ? "column-reverse" : "row") : "row-reverse",
flexGrow: 1,
justifyContent: isMobile ? "flex-end" : undefined,
height: "100vh",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: isMobile ? "100%" : "40%",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: "flex-start",
p: "25px",
height: isMobile ? "80%" : undefined
}}
>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box
sx={{
width: isMobile ? "100%" : "60%",
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
</Box>
)}
</>
);
}
case "expanded": {
return (
<Box
sx={{
position: "relative",
display: "flex",
justifyContent: startpageAlignTypeToJustifyContent[alignType],
flexGrow: 1,
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: "40%",
position: "relative",
padding: "16px",
zIndex: 2,
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: alignType === "center" ? "center" : "start",
}}
>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box
sx={{
position: "absolute",
left: 0,
top: 0,
height: "100%",
width: "100%",
zIndex: 1,
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
</Box>
<>
{isMobile ? (
<StartPageMobile/>
) : (
<Box
sx={{
position: "relative",
display: "flex",
justifyContent: startpageAlignTypeToJustifyContent[alignType],
flexGrow: 1,
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
}}
>
<Box
sx={{
width: "40%",
position: "relative",
padding: "16px",
zIndex: 3,
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: alignType === "center" ? "center" : "start",
}}
>
{quizHeaderBlock}
{quizMainBlock}
</Box>
<Box
sx={{
position: "absolute",
zIndex: -1,
left: 0,
top: 0,
height: "100%",
width: "100%",
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
</Box>
)
}
</>
);
}
case "centered": {
return (
<Box
sx={{
padding: "16px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
overflow: "hidden",
}}
>
{quizHeaderBlock}
{backgroundBlock && <Box>{backgroundBlock}</Box>}
{quizMainBlock}
</Box>
<>
{isMobile ? (
<StartPageMobile/>
) : (
<Box
sx={{
padding: "16px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "100%",
"&::-webkit-scrollbar": { width: 0 },
overflow: "hidden",
}}
>
{quizHeaderBlock}
{backgroundBlock && (
<Box
sx={{
width: "60%",
overflow: "hidden",
}}
>
{backgroundBlock}
</Box>
)}
{quizMainBlock}
</Box>
)
}
</>
);
}
default:
@ -337,6 +449,7 @@ function QuizPreviewLayoutByType({
}
}
const startpageAlignTypeToJustifyContent: Record<QuizStartpageAlignType, "start" | "center" | "end"> = {
left: "start",
center: "center",

@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { Box, Skeleton } from "@mui/material";
import { Box, Skeleton, ThemeProvider } from "@mui/material";
import { StartPageViewPublication } from "./StartPageViewPublication";
import { Question } from "./Question";
@ -10,18 +10,22 @@ import { getData } from "@api/quizRelase"
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { useGetSettings } from "../../utils/hooks/useGetSettings";
import { themesPublication } from "../../utils/themes/Publication/themePublication";
import { replaceSpacesToEmptyLines } from "./tools/replaceSpacesToEmptyLines";
const QID =
process.env.NODE_ENV === "production" ?
window.location.pathname.replace(/\//g, '')
:
"e883eccc-78b0-47bb-98b9-66d2cb0cf51d"
process.env.NODE_ENV === "production" ?
window.location.pathname.replace(/\//g, '')
:
"6e96e958-d30e-49f6-aa85-32aaef975733"
export const ViewPage = () => {
const { settings, cnt, items } = useQuestionsStore()
console.log("КВИЗ ", settings)
console.log("ВОПРОСЫ ", items)
const [visualStartPage, setVisualStartPage] = useState<boolean>();
const [errormessage, setErrormessage] = useState<string>("");
@ -33,55 +37,58 @@ export const ViewPage = () => {
//@ts-ignore
const settings = data.settings
const parseData = {
settings: {
//@ts-ignore
qid: QID,
fp: settings.fp,
rep: settings.rep,
name: settings.name,
cfg: JSON.parse(settings?.cfg),
lim: settings.lim,
due: settings.due,
delay: settings.delay,
pausable: settings.pausable
},
settings: {
//@ts-ignore
items: data.items.map((item) => {
const content = JSON.parse(item.c)
return {
description: item.desc,
id: item.id,
page: item.p,
required: item.req,
title: item.title,
type: item.typ,
content
}
}),
qid: QID,
fp: settings.fp,
rep: settings.rep,
name: settings.name,
cfg: JSON.parse(settings?.cfg),
lim: settings.lim,
due: settings.due,
delay: settings.delay,
pausable: settings.pausable
},
//@ts-ignore
items: replaceSpacesToEmptyLines(
//@ts-ignore
cnt: data.cnt
data.items.map((item) => {
const content = JSON.parse(item.c)
return {
description: item.desc,
id: item.id,
page: item.p,
required: item.req,
title: item.title,
type: item.typ,
content
}
})),
//@ts-ignore
cnt: data.cnt
}
useQuestionsStore.setState(parseData)
useQuestionsStore.setState(parseData)
} catch (e) {
//@ts-ignore
if (e?.response?.status === 423) setErrormessage("квиз не активирован")
}
}
get()
},[])
}
get()
}, [])
useEffect(() => {//установка фавиконки
if (Object.values(settings).length > 0) {
const link = document.querySelector('link[rel="icon"]');
if (link && settings?.cfg.startpage.favIcon) {
link.setAttribute("href", settings?.cfg.startpage.favIcon);
}
const link = document.querySelector('link[rel="icon"]');
if (link && settings?.cfg.startpage.favIcon) {
link.setAttribute("href", settings?.cfg.startpage.favIcon);
}
setVisualStartPage(!settings?.cfg.noStartPage);}
setVisualStartPage(!settings?.cfg.noStartPage);
}
}, [settings]);
@ -94,13 +101,16 @@ export const ViewPage = () => {
if (visualStartPage === undefined) return <Skeleton sx={{ bgcolor: 'grey', width: "100vw", height: "100vh" }} variant="rectangular" />;
if (cnt === 0 || (cnt === 1 && items[0].type === "result")) return <ApologyPage message="Нет созданных вопросов" />
return (
<Box>
{
visualStartPage ?
<StartPageViewPublication setVisualStartPage={setVisualStartPage} />
:
<Question questions={filteredQuestions} />
}
</Box>
<ThemeProvider theme={themesPublication?.[settings?.cfg.theme || "StandardTheme"]}>
<Box>
{
visualStartPage ?
<StartPageViewPublication setVisualStartPage={setVisualStartPage} />
:
<Question questions={filteredQuestions} />
}
</Box>
</ThemeProvider>
);
};

@ -1,6 +1,7 @@
import dayjs from "dayjs";
import { DatePicker } from "@mui/x-date-pickers";
import { Box, Typography } from "@mui/material";
import { Box, Typography, useTheme } from "@mui/material";
import { modes } from "../../../utils/themes/Publication/themePublication";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
@ -15,6 +16,9 @@ type DateProps = {
};
export const Date = ({ currentQuestion }: DateProps) => {
const theme = useTheme();
const mode = modes;
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const answer = answers.find(
@ -24,7 +28,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "flex",
@ -35,7 +39,11 @@ export const Date = ({ currentQuestion }: DateProps) => {
>
<DatePicker
slots={{
openPickerIcon: () => <CalendarIcon />,
//@ts-ignore
openPickerIcon: () => <CalendarIcon sx={{
"& path": {stroke: theme.palette.primary.main},
"& rect": {stroke: theme.palette.primary.main}
}} />,
}}
value={dayjs(
answer
@ -46,7 +54,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
if (!date) {
return;
}
try {
await sendAnswer({
@ -59,7 +67,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
String(
@ -73,7 +81,7 @@ export const Date = ({ currentQuestion }: DateProps) => {
} catch (e) {
enqueueSnackbar("ответ не был засчитан")
}
}}
slotProps={{
openPickerButton: {
@ -82,10 +90,14 @@ export const Date = ({ currentQuestion }: DateProps) => {
},
"data-cy": "open-datepicker",
},
layout: {
sx: {backgroundColor: theme.palette.background.default,}
}
}}
sx={{
"& .MuiInputBase-root": {
backgroundColor: "#F2F3F7",
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
borderRadius: "10px",
maxWidth: "250px",
pr: "22px",
@ -98,9 +110,11 @@ export const Date = ({ currentQuestion }: DateProps) => {
borderColor: "#9A9AAF",
},
},
}}
/>
</Box>
</Box>
);
};
};

@ -6,7 +6,9 @@ import {
Radio,
useTheme,
FormControl,
useMediaQuery
} from "@mui/material";
import { modes } from "../../../utils/themes/Publication/themePublication";
import { useQuizViewStore, updateAnswer, deleteAnswer } from "@root/quizView/store";
@ -23,121 +25,112 @@ type EmojiProps = {
};
export const Emoji = ({ currentQuestion }: EmojiProps) => {
const theme = useTheme();
const mode = modes;
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const theme = useTheme();
const { answer } =
answers.find(
({ questionId }) => questionId === currentQuestion.id
) ?? {};
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<RadioGroup
name={currentQuestion.id.toString()}
value={currentQuestion.content.variants.findIndex(
({ id }) => answer === id
)}
onChange={({ target }) =>
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[Number(target.value)].id
)
}
sx={{
display: "flex",
flexWrap: "wrap",
flexDirection: "row",
justifyContent: "space-between",
marginTop: "20px",
}}
>
<Box sx={{ display: "flex", width: "100%", gap: "42px" }}>
{currentQuestion.content.variants.map((variant, index) => (
<FormControl
key={variant.id}
sx={{
borderRadius: "12px",
border: `1px solid ${theme.palette.grey2.main}`,
overflow: "hidden",
maxWidth: "317px",
width: "100%",
height: "255px",
}}
>
<Box
return (
<Box>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<RadioGroup
name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex(
({ id }) => answer === id
)}
onChange={({ target }) =>
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[Number(target.value)].id
)
}
sx={{
display: "flex",
flexWrap: "wrap",
flexDirection: "row",
justifyContent: "space-between",
marginTop: "20px",
}}
>
<Box sx={{ display: "flex", width: "100%", gap: "42px", flexWrap: "wrap" }}>
{currentQuestion.content.variants.map((variant, index) => (
<FormControl
key={variant.id}
sx={{
display: "flex",
alignItems: "center",
height: "193px",
background: "#ffffff",
borderRadius: "12px",
border: `1px solid`,
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
overflow: "hidden",
maxWidth: "317px",
width: "100%",
height: "255px",
}}
>
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "193px",
background: "#ffffff",
}}
>
{variant.extendedText && (
<Typography fontSize={"100px"}>
{variant.extendedText}
</Typography>
)}
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
{variant.extendedText && (
<Typography fontSize={"100px"}>
{variant.extendedText}
</Typography>
)}
</Box>
</Box>
</Box>
<FormControlLabel
key={variant.id}
sx={{
margin: 0,
padding: "15px",
color: "#4D4D4D",
display: "flex",
gap: "10px",
}}
value={index}
onClick={async (event) => {
event.preventDefault();
try {
await sendAnswer({
questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
<FormControlLabel
key={variant.id}
sx={{
margin: 0,
padding: "15px",
color: theme.palette.text.primary,
display: "flex",
gap: "10px",
}}
value={index}
onClick={(event) => {
event.preventDefault();
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
enqueueSnackbar("ответ не был засчитан")
if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id);
}
}}
control={
//@ts-ignore
<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main}/>} icon={<RadioIcon />} />
}
if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id);
label={
<Box sx={{ display: "flex", gap: "10px" }}>
<Typography>{variant.answer}</Typography>
</Box>
}
}}
control={
<Radio checkedIcon={<RadioCheck />} icon={<RadioIcon />} />
}
label={
<Box sx={{ display: "flex", gap: "10px" }}>
<Typography>{variant.answer}</Typography>
</Box>
}
/>
</FormControl>
))}
</Box>
</RadioGroup>
</Box>
);
};
/>
</FormControl>
))}
</Box>
</RadioGroup>
</Box>
);
};

@ -77,7 +77,7 @@ export const File = ({ currentQuestion }: FileProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "flex",
@ -89,11 +89,11 @@ export const File = ({ currentQuestion }: FileProps) => {
>
{answer?.split("|")[0] && (
<Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
<Typography>Вы загрузили:</Typography>
<Typography color={theme.palette.text.primary}>Вы загрузили:</Typography>
<Box
sx={{
padding: "5px 5px 5px 16px",
backgroundColor: theme.palette.brightPurple.main,
backgroundColor: theme.palette.primary.main,
borderRadius: "8px",
color: "#FFFFFF",
display: "flex",
@ -105,9 +105,7 @@ export const File = ({ currentQuestion }: FileProps) => {
<IconButton
sx={{ p: 0 }}
onClick={() => {
updateAnswer(currentQuestion.id, "");
updateAnswer(currentQuestion.id, "");
}}
>
<CloseBold />
@ -138,7 +136,8 @@ export const File = ({ currentQuestion }: FileProps) => {
alignItems: "center",
padding: "33px 44px 33px 55px",
backgroundColor: theme.palette.background.default,
border: `1px solid ${theme.palette.grey2.main}`,
border: `1px solid #9A9AAF`,
// border: `1px solid ${theme.palette.grey2.main}`,
borderRadius: "8px",
}}
>
@ -146,7 +145,8 @@ export const File = ({ currentQuestion }: FileProps) => {
<Box>
<Typography
sx={{
color: theme.palette.grey2.main,
color: "#9A9AAF",
// color: theme.palette.grey2.main,
fontWeight: 500,
}}
>
@ -157,7 +157,8 @@ export const File = ({ currentQuestion }: FileProps) => {
</Typography>
<Typography
sx={{
color: theme.palette.grey2.main,
color: "#9A9AAF",
// color: theme.palette.grey2.main,
fontSize: "16px",
lineHeight: "19px",
}}
@ -196,4 +197,5 @@ export const File = ({ currentQuestion }: FileProps) => {
</Box>
</Box>
);
};

@ -34,9 +34,9 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<RadioGroup
name={currentQuestion.id.toString()}
name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex(
({ id }) => answer === id
)}
@ -66,30 +66,31 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
sx={{
cursor: "pointer",
borderRadius: "5px",
border: `1px solid ${theme.palette.grey2.main}`,
border: `1px solid`,
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
}}
onClick={async(event) => {
event.preventDefault();
try {
await sendAnswer({
questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
enqueueSnackbar("ответ не был засчитан")
}
if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id);
}
@ -116,12 +117,13 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
sx={{
display: "block",
textAlign: "center",
color: theme.palette.grey2.main,
color: theme.palette.text.primary,
marginTop: "10px",
}}
value={index}
control={
<Radio checkedIcon={<RadioCheck />} icon={<RadioIcon />} />
//@ts-ignore
<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main}/>} icon={<RadioIcon />} />
}
label={variant.answer}
/>
@ -131,4 +133,5 @@ export const Images = ({ currentQuestion }: ImagesProps) => {
</RadioGroup>
</Box>
);
};
};

@ -1,5 +1,5 @@
import { useState, useEffect } from "react";
import { Box, Typography, Slider, useTheme } from "@mui/material";
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
import { useDebouncedCallback } from "use-debounce";
import CustomTextField from "@ui_kit/CustomTextField";
@ -11,6 +11,7 @@ import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
import { modes } from "../../../utils/themes/Publication/themePublication";
type NumberProps = {
currentQuestion: QuizQuestionNumber;
@ -22,6 +23,10 @@ export const Number = ({ currentQuestion }: NumberProps) => {
const [maxRange, setMaxRange] = useState<string>("100000000000");
const theme = useTheme();
const { answers } = useQuizViewStore();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const updateMinRangeDebounced = useDebouncedCallback(async (value, crowded = false) => {
if (crowded) {
setMinRange(maxRange);
@ -44,7 +49,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}, 1000);
const updateMaxRangeDebounced = useDebouncedCallback(async(value, crowded = false) => {
const updateMaxRangeDebounced = useDebouncedCallback(async (value, crowded = false) => {
if (crowded) {
setMaxRange(minRange);
}
@ -66,6 +71,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}, 1000);
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
const mode = modes;
const min = window.Number(currentQuestion.content.range.split("—")[0]);
const max = window.Number(currentQuestion.content.range.split("—")[1]);
const sliderValue = answer || currentQuestion.content.start + "—" + max;
@ -84,7 +90,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "flex",
@ -92,6 +98,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
width: "100%",
marginTop: "20px",
gap: "30px",
paddingRight: isMobile ? "10px" : undefined
}}
>
<CustomSlider
@ -123,22 +130,33 @@ export const Number = ({ currentQuestion }: NumberProps) => {
setMaxRange(String(range[1]));
}
}}
//@ts-ignore
sx={{
color: theme.palette.primary.main,
"& .MuiSlider-valueLabel": {
background: theme.palette.primary.main,
}
}}
/>
{!currentQuestion.content.chooseRange && (
<CustomTextField
placeholder="0"
value={answer}
onChange={async({ target }) => {
onChange={async ({ target }) => {
updateMinRangeDebounced(window.Number(target.value) > max
? String(max)
: window.Number(target.value) < min
? String(min)
: target.value, true);
? String(max)
: window.Number(target.value) < min
? String(min)
: target.value, true);
}}
sx={{
maxWidth: "80px",
"& .MuiInputBase-input": { textAlign: "center" },
borderColor: theme.palette.text.primary,
"& .MuiInputBase-input": {
textAlign: "center",
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
},
}}
/>
)}
@ -168,10 +186,14 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}}
sx={{
maxWidth: "80px",
"& .MuiInputBase-input": { textAlign: "center" },
borderColor: theme.palette.text.primary,
"& .MuiInputBase-input": {
textAlign: "center",
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
},
}}
/>
<Typography>до</Typography>
<Typography color={theme.palette.text.primary}>до</Typography>
<CustomTextField
placeholder="0"
value={maxRange}
@ -188,7 +210,11 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}}
sx={{
maxWidth: "80px",
"& .MuiInputBase-input": { textAlign: "center" },
borderColor: theme.palette.text.primary,
"& .MuiInputBase-input": {
textAlign: "center",
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
},
}}
/>
</Box>
@ -196,4 +222,5 @@ export const Number = ({ currentQuestion }: NumberProps) => {
</Box>
</Box>
);
};
};

@ -1,21 +1,23 @@
import { Box, Typography } from "@mui/material";
import { Box, Typography, useTheme } from "@mui/material";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
import YoutubeEmbedIframe from "../tools/YoutubeEmbedIframe";
type PageProps = {
currentQuestion: QuizQuestionPage;
};
export const Page = ({ currentQuestion }: PageProps) => {
const theme = useTheme();
const { answers } = useQuizViewStore();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
return (
<Box>
<Typography variant="h5" sx={{ paddingBottom: "25px" }}>{currentQuestion.title}</Typography>
<Typography>{currentQuestion.content.text}</Typography>
<Typography variant="h5" sx={{ paddingBottom: "25px", color: theme.palette.text.primary }}>{currentQuestion.title}</Typography>
<Typography color={theme.palette.text.primary}>{currentQuestion.content.text}</Typography>
<Box
sx={{
display: "flex",
@ -24,32 +26,25 @@ export const Page = ({ currentQuestion }: PageProps) => {
marginTop: "20px",
}}
>
{currentQuestion.content.picture && (
<Box sx={{borderRadius: "12px",
border: "1px solid #9A9AAF", overflow: "hidden" }}>
<img
src={currentQuestion.content.picture}
alt=""
style={{
display: "block",
width: "100%",
height: "100%",
objectFit: "contain",
}}
/>
</Box>
)}
{currentQuestion.content.video && (
<video
src={currentQuestion.content.video}
controls
style={{
width: "100%",
height: "100%",
maxHeight: "80vh",
objectFit: "contain",
}}
{
//@ts-ignore
currentQuestion.content.useImage ? (
<Box sx={{ borderRadius: "12px", border: "1px solid #9A9AAF", overflow: "hidden" }}>
<img
src={currentQuestion.content.back}
alt=""
style={{
display: "block",
width: "100%",
height: "100%",
objectFit: "contain",
}}
/>
</Box>
) : (
<YoutubeEmbedIframe
containerSX={{ width: "100%", height: "100%", maxHeight: "80vh", objectFit: "contain" }}
videoUrl={currentQuestion.content.video}
/>
)}
</Box>

@ -3,6 +3,7 @@ import {
Typography,
Rating as RatingComponent,
useTheme,
useMediaQuery
} from "@mui/material";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
@ -59,6 +60,7 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const { answer } =
answers.find(
({ questionId }) => questionId === currentQuestion.id
@ -69,16 +71,20 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "inline-flex",
alignItems: "center",
gap: "20px",
marginTop: "20px",
width: isMobile ? "100%" : undefined
}}
>
<Typography sx={{ color: theme.palette.grey2.main }}>
<Typography sx={{
color: "#9A9AAF"
// color: theme.palette.grey2.main
}}>
{currentQuestion.content.ratingNegativeDescription}
</Typography>
<Box
@ -93,32 +99,35 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
try {
await sendAnswer({
questionId: currentQuestion.id,
body: String(value),
//@ts-ignore
qid: settings.qid
})
updateAnswer(currentQuestion.id, String(value))
} catch (e) {
enqueueSnackbar("ответ не был засчитан")
}
}
}
sx={{ height: "50px", gap: "15px" }}
}}
sx={{ height: "50px",
gap: isMobile ? undefined : "15px",
justifyContent: isMobile ? "space-between" : undefined,
width: isMobile ? "100%" : undefined
}}
max={currentQuestion.content.steps}
icon={form?.icon(theme.palette.brightPurple.main)}
emptyIcon={form?.icon(theme.palette.grey2.main)}
icon={form?.icon(theme.palette.primary.main)}
emptyIcon={form?.icon("#9A9AAF")}
/>
</Box>
<Typography sx={{ color: theme.palette.grey2.main }}>
<Typography sx={{ color: "#9A9AAF" }}>
{currentQuestion.content.ratingPositiveDescription}
</Typography>
</Box>
</Box>
);
};
};

@ -1,4 +1,4 @@
import { Box, Typography } from "@mui/material";
import { Box, Typography, useTheme } from "@mui/material";
import { Select as SelectComponent } from "../tools//Select";
@ -14,6 +14,8 @@ type SelectProps = {
};
export const Select = ({ currentQuestion }: SelectProps) => {
const theme = useTheme();
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const { answer } =
@ -23,7 +25,7 @@ export const Select = ({ currentQuestion }: SelectProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "flex",
@ -36,6 +38,10 @@ export const Select = ({ currentQuestion }: SelectProps) => {
placeholder={currentQuestion.content.default}
activeItemIndex={answer ? Number(answer) : -1}
items={currentQuestion.content.variants.map(({ answer }) => answer)}
//@ts-ignore
colorMain={theme.palette.primary.main}
//@ts-ignore
color={theme.palette.primary.main}
onChange={async(_, value) => {
if (value < 0) {
deleteAnswer(currentQuestion.id);

@ -1,4 +1,4 @@
import { Box, Typography } from "@mui/material";
import { Box, Typography, useTheme } from "@mui/material";
import CustomTextField from "@ui_kit/CustomTextField";
@ -15,6 +15,7 @@ type TextProps = {
};
export const Text = ({ currentQuestion }: TextProps) => {
const theme = useTheme();
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
@ -36,7 +37,7 @@ export const Text = ({ currentQuestion }: TextProps) => {
}, 400);
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box
sx={{
display: "flex",
@ -54,6 +55,11 @@ export const Text = ({ currentQuestion }: TextProps) => {
inputHC(target.value)
}
}
sx={{
"&:focus-visible": {
borderColor: theme.palette.primary.main
}
}}
/>
</Box>
</Box>

@ -28,6 +28,7 @@ import type { QuestionVariant } from "../../../model/questionTypes/shared";
import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store"
import { modes } from "../../../utils/themes/Publication/themePublication";
type VariantProps = {
stepNumber: number;
@ -45,6 +46,7 @@ type VariantItemProps = {
export const Variant = ({ currentQuestion }: VariantProps) => {
const { settings } = useQuestionsStore()
const { answers, ownVariants } = useQuizViewStore();
const mode = modes;
const { answer } =
answers.find(
({ questionId }) => questionId === currentQuestion.id
@ -61,12 +63,13 @@ export const Variant = ({ currentQuestion }: VariantProps) => {
}
}, []);
const theme = useTheme();
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box sx={{ display: "flex" }}>
<Group
name={currentQuestion.id.toString()}
name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex(
({ id }) => answer === id
)}
@ -131,6 +134,7 @@ const VariantItem = ({
}: VariantItemProps) => {
const { settings } = useQuestionsStore()
const theme = useTheme();
const mode = modes;
return (
<FormControlLabel
@ -138,8 +142,11 @@ const VariantItem = ({
sx={{
margin: "0",
borderRadius: "12px",
color: theme.palette.text.primary,
padding: "15px",
border: `1px solid ${theme.palette.grey2.main}`,
border: `1px solid`,
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
display: "flex",
maxWidth: "685px",
justifyContent: "space-between",
@ -155,11 +162,12 @@ const VariantItem = ({
currentQuestion.content.multi ? (
<Checkbox
checked={!!answer?.includes(variant.id)}
checkedIcon={<CheckboxIcon checked />}
checkedIcon={<CheckboxIcon checked color={theme.palette.primary.main} />}
icon={<CheckboxIcon />}
/>
) : (
<Radio checkedIcon={<RadioCheck />} icon={<RadioIcon />} />
) :
//@ts-ignore
(<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main}/>} icon={<RadioIcon />} />
)
}
//@ts-ignore
@ -216,6 +224,7 @@ const VariantItem = ({
deleteAnswer(currentQuestion.id);
}
}}
/>
);
};
};

@ -5,7 +5,9 @@ import {
FormControlLabel,
Radio,
useTheme,
useMediaQuery
} from "@mui/material";
import { modes } from "../../../utils/themes/Publication/themePublication";
import gag from "./gag.png"
@ -27,6 +29,8 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const mode = modes;
const { answer } =
answers.find(
({ questionId }) => questionId === currentQuestion.id
@ -37,10 +41,16 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
return (
<Box>
<Typography variant="h5">{currentQuestion.title}</Typography>
<Box sx={{ display: "flex", marginTop: "20px" }}>
<Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box sx={{
display: "flex",
marginTop: "20px",
flexDirection: isMobile ? "column-reverse" : undefined,
gap: isMobile ? "30px" : undefined
}}>
<RadioGroup
name={currentQuestion.id.toString()}
name={currentQuestion.id}
value={currentQuestion.content.variants.findIndex(
({ id }) => answer === id
)}
@ -52,7 +62,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
flexBasis: "100%",
}}
>
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
<Box sx={{ display: "flex", flexDirection: "column", width: "100%", gap: isMobile ? "20px" : undefined }}>
{currentQuestion.content.variants.map((variant, index) => (
<FormControlLabel
key={variant.id}
@ -60,41 +70,45 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
marginBottom: "15px",
borderRadius: "5px",
padding: "15px",
color: "#4D4D4D",
border: `1px solid ${theme.palette.grey2.main}`,
color: theme.palette.text.primary,
backgroundColor: mode[settings.cfg.theme] ? "white" : theme.palette.background.default,
border: `1px solid`,
borderColor: answer === variant.id ? theme.palette.primary.main : "#9A9AAF",
display: "flex",
margin: isMobile ? 0 : undefined,
}}
value={index}
onClick={async(event) => {
event.preventDefault();
try {
await sendAnswer({
questionId: currentQuestion.id,
body: currentQuestion.content.variants[index].id,
//@ts-ignore
qid: settings.qid
})
updateAnswer(
currentQuestion.id,
currentQuestion.content.variants[index].id
);
} catch (e) {
enqueueSnackbar("ответ не был засчитан")
}
if (answer === currentQuestion.content.variants[index].id) {
deleteAnswer(currentQuestion.id);
}
}}
control={
<Radio checkedIcon={<RadioCheck />} icon={<RadioIcon />} />
//@ts-ignore
<Radio checkedIcon={<RadioCheck color={theme.palette.primary.main}/>} icon={<RadioIcon />} />
}
label={variant.answer}
/>
@ -127,7 +141,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
alt=""
/>
:
(variant?.extendedText || "Выберите вариант ответа слева")
(variant?.extendedText || isMobile ? ("Выберите вариант ответа ниже") : ("Выберите вариант ответа слева"))
}
</Box>
@ -135,4 +149,5 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
</Box>
</Box>
);
};
};

@ -17,6 +17,8 @@ type SelectProps = {
empty?: boolean;
onChange?: (item: string, num: number) => void;
sx?: SxProps;
colorMain?: string;
colorPlaceholder?: string;
placeholder?: string;
};
@ -27,6 +29,8 @@ export const Select = ({
onChange,
sx,
placeholder = "",
colorMain = "#7E2AEA",
colorPlaceholder = "#9A9AAF",
}: SelectProps) => {
const [activeItem, setActiveItem] = useState<number>(
empty ? -1 : activeItemIndex
@ -63,7 +67,7 @@ export const Select = ({
value ? (
items[Number(value)]
) : (
<Typography sx={{ color: theme.palette.grey2.main }}>
<Typography sx={{ color: colorPlaceholder }}>
{placeholder}
</Typography>
)
@ -77,7 +81,7 @@ export const Select = ({
height: "48px",
borderRadius: "8px",
"& .MuiOutlinedInput-notchedOutline": {
border: `1px solid ${theme.palette.brightPurple.main} !important`,
border: `1px solid ${colorMain} !important`,
height: "48px",
borderRadius: "10px",
},
@ -100,14 +104,14 @@ export const Select = ({
gap: "8px",
"& .Mui-selected": {
backgroundColor: theme.palette.background.default,
color: theme.palette.brightPurple.main,
color: colorMain,
},
},
},
}}
inputProps={{
sx: {
color: theme.palette.brightPurple.main,
color: colorMain,
display: "flex",
alignItems: "center",
px: "9px",
@ -126,7 +130,7 @@ export const Select = ({
gap: "20px",
padding: "10px",
borderRadius: "5px",
color: theme.palette.grey2.main,
color: colorPlaceholder,
}}
>
{item}

@ -0,0 +1,30 @@
export const replaceSpacesToEmptyLines = <T = unknown>(object: T): T => {
if (Array.isArray(object)) {
return object.map(replaceSpacesToEmptyLines) as T;
}
if (!object || typeof object !== "object") {
return object;
}
const result: Record<string, unknown> = {};
for (const [key, value] of Object.entries(object)) {
if (typeof value === "string") {
result[key] = value.replace(/ /g, "");
continue;
}
if (typeof value === "object") {
result[key] = replaceSpacesToEmptyLines(value);
continue;
}
result[key] = value;
}
return result as T;
};

@ -11,9 +11,10 @@ interface Props {
checked?: boolean;
sx?: SxProps;
dataCy?: string;
colorIcon?: string;
}
export default function CustomCheckbox({ label, handleChange, checked, sx, dataCy }: Props) {
export default function CustomCheckbox({ label, handleChange, checked, sx, dataCy, colorIcon }: Props) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
@ -24,7 +25,8 @@ export default function CustomCheckbox({ label, handleChange, checked, sx, dataC
sx={{ padding: "0px 13px 1px 11px" }}
disableRipple
icon={<CheckboxIcon />}
checkedIcon={<CheckboxIcon checked />}
//@ts-ignore
checkedIcon={<CheckboxIcon checked color={colorIcon} />}
onChange={handleChange}
checked={checked}
data-cy={dataCy}
@ -32,7 +34,7 @@ export default function CustomCheckbox({ label, handleChange, checked, sx, dataC
}
label={label}
sx={{
color: theme.palette.grey2.main,
color: "#9A9AAF",
height: "26px",
...sx,
}}

@ -40,11 +40,11 @@ export const CustomSlider = ({
onMouseDown={(e) => e.stopPropagation()}
data-cy="slider"
sx={{
color: theme.palette.brightPurple.main,
color: "#7E2AEA",
padding: "0",
marginTop: "75px",
"& .MuiSlider-valueLabel": {
background: theme.palette.brightPurple.main,
background: "#7E2AEA",
borderRadius: "8px",
minWidth: "60px",
width: "auto",

@ -0,0 +1,43 @@
import { createTheme } from "@mui/material";
import theme from "../generic";
const themePublic = createTheme({
...theme,
components: {
MuiButton: {
variants: [
{
props: {
variant: 'contained'
},
style: {
padding: '13px 20px',
borderRadius: '8px',
boxShadow: "none",
// "&:hover": {
// backgroundColor: "#581CA7"
// }
},
},
{
props: {
variant: 'outlined'
},
style: {
padding: '10px 20px',
borderRadius: '8px',
"&:hover": {
backgroundColor: "#581CA7",
border: '1px solid #581CA7',
}
},
},
],
},
},
},
)
export default themePublic;

@ -0,0 +1,253 @@
import { createTheme } from "@mui/material";
import themePublic from "./genericPublication";
import theme from "../generic";
const StandardTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#7E2AEA",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#7E2AEA",
},
background: {
default: "#FFFFFF",
},
}
})
const StandardDarkTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#7E2AEA",
},
secondary: {
main: "#252734"
},
text: {
primary: "#FFFFFF",
secondary: "#7E2AEA",
},
background: {
default: "#333647",
},
}
})
const PinkTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#D34085",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#D34085",
},
background: {
default: "#FFF9FC",
},
}
})
const PinkDarkTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#D34085",
},
secondary: {
main: "#252734"
},
text: {
primary: "#FFFFFF",
secondary: "#D34085",
},
background: {
default: "#333647",
},
}
})
const BlackWhiteTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#4E4D51",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#FFF9FC",
},
background: {
default: "#FFFFFF",
},
}
})
const OliveTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#758E4F",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#758E4F",
},
background: {
default: "#F9FBF1",
},
}
})
const PurpleTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#7E2AEA",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#7E2AEA",
},
background: {
default: "#FBF8FF",
},
}
})
const YellowTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#F2B133",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#F2B133",
},
background: {
default: "#FFFCF6",
},
}
})
const GoldDarkTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#E6AA37",
},
secondary: {
main: "#FFFCF6",
},
text: {
primary: "#FFFFFF",
secondary: "#F2B133",
},
background: {
default: "#333647",
},
}
})
const BlueTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#4964ED",
},
secondary: {
main: "#252734"
},
text: {
primary: "#333647",
secondary: "#4964ED",
},
background: {
default: "#F5F7FF",
},
}
})
const BlueDarkTheme = createTheme({
...themePublic,
palette: {
primary: {
main: "#07A0C3",
},
secondary: {
main: "#252734"
},
text: {
primary: "#FFFFFF",
secondary: "#07A0C3",
},
background: {
default: "#333647",
},
}
})
export const modes = {
StandardTheme: true,
StandardDarkTheme: false,
PinkTheme: true,
PinkDarkTheme: false,
BlackWhiteTheme: true,
OliveTheme: true,
YellowTheme: true,
GoldDarkTheme: false,
PurpleTheme: true,
BlueTheme: true,
BlueDarkTheme: false
}
export const themesPublication = {
StandardTheme,
StandardDarkTheme,
PinkTheme,
PinkDarkTheme,
BlackWhiteTheme,
OliveTheme,
YellowTheme,
GoldDarkTheme,
PurpleTheme,
BlueTheme,
BlueDarkTheme,
}