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

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

@ -1,7 +1,12 @@
import { Box, useTheme } from "@mui/material"; import {Box, SxProps, Theme, useTheme} from "@mui/material";
interface Color{
export default function ArrowDownIcon(props: any) { color?: string
}
export default function ArrowDownIcon(
props: any,
{color = "#7E2AEA"}: Color
) {
const theme = useTheme(); const theme = useTheme();
return ( 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"> <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> </svg>
</Box> </Box>
); );

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

File diff suppressed because one or more lines are too long

@ -1,7 +1,10 @@
import { Box, useTheme } from "@mui/material"; import { Box, useTheme } from "@mui/material";
interface Props{
color?: string
}
export default function UploadIcon() { export default function UploadIcon({color= "#9A9AAF"}: Props) {
const theme = useTheme(); const theme = useTheme();
return ( 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"> <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="M10.75 10.25L16 5L21.25 10.25" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
<path d="M16 19V5" stroke={theme.palette.grey2.main} 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={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={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg> </svg>
</Box> </Box>
); );

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

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

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

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

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

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

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

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

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

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

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

@ -1,5 +1,5 @@
import { useState, useEffect } from "react"; 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 { useDebouncedCallback } from "use-debounce";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
@ -11,6 +11,7 @@ import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { sendAnswer } from "@api/quizRelase"; import { sendAnswer } from "@api/quizRelase";
import { useQuestionsStore } from "@root/quizData/store" import { useQuestionsStore } from "@root/quizData/store"
import { modes } from "../../../utils/themes/Publication/themePublication";
type NumberProps = { type NumberProps = {
currentQuestion: QuizQuestionNumber; currentQuestion: QuizQuestionNumber;
@ -22,6 +23,10 @@ export const Number = ({ currentQuestion }: NumberProps) => {
const [maxRange, setMaxRange] = useState<string>("100000000000"); const [maxRange, setMaxRange] = useState<string>("100000000000");
const theme = useTheme(); const theme = useTheme();
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const updateMinRangeDebounced = useDebouncedCallback(async (value, crowded = false) => { const updateMinRangeDebounced = useDebouncedCallback(async (value, crowded = false) => {
if (crowded) { if (crowded) {
setMinRange(maxRange); setMinRange(maxRange);
@ -44,7 +49,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}, 1000); }, 1000);
const updateMaxRangeDebounced = useDebouncedCallback(async(value, crowded = false) => { const updateMaxRangeDebounced = useDebouncedCallback(async (value, crowded = false) => {
if (crowded) { if (crowded) {
setMaxRange(minRange); setMaxRange(minRange);
} }
@ -66,6 +71,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}, 1000); }, 1000);
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string; const answer = answers.find(({ questionId }) => questionId === currentQuestion.id)?.answer as string;
const mode = modes;
const min = window.Number(currentQuestion.content.range.split("—")[0]); const min = window.Number(currentQuestion.content.range.split("—")[0]);
const max = window.Number(currentQuestion.content.range.split("—")[1]); const max = window.Number(currentQuestion.content.range.split("—")[1]);
const sliderValue = answer || currentQuestion.content.start + "—" + max; const sliderValue = answer || currentQuestion.content.start + "—" + max;
@ -84,7 +90,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
return ( return (
<Box> <Box>
<Typography variant="h5">{currentQuestion.title}</Typography> <Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -92,6 +98,7 @@ export const Number = ({ currentQuestion }: NumberProps) => {
width: "100%", width: "100%",
marginTop: "20px", marginTop: "20px",
gap: "30px", gap: "30px",
paddingRight: isMobile ? "10px" : undefined
}} }}
> >
<CustomSlider <CustomSlider
@ -123,22 +130,33 @@ export const Number = ({ currentQuestion }: NumberProps) => {
setMaxRange(String(range[1])); setMaxRange(String(range[1]));
} }
}} }}
//@ts-ignore
sx={{
color: theme.palette.primary.main,
"& .MuiSlider-valueLabel": {
background: theme.palette.primary.main,
}
}}
/> />
{!currentQuestion.content.chooseRange && ( {!currentQuestion.content.chooseRange && (
<CustomTextField <CustomTextField
placeholder="0" placeholder="0"
value={answer} value={answer}
onChange={async({ target }) => { onChange={async ({ target }) => {
updateMinRangeDebounced(window.Number(target.value) > max updateMinRangeDebounced(window.Number(target.value) > max
? String(max) ? String(max)
: window.Number(target.value) < min : window.Number(target.value) < min
? String(min) ? String(min)
: target.value, true); : target.value, true);
}} }}
sx={{ sx={{
maxWidth: "80px", 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={{ sx={{
maxWidth: "80px", 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 <CustomTextField
placeholder="0" placeholder="0"
value={maxRange} value={maxRange}
@ -188,7 +210,11 @@ export const Number = ({ currentQuestion }: NumberProps) => {
}} }}
sx={{ sx={{
maxWidth: "80px", 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> </Box>
@ -196,4 +222,5 @@ export const Number = ({ currentQuestion }: NumberProps) => {
</Box> </Box>
</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 { useQuizViewStore, updateAnswer } from "@root/quizView/store";
import type { QuizQuestionPage } from "../../../model/questionTypes/page"; import type { QuizQuestionPage } from "../../../model/questionTypes/page";
import YoutubeEmbedIframe from "../tools/YoutubeEmbedIframe";
type PageProps = { type PageProps = {
currentQuestion: QuizQuestionPage; currentQuestion: QuizQuestionPage;
}; };
export const Page = ({ currentQuestion }: PageProps) => { export const Page = ({ currentQuestion }: PageProps) => {
const theme = useTheme();
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
return ( return (
<Box> <Box>
<Typography variant="h5" sx={{ paddingBottom: "25px" }}>{currentQuestion.title}</Typography> <Typography variant="h5" sx={{ paddingBottom: "25px", color: theme.palette.text.primary }}>{currentQuestion.title}</Typography>
<Typography>{currentQuestion.content.text}</Typography> <Typography color={theme.palette.text.primary}>{currentQuestion.content.text}</Typography>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -24,32 +26,25 @@ export const Page = ({ currentQuestion }: PageProps) => {
marginTop: "20px", marginTop: "20px",
}} }}
> >
{currentQuestion.content.picture && ( {
<Box sx={{borderRadius: "12px", //@ts-ignore
border: "1px solid #9A9AAF", overflow: "hidden" }}> currentQuestion.content.useImage ? (
<img <Box sx={{ borderRadius: "12px", border: "1px solid #9A9AAF", overflow: "hidden" }}>
src={currentQuestion.content.picture} <img
alt="" src={currentQuestion.content.back}
style={{ alt=""
display: "block", style={{
width: "100%", display: "block",
height: "100%", width: "100%",
objectFit: "contain", height: "100%",
}} objectFit: "contain",
/> }}
</Box> />
</Box>
)} ) : (
{currentQuestion.content.video && ( <YoutubeEmbedIframe
<video containerSX={{ width: "100%", height: "100%", maxHeight: "80vh", objectFit: "contain" }}
src={currentQuestion.content.video} videoUrl={currentQuestion.content.video}
controls
style={{
width: "100%",
height: "100%",
maxHeight: "80vh",
objectFit: "contain",
}}
/> />
)} )}
</Box> </Box>

@ -3,6 +3,7 @@ import {
Typography, Typography,
Rating as RatingComponent, Rating as RatingComponent,
useTheme, useTheme,
useMediaQuery
} from "@mui/material"; } from "@mui/material";
import { useQuizViewStore, updateAnswer } from "@root/quizView/store"; import { useQuizViewStore, updateAnswer } from "@root/quizView/store";
@ -59,6 +60,7 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
const { settings } = useQuestionsStore() const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(650));
const { answer } = const { answer } =
answers.find( answers.find(
({ questionId }) => questionId === currentQuestion.id ({ questionId }) => questionId === currentQuestion.id
@ -69,16 +71,20 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
return ( return (
<Box> <Box>
<Typography variant="h5">{currentQuestion.title}</Typography> <Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box <Box
sx={{ sx={{
display: "inline-flex", display: "inline-flex",
alignItems: "center", alignItems: "center",
gap: "20px", gap: "20px",
marginTop: "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} {currentQuestion.content.ratingNegativeDescription}
</Typography> </Typography>
<Box <Box
@ -93,32 +99,35 @@ export const Rating = ({ currentQuestion }: RatingProps) => {
try { try {
await sendAnswer({ await sendAnswer({
questionId: currentQuestion.id, questionId: currentQuestion.id,
body: String(value), body: String(value),
//@ts-ignore //@ts-ignore
qid: settings.qid qid: settings.qid
}) })
updateAnswer(currentQuestion.id, String(value)) updateAnswer(currentQuestion.id, String(value))
} catch (e) { } catch (e) {
enqueueSnackbar("ответ не был засчитан") enqueueSnackbar("ответ не был засчитан")
} }
} }}
sx={{ height: "50px",
} gap: isMobile ? undefined : "15px",
sx={{ height: "50px", gap: "15px" }} justifyContent: isMobile ? "space-between" : undefined,
width: isMobile ? "100%" : undefined
}}
max={currentQuestion.content.steps} max={currentQuestion.content.steps}
icon={form?.icon(theme.palette.brightPurple.main)} icon={form?.icon(theme.palette.primary.main)}
emptyIcon={form?.icon(theme.palette.grey2.main)} emptyIcon={form?.icon("#9A9AAF")}
/> />
</Box> </Box>
<Typography sx={{ color: theme.palette.grey2.main }}> <Typography sx={{ color: "#9A9AAF" }}>
{currentQuestion.content.ratingPositiveDescription} {currentQuestion.content.ratingPositiveDescription}
</Typography> </Typography>
</Box> </Box>
</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"; import { Select as SelectComponent } from "../tools//Select";
@ -14,6 +14,8 @@ type SelectProps = {
}; };
export const Select = ({ currentQuestion }: SelectProps) => { export const Select = ({ currentQuestion }: SelectProps) => {
const theme = useTheme();
const { settings } = useQuestionsStore() const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const { answer } = const { answer } =
@ -23,7 +25,7 @@ export const Select = ({ currentQuestion }: SelectProps) => {
return ( return (
<Box> <Box>
<Typography variant="h5">{currentQuestion.title}</Typography> <Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -36,6 +38,10 @@ export const Select = ({ currentQuestion }: SelectProps) => {
placeholder={currentQuestion.content.default} placeholder={currentQuestion.content.default}
activeItemIndex={answer ? Number(answer) : -1} activeItemIndex={answer ? Number(answer) : -1}
items={currentQuestion.content.variants.map(({ answer }) => answer)} items={currentQuestion.content.variants.map(({ answer }) => answer)}
//@ts-ignore
colorMain={theme.palette.primary.main}
//@ts-ignore
color={theme.palette.primary.main}
onChange={async(_, value) => { onChange={async(_, value) => {
if (value < 0) { if (value < 0) {
deleteAnswer(currentQuestion.id); 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"; import CustomTextField from "@ui_kit/CustomTextField";
@ -15,6 +15,7 @@ type TextProps = {
}; };
export const Text = ({ currentQuestion }: TextProps) => { export const Text = ({ currentQuestion }: TextProps) => {
const theme = useTheme();
const { settings } = useQuestionsStore() const { settings } = useQuestionsStore()
const { answers } = useQuizViewStore(); const { answers } = useQuizViewStore();
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {}; const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.id) ?? {};
@ -36,7 +37,7 @@ export const Text = ({ currentQuestion }: TextProps) => {
}, 400); }, 400);
return ( return (
<Box> <Box>
<Typography variant="h5">{currentQuestion.title}</Typography> <Typography variant="h5" color={theme.palette.text.primary}>{currentQuestion.title}</Typography>
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
@ -54,6 +55,11 @@ export const Text = ({ currentQuestion }: TextProps) => {
inputHC(target.value) inputHC(target.value)
} }
} }
sx={{
"&:focus-visible": {
borderColor: theme.palette.primary.main
}
}}
/> />
</Box> </Box>
</Box> </Box>

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

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

@ -17,6 +17,8 @@ type SelectProps = {
empty?: boolean; empty?: boolean;
onChange?: (item: string, num: number) => void; onChange?: (item: string, num: number) => void;
sx?: SxProps; sx?: SxProps;
colorMain?: string;
colorPlaceholder?: string;
placeholder?: string; placeholder?: string;
}; };
@ -27,6 +29,8 @@ export const Select = ({
onChange, onChange,
sx, sx,
placeholder = "", placeholder = "",
colorMain = "#7E2AEA",
colorPlaceholder = "#9A9AAF",
}: SelectProps) => { }: SelectProps) => {
const [activeItem, setActiveItem] = useState<number>( const [activeItem, setActiveItem] = useState<number>(
empty ? -1 : activeItemIndex empty ? -1 : activeItemIndex
@ -63,7 +67,7 @@ export const Select = ({
value ? ( value ? (
items[Number(value)] items[Number(value)]
) : ( ) : (
<Typography sx={{ color: theme.palette.grey2.main }}> <Typography sx={{ color: colorPlaceholder }}>
{placeholder} {placeholder}
</Typography> </Typography>
) )
@ -77,7 +81,7 @@ export const Select = ({
height: "48px", height: "48px",
borderRadius: "8px", borderRadius: "8px",
"& .MuiOutlinedInput-notchedOutline": { "& .MuiOutlinedInput-notchedOutline": {
border: `1px solid ${theme.palette.brightPurple.main} !important`, border: `1px solid ${colorMain} !important`,
height: "48px", height: "48px",
borderRadius: "10px", borderRadius: "10px",
}, },
@ -100,14 +104,14 @@ export const Select = ({
gap: "8px", gap: "8px",
"& .Mui-selected": { "& .Mui-selected": {
backgroundColor: theme.palette.background.default, backgroundColor: theme.palette.background.default,
color: theme.palette.brightPurple.main, color: colorMain,
}, },
}, },
}, },
}} }}
inputProps={{ inputProps={{
sx: { sx: {
color: theme.palette.brightPurple.main, color: colorMain,
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
px: "9px", px: "9px",
@ -126,7 +130,7 @@ export const Select = ({
gap: "20px", gap: "20px",
padding: "10px", padding: "10px",
borderRadius: "5px", borderRadius: "5px",
color: theme.palette.grey2.main, color: colorPlaceholder,
}} }}
> >
{item} {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; checked?: boolean;
sx?: SxProps; sx?: SxProps;
dataCy?: string; 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 theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790)); 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" }} sx={{ padding: "0px 13px 1px 11px" }}
disableRipple disableRipple
icon={<CheckboxIcon />} icon={<CheckboxIcon />}
checkedIcon={<CheckboxIcon checked />} //@ts-ignore
checkedIcon={<CheckboxIcon checked color={colorIcon} />}
onChange={handleChange} onChange={handleChange}
checked={checked} checked={checked}
data-cy={dataCy} data-cy={dataCy}
@ -32,7 +34,7 @@ export default function CustomCheckbox({ label, handleChange, checked, sx, dataC
} }
label={label} label={label}
sx={{ sx={{
color: theme.palette.grey2.main, color: "#9A9AAF",
height: "26px", height: "26px",
...sx, ...sx,
}} }}

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