fix: conflicts resolved

This commit is contained in:
IlyaDoronin 2023-10-06 16:41:32 +03:00
commit 010704ef40
24 changed files with 969 additions and 744 deletions

@ -8,8 +8,8 @@ export default function AddEmoji() {
return (
<Box
sx={{
height: "38px",
width: "45px",
height: "40px",
width: "60px",
display: "flex",
alignItems: "center",
justifyContent: "center",
@ -37,24 +37,24 @@ export default function AddEmoji() {
<path
d="M20 31C21.0949 30.9993 22.1837 30.8371 23.2313 30.5187L31 20C31 17.8244 30.3549 15.6977 29.1462 13.8887C27.9375 12.0798 26.2195 10.6699 24.2095 9.83733C22.1995 9.00477 19.9878 8.78693 17.854 9.21137C15.7202 9.6358 13.7602 10.6835 12.2218 12.2218C10.6835 13.7602 9.6358 15.7202 9.21137 17.854C8.78693 19.9878 9.00477 22.1995 9.83733 24.2095C10.6699 26.2195 12.0798 27.9375 13.8887 29.1462C15.6977 30.3549 17.8244 31 20 31Z"
stroke="#7E2AEA"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M15.875 19.083C16.6344 19.083 17.25 18.4674 17.25 17.708C17.25 16.9486 16.6344 16.333 15.875 16.333C15.1156 16.333 14.5 16.9486 14.5 17.708C14.5 18.4674 15.1156 19.083 15.875 19.083Z"
d="M15.875 19.084C16.6344 19.084 17.25 18.4684 17.25 17.709C17.25 16.9496 16.6344 16.334 15.875 16.334C15.1156 16.334 14.5 16.9496 14.5 17.709C14.5 18.4684 15.1156 19.084 15.875 19.084Z"
fill="#7E2AEA"
/>
<path
d="M24.125 19.083C24.8844 19.083 25.5 18.4674 25.5 17.708C25.5 16.9486 24.8844 16.333 24.125 16.333C23.3656 16.333 22.75 16.9486 22.75 17.708C22.75 18.4674 23.3656 19.083 24.125 19.083Z"
d="M24.125 19.084C24.8844 19.084 25.5 18.4684 25.5 17.709C25.5 16.9496 24.8844 16.334 24.125 16.334C23.3656 16.334 22.75 16.9496 22.75 17.709C22.75 18.4684 23.3656 19.084 24.125 19.084Z"
fill="#7E2AEA"
/>
<path
d="M24.7677 22.75C24.2831 23.5849 23.5878 24.2778 22.7512 24.7595C21.9147 25.2412 20.9663 25.4947 20.001 25.4947C19.0357 25.4947 18.0874 25.2412 17.2508 24.7595C16.4143 24.2778 15.719 23.5849 15.2344 22.75"
stroke="#7E2AEA"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</Box>

@ -0,0 +1,53 @@
import { Box, SxProps } from "@mui/material";
import { FC } from "react";
interface Iprops {
onClick?: () => void;
sx?: SxProps;
}
const Image: FC<Iprops> = ({ onClick, sx }) => {
return (
<Box
onClick={onClick}
sx={{
height: "38px",
width: "45px",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "pointer",
...sx,
}}
>
<svg
width="27"
height="22"
viewBox="0 0 27 22"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24.9583 1H2.04167C1.46637 1 1 1.44772 1 2V20C1 20.5523 1.46637 21 2.04167 21H24.9583C25.5336 21 26 20.5523 26 20V2C26 1.44772 25.5336 1 24.9583 1Z"
stroke="#7E2AEA"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M1 15.9035L7.54948 9.31272C7.64641 9.21368 7.76194 9.13502 7.88936 9.08133C8.01677 9.02765 8.15353 9 8.29167 9C8.4298 9 8.56656 9.02765 8.69398 9.08133C8.82139 9.13502 8.93693 9.21368 9.03385 9.31272L14.8411 15.1567C14.9381 15.2557 15.0536 15.3343 15.181 15.388C15.3084 15.4417 15.4452 15.4694 15.5833 15.4694C15.7215 15.4694 15.8582 15.4417 15.9856 15.388C16.1131 15.3343 16.2286 15.2557 16.3255 15.1567L19.0078 12.4574C19.1047 12.3584 19.2203 12.2797 19.3477 12.2261C19.4751 12.1724 19.6119 12.1447 19.75 12.1447C19.8881 12.1447 20.0249 12.1724 20.1523 12.2261C20.2797 12.2797 20.3953 12.3584 20.4922 12.4574L26 18"
stroke="#7E2AEA"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M16.5 9C17.3284 9 18 8.32843 18 7.5C18 6.67157 17.3284 6 16.5 6C15.6716 6 15 6.67157 15 7.5C15 8.32843 15.6716 9 16.5 9Z"
fill="#7E2AEA"
/>
</svg>
</Box>
);
};
export default Image;

@ -13,8 +13,8 @@ export default function Plus() {
>
<svg
width="20"
height="30"
viewBox="0 0 15 40"
height="40"
viewBox="0 0 20 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>

@ -1,5 +1,4 @@
import React from "react";
import Stepper from "@ui_kit/Stepper";
import { Box, Button, IconButton, Typography, Paper, useTheme, Link, SxProps, Theme, TextField } from "@mui/material";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import CustomTextField from "@ui_kit/CustomTextField";
@ -41,7 +40,6 @@ export default function ContactFormPage() {
const theme = useTheme();
return (
<>
<Stepper activeStep={activeStep} desc={"Настройте форму контактов"} />
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Link
sx={{

@ -1,4 +1,5 @@
import React, { useState } from "react";
import { useParams } from "react-router-dom";
import {
Box,
Button,
@ -18,7 +19,7 @@ import {
Tooltip,
useTheme,
} from "@mui/material";
import Stepper from "@ui_kit/Stepper";
import { quizStore } from "@root/quizes";
import LinkIcon from "../../assets/icons/LinkIcon";
import InfoIcon from "../../assets/icons/InfoIcon";
import ArrowDown from "../../assets/icons/ArrowDownIcon";
@ -70,17 +71,8 @@ export default function InstallQuiz() {
},
];
const [activeStep, setActiveStep] = React.useState(5);
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const [display, setDisplay] = React.useState("1");
const quizId = Number(useParams().quizId);
const handleChange = (event: SelectChangeEvent) => {
setDisplay(event.target.value);
};
@ -96,9 +88,14 @@ export default function InstallQuiz() {
const [backgroundType, setBackgroundType] = useState<BackgroundType>("text");
const theme = useTheme();
const { listQuizes, updateQuizesList } = quizStore();
const handleNext = () => {
updateQuizesList(quizId, { step: listQuizes[quizId].step + 1 });
};
return (
<>
<Stepper activeStep={activeStep} desc={"Установите квиз"} />
<Box sx={{ marginTop: "60px", display: "flex", gap: "40px" }}>
<Paper
sx={{
@ -416,7 +413,7 @@ export default function InstallQuiz() {
>
<ArrowLeft />
</Button>
<Button variant="contained">Запустить рекламу</Button>
<Button variant="contained" onClick={handleNext}>Запустить рекламу</Button>
</Box>
<Modal

@ -45,7 +45,7 @@ export const AnswerItem = ({
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isTablet = useMediaQuery(theme.breakpoints.down(790));
const debounced = useDebouncedCallback((value) => {
const answerNew = variants.slice();
answerNew[index].answer = value;
@ -72,7 +72,7 @@ export const AnswerItem = ({
const addNewAnswer = () => {
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
answerNew.push({ answer: "", hints: "", emoji: "", image: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
@ -114,7 +114,12 @@ export const AnswerItem = ({
key={index}
fullWidth
variant="standard"
sx={{ padding: isMobile ? " 15px 0 15px 0" : "0 0 18px 0" }}
sx={{
margin: isTablet ? " 15px 0 20px 0" : "0 0 20px 0",
borderRadius: "10px",
border: "1px solid rgba(0, 0, 0, 0.23)",
background: "white",
}}
>
<TextField
defaultValue={variant.answer}
@ -124,23 +129,41 @@ export const AnswerItem = ({
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
onChange={({ target }) => debounced(target.value)}
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
if (event.code === "Enter" && !listQuestions[quizId][totalIndex].content.largeCheck) {
if (
event.code === "Enter" &&
!listQuestions[quizId][totalIndex].content.largeCheck
) {
addNewAnswer();
}
}}
InputProps={{
startAdornment: (
<>
<InputAdornment {...provided.dragHandleProps} position="start">
<PointsIcon style={{ color: "#9A9AAF", fontSize: "30px" }} />
<InputAdornment
{...provided.dragHandleProps}
position="start"
>
<PointsIcon
style={{ color: "#9A9AAF", fontSize: "30px" }}
/>
</InputAdornment>
{icon && icon}
</>
),
endAdornment: (
<InputAdornment position="end">
<IconButton sx={{ padding: "0" }} aria-describedby="my-popover-id" onClick={handleClick}>
<MessageIcon style={{ color: "#9A9AAF", fontSize: "30px", marginRight: "6.5px" }} />
<IconButton
sx={{ padding: "0" }}
aria-describedby="my-popover-id"
onClick={handleClick}
>
<MessageIcon
style={{
color: "#9A9AAF",
fontSize: "30px",
marginRight: "6.5px",
}}
/>
</IconButton>
<Popover
id="my-popover-id"
@ -154,11 +177,18 @@ export const AnswerItem = ({
placeholder="Подсказка для этого ответа"
value={variant.hints}
onChange={changeAnswerHint}
onKeyDown={(event: KeyboardEvent<HTMLTextAreaElement>) => event.stopPropagation()}
onKeyDown={(
event: KeyboardEvent<HTMLTextAreaElement>
) => event.stopPropagation()}
/>
</Popover>
<IconButton sx={{ padding: "0" }} onClick={deleteAnswer}>
<DeleteIcon style={{ color: theme.palette.grey2.main, marginRight: "-1px" }} />
<DeleteIcon
style={{
color: theme.palette.grey2.main,
marginRight: "-1px",
}}
/>
</IconButton>
</InputAdornment>
),

@ -27,7 +27,7 @@ export default function DropDown({ totalIndex }: Props) {
const addNewAnswer = () => {
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
answerNew.push({ answer: "", hints: "", emoji: "", image: "" });
updateQuestionsList(quizId, totalIndex, {
content: {

@ -1,5 +1,11 @@
import { useParams } from "react-router-dom";
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
import {
Box,
Typography,
Tooltip,
useMediaQuery,
useTheme,
} from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox";
import CustomTextField from "@ui_kit/CustomTextField";
import { useDebouncedCallback } from "use-debounce";
@ -38,6 +44,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
sx={{
position: "relative",
display: "flex",
gap: "20px",
width: "100%",
justifyContent: "space-between",
flexDirection: isMobile ? "column" : null,
@ -56,7 +63,12 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
}}
>
<Typography
sx={{ height: isMobile ? "18px" : "auto", fontWeight: "500", fontSize: "18px", color: " #4D4D4D" }}
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
Настройки ответов
</Typography>
@ -72,7 +84,12 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
})
}
/>
<Box sx={{ display: isMobile ? "none" : "block", mt: isMobile ? "11px" : "6px" }}>
<Box
sx={{
display: isMobile ? "none" : "block",
mt: isMobile ? "11px" : "6px",
}}
>
<Typography
sx={{
height: isMobile ? "18px" : "auto",
@ -104,7 +121,12 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
}}
>
<Typography
sx={{ height: isMobile ? "18px" : "auto", fontWeight: "500", fontSize: "18px", color: " #4D4D4D" }}
sx={{
height: isMobile ? "18px" : "auto",
fontWeight: "500",
fontSize: "18px",
color: " #4D4D4D",
}}
>
Настройки вопросов
</Typography>
@ -135,13 +157,14 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
});
}}
/>
<InfoIcon
sx={{
position: isMobile ? "absolute" : null,
display: "block",
right: isMobile ? "30px" : null,
}}
/>
<Tooltip
title="Будет отображаться как заголовок вопроса в приходящих заявках."
placement="top"
>
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
<Box
sx={{

@ -6,11 +6,7 @@ import {
Typography,
useMediaQuery,
useTheme,
IconButton,
InputAdornment,
Popover,
TextField,
TextareaAutosize,
} from "@mui/material";
import { EnterIcon } from "../../../assets/icons/questionsPage/enterIcon";
import ButtonsOptions from "../ButtonsOptions";
@ -21,12 +17,8 @@ import { EmojiIcons } from "@icons/EmojiIocns";
import { questionStore, updateQuestionsList } from "@root/questions";
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
import { MessageIcon } from "@icons/messagIcon";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import { ImageAddIcons } from "@icons/ImageAddIcons";
import AddEmoji from "../../../assets/icons/questionsPage/addEmoji";
import PlusImage from "../../../assets/icons/questionsPage/plus";
import AddEmoji from "@icons/questionsPage/addEmoji";
import PlusImage from "@icons/questionsPage/plus";
interface Props {
totalIndex: number;
@ -48,121 +40,14 @@ export default function Emoji({ totalIndex }: Props) {
return (
<>
{/* <Box sx={{ padding: "0 20px 0px 20px" }}>
<Box
sx={{
width: "100%",
border: "1px solid #9A9AAF",
borderRadius: "8px",
marginBottom: "15px",
}}
>
<TextField
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
InputProps={{
startAdornment: (
<>
<InputAdornment position="start">
<PointsIcon style={{ color: "#9A9AAF", fontSize: "30px" }} />
</InputAdornment>
{!isMobile && (
<Box
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
display: "flex",
justifyContent: "space-between",
marginRight: "20px",
marginLeft: "12px",
}}
>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", width: "40px" }}>
<EmojiIcons fontSize="22px" color="#7E2AEA" />
</Box>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "20px",
color: "white",
fontSize: "15px",
}}
>
+
</span>
</Box>
)}
</>
),
endAdornment: (
<InputAdornment position="end">
<IconButton sx={{ padding: "0" }} aria-describedby="my-popover-id">
<MessageIcon style={{ color: "#9A9AAF", fontSize: "30px", marginRight: "6.5px" }} />
</IconButton>
<Popover id="my-popover-id" anchorOrigin={{ vertical: "bottom", horizontal: "left" }} open={false}>
<TextareaAutosize style={{ margin: "10px" }} placeholder="Подсказка для этого ответа" />
</Popover>
<IconButton sx={{ padding: "0" }}>
<DeleteIcon style={{ color: theme.palette.grey2.main, marginRight: "-1px" }} />
</IconButton>
</InputAdornment>
),
}}
sx={{
"& .MuiInputBase-root": {
padding: "13.5px",
borderRadius: "10px",
background: "#ffffff",
height: "48px",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
}}
inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
}}
/>
{isMobile && (
<Box sx={{ display: "flex", alignItems: "center", m: "8px", position: "relative" }}>
<Box sx={{ width: "100%", background: "#EEE4FC", height: "40px" }} />
<ImageAddIcons
style={{ position: "absolute", color: "#7E2AEA", fontSize: "20px", left: "45%", right: "55%" }}
/>
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
}}
>
+
</Box>
</Box>
)}
</Box>
<Box sx={{ display: "flex", alignItems: "center", marginBottom: "20px" }}> */}
<Box sx={{ padding: "0 20px 0px 20px" }}>
<Box sx={{ padding: "20px" }}>
<AnswerDraggableList
variants={listQuestions[quizId][totalIndex].content.variants}
totalIndex={totalIndex}
additionalContent={(variant, index) => (
<>
{!isTablet && (
<Box sx={{ cursor: "pointer", margin: "0 15px 0 5px" }}>
<Box sx={{ cursor: "pointer" }}>
<Box
onClick={({ currentTarget }) => {
setAnchorElement(currentTarget);
@ -181,16 +66,26 @@ export default function Emoji({ totalIndex }: Props) {
{variant.emoji ? (
<Box
sx={{
width: "30px",
height: "40px",
width: "60px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
background: "#EEE4FC",
borderRadius: "3px",
marginRight: "15px",
}}
>
<Box sx={{ marginLeft: "3px" }}>{variant.emoji}</Box>
<Box sx={{ marginLeft: "-3px" }}>
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "center",
}}
>
{variant.emoji}
</Box>
<Box>
<PlusImage />
</Box>
</Box>
@ -308,8 +203,9 @@ export default function Emoji({ totalIndex }: Props) {
variant="body2"
sx={{ color: theme.palette.brightPurple.main }}
onClick={() => {
const answerNew = listQuestions[quizId][totalIndex].content.variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
const answerNew =
listQuestions[quizId][totalIndex].content.variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "", image: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
@ -333,7 +229,13 @@ export default function Emoji({ totalIndex }: Props) {
>
или нажмите Enter
</Typography>
<EnterIcon style={{ color: "#7E2AEA", fontSize: "24px", marginLeft: "6px" }} />
<EnterIcon
style={{
color: "#7E2AEA",
fontSize: "24px",
marginLeft: "6px",
}}
/>
</>
)}
</Box>

@ -1,18 +1,25 @@
import { useState } from "react";
import {
Box,
Link,
Typography,
ButtonBase,
useTheme,
useMediaQuery,
InputAdornment,
IconButton,
Button,
Popover,
TextareaAutosize,
TextField,
} from "@mui/material";
import { useParams } from "react-router-dom";
import AddImage from "../../../assets/icons/questionsPage/addImage";
import { AnswerDraggableList } from "../AnswerDraggableList";
import { CropModal } from "@ui_kit/Modal/CropModal";
import { UploadImageModal } from "../UploadImage/UploadImageModal";
import AddImage from "@icons/questionsPage/addImage";
import Image from "@icons/questionsPage/image";
import { EnterIcon } from "../../../assets/icons/questionsPage/enterIcon";
import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict";
import SwitchOptionsAndPict from "./switchOptionsAndPict";
@ -22,206 +29,330 @@ import { ImageAddIcons } from "@icons/ImageAddIcons";
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
import { MessageIcon } from "@icons/messagIcon";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import PlusImage from "@icons/questionsPage/plus";
interface Props {
totalIndex: number;
}
export default function OptionsAndPicture({ totalIndex }: Props) {
const [switchState, setSwitchState] = React.useState("setting");
const { listQuestions } = questionStore();
const quizId = Number(useParams().quizId);
const [open, setOpen] = useState(false);
const [opened, setOpened] = useState<boolean>(false);
const [switchState, setSwitchState] = useState("setting");
const [currentIndex, setCurrentIndex] = useState<number>(0);
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const SSHC = (data: string) => {
setSwitchState(data);
};
const uploadImage = (files: FileList | null) => {
if (files?.length) {
const [file] = Array.from(files);
const clonContent = { ...listQuestions[quizId][totalIndex].content };
clonContent.variants[currentIndex].image = URL.createObjectURL(file);
updateQuestionsList(quizId, totalIndex, { content: clonContent });
setOpen(false);
setOpened(true);
}
};
return (
<>
<Box sx={{ pl: "20px", pr: "20px" }}>
<Box
sx={{
display: "flex",
alignItems: "center",
paddingBottom: isMobile ? "15px" : "24px",
marginTop: isMobile ? "15px" : "4px",
height: isMobile ? "auto" : "40px",
marginLeft: isTablet ? "0px" : "60px",
}}
>
{listQuestions[quizId][totalIndex].content.variants.map((_, index) => (
<ButtonBase
key={index}
component="label"
sx={{
display: isTablet ? "none" : "flex",
cursor: "pointer",
alignItems: "center",
justifyContent: "flex-start",
}}
>
<input
onChange={({ target }) => {
if (target.files?.length) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.variants[index].answer = URL.createObjectURL(target.files[0]);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}
}}
hidden
accept="image/*"
multiple
type="file"
/>
<Box sx={{ display: isTablet ? "none" : "flex", alignItems: "center" }}>
<AnswerDraggableList
variants={listQuestions[quizId][totalIndex].content.variants}
totalIndex={totalIndex}
additionalContent={(variant, index) => (
<>
{!isMobile && (
<Box
sx={{ cursor: "pointer" }}
onClick={() => {
setCurrentIndex(index);
setOpen(true);
}}
>
{variant.image ? (
<Box
sx={{
overflow: "hidden",
width: "60px",
display: "flex",
alignItems: "center",
background: "#EEE4FC",
borderRadius: "3px",
margin: "0 10px",
height: "40px",
}}
>
<Box sx={{ display: "flex", width: "40px" }}>
<img
src={variant.image}
alt=""
style={{ width: "100%" }}
/>
</Box>
<PlusImage />
</Box>
) : (
<Button component="label" sx={{ padding: "0px" }}>
<AddImage
sx={{
height: "40px",
width: "60px",
margin: "0 10px",
}}
/>
</Button>
)}
</Box>
)}
</>
)}
additionalMobile={(variant, index) => (
<>
{isMobile && (
<Box
onClick={() => {
setCurrentIndex(index);
setOpen(true);
}}
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
overflow: "hidden",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
m: "8px",
position: "relative",
borderRadius: "3px",
}}
>
<Box
sx={{
width: "100%",
background: "#EEE4FC",
height: "40px",
display: "flex",
alignItems: "center",
justifyContent: "center",
width: "100%",
maxHeight: "98px",
}}
>
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
{variant.image ? (
<Box
sx={{
overflow: "hidden",
width: "40px",
display: "flex",
alignItems: "center",
background: "#EEE4FC",
height: "30px",
borderRadius: "3px",
}}
>
<img
src={variant.image}
alt=""
style={{ width: "100%" }}
/>
</Box>
) : (
<Button component="label" sx={{ padding: "0px" }}>
<Image
sx={{
height: "40px",
width: "60px",
margin: "0 10px",
}}
/>
</Button>
)}
</Box>
<span
style={{
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "25px",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
fontSize: "15px",
backgroundColor: "#7E2AEA",
}}
>
+
</span>
</Box>
</Box>
<Typography
sx={{
padding: "0 0 0 20px",
fontWeight: 400,
fontSize: "18px",
lineHeight: "21.33px",
color: theme.palette.grey2.main,
}}
>
Добавьте ответ
</Typography>
</Box>
</ButtonBase>
))}
<Box
sx={{
width: "100%",
border: "1px solid #9A9AAF",
borderRadius: "8px",
display: isTablet ? "block" : "none",
}}
>
<TextField
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
InputProps={{
startAdornment: (
<>
<InputAdornment position="start">
<PointsIcon style={{ color: "#9A9AAF", fontSize: "30px" }} />
</InputAdornment>
{!isMobile && (
)}
</>
)}
/>
<UploadImageModal
open={open}
onClose={() => setOpen(false)}
imgHC={uploadImage}
/>
<CropModal
opened={opened}
onClose={() => setOpened(false)}
picture={
listQuestions[quizId][totalIndex].content.variants[currentIndex]
.image
}
/>
<Box
sx={{
width: "100%",
border: "1px solid #9A9AAF",
borderRadius: "8px",
display: isTablet ? "block" : "none",
}}
>
<TextField
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
InputProps={{
startAdornment: (
<>
<InputAdornment position="start">
<PointsIcon
style={{ color: "#9A9AAF", fontSize: "30px" }}
/>
</InputAdornment>
{!isMobile && (
<Box
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
display: "flex",
justifyContent: "space-between",
marginRight: "20px",
marginLeft: "12px",
}}
>
<Box
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
display: "flex",
justifyContent: "space-between",
marginRight: "20px",
marginLeft: "12px",
alignItems: "center",
justifyContent: "center",
width: "100%",
}}
>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", width: "100%" }}>
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
</Box>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "25px",
color: "white",
fontSize: "15px",
}}
>
+
</span>
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
</Box>
)}
</>
),
endAdornment: (
<InputAdornment position="end">
<IconButton sx={{ padding: "0" }} aria-describedby="my-popover-id">
<MessageIcon style={{ color: "#9A9AAF", fontSize: "30px", marginRight: "6.5px" }} />
</IconButton>
<Popover id="my-popover-id" anchorOrigin={{ vertical: "bottom", horizontal: "left" }} open={false}>
<TextareaAutosize style={{ margin: "10px" }} placeholder="Подсказка для этого ответа" />
</Popover>
<IconButton sx={{ padding: "0" }}>
<DeleteIcon style={{ color: theme.palette.grey2.main, marginRight: "-1px" }} />
</IconButton>
</InputAdornment>
),
}}
sx={{
"& .MuiInputBase-root": {
padding: "13.5px",
borderRadius: "10px",
background: "#ffffff",
height: isMobile ? "41px" : "48px",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
}}
inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
}}
/>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "25px",
color: "white",
fontSize: "15px",
}}
>
+
</span>
</Box>
)}
</>
),
endAdornment: (
<InputAdornment position="end">
<IconButton
sx={{ padding: "0" }}
aria-describedby="my-popover-id"
>
<MessageIcon
style={{
color: "#9A9AAF",
fontSize: "30px",
marginRight: "6.5px",
}}
/>
</IconButton>
<Popover
id="my-popover-id"
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
open={false}
>
<TextareaAutosize
style={{ margin: "10px" }}
placeholder="Подсказка для этого ответа"
/>
</Popover>
<IconButton sx={{ padding: "0" }}>
<DeleteIcon
style={{
color: theme.palette.grey2.main,
marginRight: "-1px",
}}
/>
</IconButton>
</InputAdornment>
),
}}
sx={{
"& .MuiInputBase-root": {
padding: "13.5px",
borderRadius: "10px",
background: "#ffffff",
height: "48px",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
}}
inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
}}
/>
{isMobile && (
{isMobile && (
<Box
sx={{
display: "flex",
alignItems: "center",
m: "8px",
position: "relative",
}}
>
<Box
sx={{ width: "100%", background: "#EEE4FC", height: "40px" }}
/>
<ImageAddIcons
style={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
/>
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
m: "8px",
position: "relative",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
}}
>
<Box sx={{ width: "100%", background: "#EEE4FC", height: "40px" }} />
<Box
sx={{ width: "100%", background: "#EEE4FC", height: "40px" }}
/>
<ImageAddIcons
style={{
position: "absolute",
@ -246,8 +377,8 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
+
</Box>
</Box>
)}
</Box>
</Box>
)}
</Box>
<Box
sx={{
@ -268,7 +399,12 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
}}
onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.variants.push({ answer: "", hints: "", emoji: "" });
clonContent.variants.push({
answer: "",
hints: "",
emoji: "",
image: "",
});
updateQuestionsList(quizId, totalIndex, { content: clonContent });
}}
@ -287,12 +423,22 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
>
или нажмите Enter
</Typography>
<EnterIcon style={{ color: "#7E2AEA", fontSize: "24px", marginLeft: "6px" }} />
<EnterIcon
style={{
color: "#7E2AEA",
fontSize: "24px",
marginLeft: "6px",
}}
/>
</>
)}
</Box>
</Box>
<ButtonsOptionsAndPict switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
<ButtonsOptionsAndPict
switchState={switchState}
SSHC={SSHC}
totalIndex={totalIndex}
/>
<SwitchOptionsAndPict switchState={switchState} totalIndex={totalIndex} />
</>
);

@ -6,35 +6,32 @@ import {
Typography,
Button,
useTheme,
useMediaQuery,
InputAdornment,
IconButton,
TextareaAutosize,
Popover,
TextField,
useMediaQuery
} from "@mui/material";
import ButtonsOptions from "../ButtonsOptions";
import { AnswerDraggableList } from "../AnswerDraggableList";
import { CropModal } from "@ui_kit/Modal/CropModal";
import { UploadImageModal } from "../UploadImage/UploadImageModal";
import { questionStore, updateQuestionsList } from "@root/questions";
import { EnterIcon } from "../../../assets/icons/questionsPage/enterIcon";
import AddImage from "../../../assets/icons/questionsPage/addImage";
import Image from "../../../assets/icons/questionsPage/image";
import SwitchAnswerOptionsPict from "./switchOptionsPict";
import type { ChangeEvent } from "react";
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
import { MessageIcon } from "@icons/messagIcon";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import { ImageAddIcons } from "@icons/ImageAddIcons";
import PlusImage from "@icons/questionsPage/plus";
interface Props {
totalIndex: number;
}
export default function OptionsPicture({ totalIndex }: Props) {
const [open, setOpen] = useState(false);
const [opened, setOpened] = useState<boolean>(false);
const [currentIndex, setCurrentIndex] = useState<number>(0);
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isTablet = useMediaQuery(theme.breakpoints.down(790));
const quizId = Number(useParams().quizId);
const [switchState, setSwitchState] = useState("setting");
const { listQuestions } = questionStore();
@ -43,216 +40,176 @@ export default function OptionsPicture({ totalIndex }: Props) {
setSwitchState(data);
};
const addImage = ({ target }: ChangeEvent<HTMLInputElement>) => {
if (target.files?.length) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.images.push(URL.createObjectURL(target.files[0]));
const uploadImage = (files: FileList | null) => {
if (files?.length) {
const [file] = Array.from(files);
const clonContent = { ...listQuestions[quizId][totalIndex].content };
clonContent.variants[currentIndex].image = URL.createObjectURL(file);
updateQuestionsList(quizId, totalIndex, { content: clonContent });
setOpen(false);
setOpened(true);
}
};
const addNewAnswer = () => {
const answerNew =
listQuestions[quizId][totalIndex].content.variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "", image: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
});
};
return (
<>
<Box sx={{ pl: "20px", pr: "20px" }}>
<Box
sx={{
display: "flex",
alignItems: "center",
paddingBottom: isMobile ? "15px" : "20px",
marginTop: isMobile ? "15px" : "4px",
height: isMobile ? "auto" : "40px",
marginLeft: isTablet ? "0px" : "60px",
}}
>
<input type="file" hidden onChange={addImage} />
<Box sx={{ display: isTablet ? "none" : "flex", alignItems: "center" }}>
<Box
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
display: "flex",
justifyContent: "space-between",
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
width: "100%",
maxHeight: "98px",
}}
>
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
</Box>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "25px",
color: "white",
fontSize: "15px",
}}
>
+
</span>
</Box>
<Typography
sx={{
padding: "0 0 0 20px",
fontWeight: 400,
fontSize: "18px",
lineHeight: "21.33px",
color: theme.palette.grey2.main,
}}
>
Добавьте ответ
</Typography>
</Box>
<Box
sx={{
width: "100%",
border: "1px solid #9A9AAF",
borderRadius: "8px",
display: isTablet ? "block" : "none",
}}
>
<TextField
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
InputProps={{
startAdornment: (
<>
<InputAdornment position="start">
<PointsIcon style={{ color: "#9A9AAF", fontSize: "30px" }} />
</InputAdornment>
{!isMobile && (
<Box
sx={{
width: "60px",
height: "40px",
background: "#EEE4FC",
display: "flex",
justifyContent: "space-between",
marginRight: "20px",
marginLeft: "12px",
}}
>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", width: "100%" }}>
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
</Box>
<span
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "#7E2AEA",
height: "100%",
width: "25px",
color: "white",
fontSize: "15px",
}}
>
+
</span>
</Box>
)}
</>
),
endAdornment: (
<InputAdornment position="end">
<IconButton sx={{ padding: "0" }} aria-describedby="my-popover-id">
<MessageIcon style={{ color: "#9A9AAF", fontSize: "30px", marginRight: "6.5px" }} />
</IconButton>
<Popover id="my-popover-id" anchorOrigin={{ vertical: "bottom", horizontal: "left" }} open={false}>
<TextareaAutosize style={{ margin: "10px" }} placeholder="Подсказка для этого ответа" />
</Popover>
<IconButton sx={{ padding: "0" }}>
<DeleteIcon style={{ color: theme.palette.grey2.main, marginRight: "-1px" }} />
</IconButton>
</InputAdornment>
),
}}
sx={{
"& .MuiInputBase-root": {
padding: "13.5px",
borderRadius: "10px",
background: "#ffffff",
height: isMobile ? "41px" : "48px",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
}}
inputProps={{
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
}}
/>
{isMobile && (
<Box
sx={{
display: "flex",
alignItems: "center",
m: "8px",
position: "relative",
}}
>
<Box sx={{ width: "100%", background: "#EEE4FC", height: "40px" }} />
<ImageAddIcons
style={{
position: "absolute",
color: "#7E2AEA",
fontSize: "20px",
left: "45%",
right: "55%",
}}
/>
<Box sx={{ padding: "20px" }}>
<AnswerDraggableList
variants={listQuestions[quizId][totalIndex].content.variants}
totalIndex={totalIndex}
additionalContent={(variant, index) => (
<>
{!isMobile && (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
sx={{ cursor: "pointer" }}
onClick={() => {
setCurrentIndex(index);
setOpen(true);
}}
>
+
{variant.image ? (
<Box
sx={{
overflow: "hidden",
width: "60px",
display: "flex",
alignItems: "center",
background: "#EEE4FC",
borderRadius: "3px",
margin: "0 10px",
height: "40px",
}}
>
<Box sx={{ display: "flex", width: "40px" }}>
<img
src={variant.image}
alt=""
style={{ width: "100%" }}
/>
</Box>
<PlusImage />
</Box>
) : (
<Button component="label" sx={{ padding: "0px" }}>
<AddImage
sx={{ height: "40px", width: "60px", margin: "0 10px" }}
/>
</Button>
)}
</Box>
</Box>
)}
</Box>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
marginBottom: "17px",
}}
>
)}
</>
)}
additionalMobile={(variant, index) => (
<>
{isMobile && (
<Box
onClick={() => {
setCurrentIndex(index);
setOpen(true);
}}
sx={{
overflow: "hidden",
display: "flex",
alignItems: "center",
m: "8px",
position: "relative",
borderRadius: "3px",
}}
>
<Box
sx={{
width: "100%",
background: "#EEE4FC",
height: "40px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{variant.image ? (
<Box
sx={{
overflow: "hidden",
width: "40px",
display: "flex",
alignItems: "center",
background: "#EEE4FC",
height: "30px",
borderRadius: "3px",
}}
>
<img
src={variant.image}
alt=""
style={{ width: "100%" }}
/>
</Box>
) : (
<Button component="label" sx={{ padding: "0px" }}>
<Image
sx={{
height: "40px",
width: "60px",
margin: "0 10px",
}}
/>
</Button>
)}
</Box>
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "20px",
background: "#EEE4FC",
height: "40px",
color: "white",
backgroundColor: "#7E2AEA",
}}
>
+
</Box>
</Box>
)}
</>
)}
/>
<UploadImageModal
open={open}
onClose={() => setOpen(false)}
imgHC={uploadImage}
/>
<CropModal
opened={opened}
onClose={() => setOpened(false)}
picture={
listQuestions[quizId][totalIndex].content.variants[currentIndex]
.image
}
/>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Link
component="button"
variant="body2"
sx={{
color: theme.palette.brightPurple.main,
fontWeight: "400",
fontSize: "16px",
mr: "4px",
height: "19px",
}}
sx={{ color: theme.palette.brightPurple.main }}
onClick={addNewAnswer}
>
Добавьте ответ
</Link>
@ -268,7 +225,13 @@ export default function OptionsPicture({ totalIndex }: Props) {
>
или нажмите Enter
</Typography>
<EnterIcon style={{ color: "#7E2AEA", fontSize: "24px", marginLeft: "6px" }} />
<EnterIcon
style={{
color: "#7E2AEA",
fontSize: "24px",
marginLeft: "6px",
}}
/>
</>
)}
</Box>

@ -163,19 +163,6 @@ export default function SettingOpytionsPict({ totalIndex }: SettingOpytionsPictP
}
/>
)}
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Большие картинки"}
checked={listQuestions[quizId][totalIndex].content.own}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
own: target.checked,
},
})
}
/>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}

@ -7,6 +7,7 @@ import {
Select,
SelectChangeEvent,
Typography,
Tooltip,
useMediaQuery,
useTheme,
} from "@mui/material";
@ -166,7 +167,11 @@ export default function UploadFile({ totalIndex }: Props) {
>
Пользователь может загрузить любой собственный файл
</Typography>
<InfoIcon />
<Tooltip title="Можно загрузить файл в желаемом формате." placement="top">
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
</Box>
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />

@ -25,7 +25,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
const addNewAnswer = () => {
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
answerNew.push({ answer: "", hints: "", emoji: "", image: "" });
updateQuestionsList(quizId, totalIndex, {
content: {

@ -11,10 +11,15 @@ import {
Modal,
Radio,
RadioGroup,
Tooltip,
Typography,
useTheme,
} from "@mui/material";
import { questionStore, resetSomeField, updateQuestionsList } from "@root/questions";
import {
questionStore,
resetSomeField,
updateQuestionsList,
} from "@root/questions";
import { Select } from "./Select";
import RadioCheck from "@ui_kit/RadioCheck";
@ -29,15 +34,22 @@ type BranchingQuestionsProps = {
const ACTIONS = ["Показать", "Скрыть"];
const STIPULATIONS = ["Условие 1", "Условие 2", "Условие 3"];
const ANSWERS = ["Ответ 1", "Ответ 2", "Ответ 3"];
const CONDITIONS = ["Все условия обязательны", "Обязательно хотя бы одно условие"];
const CONDITIONS = [
"Все условия обязательны",
"Обязательно хотя бы одно условие",
];
export default function BranchingQuestions({ totalIndex }: BranchingQuestionsProps) {
export default function BranchingQuestions({
totalIndex,
}: BranchingQuestionsProps) {
const theme = useTheme();
const [titleInputWidth, setTitleInputWidth] = useState<number>(0);
const quizId = Number(useParams().quizId);
const { openedModalSettings, listQuestions } = questionStore();
const titleRef = useRef<HTMLDivElement>(null);
const [title, setTitle] = useState<string>(listQuestions[quizId][totalIndex].title)
const [title, setTitle] = useState<string>(
listQuestions[quizId][totalIndex].title
);
useEffect(() => {
setTitleInputWidth(titleRef.current?.offsetWidth || 0);
@ -74,9 +86,10 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
sx={{
boxSizing: "border-box",
background: "#F2F3F7",
padding: "25px",
height: "70px",
padding: "0 25px",
display: "flex",
alignItems: "center",
}}
>
<Box sx={{ color: "#9A9AAF" }}>
@ -113,7 +126,14 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
</Box>
<Typography component="span">)</Typography>
</Box>
<InfoIcon width={24} height={24} />
<Tooltip
title="Настройте условия, при которых данный вопрос будет отображаться в квизе."
placement="top"
>
<Box>
<InfoIcon />
</Box>
</Tooltip>
</Box>
<Box
sx={{
@ -132,7 +152,9 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
>
<Select
items={ACTIONS}
activeItemIndex={listQuestions[quizId][totalIndex].content.rule.show ? 0 : 1}
activeItemIndex={
listQuestions[quizId][totalIndex].content.rule.show ? 0 : 1
}
sx={{ maxWidth: "140px" }}
onChange={(action) => {
const clonContent = listQuestions[quizId][totalIndex].content;
@ -142,126 +164,157 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
});
}}
/>
<Typography sx={{ color: theme.palette.grey2.main }}>если в ответе на вопрос</Typography>
<Typography sx={{ color: theme.palette.grey2.main }}>
если в ответе на вопрос
</Typography>
</Box>
{listQuestions[quizId][totalIndex].content.rule.reqs.map((request, index) => (
<Box
key={index}
sx={{
padding: "20px",
borderRadius: "8px",
height: "100%",
bgcolor: "#F2F3F7",
}}
>
{listQuestions[quizId][totalIndex].content.rule.reqs.map(
(request, index) => (
<Box
key={index}
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
padding: "20px",
borderRadius: "8px",
height: "100%",
bgcolor: "#F2F3F7",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>Условие 1</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<DeleteIcon style={{ color: "#4D4D4D" }} />
</IconButton>
</Box>
<Select
empty
activeItemIndex={request.id ? Number(request.id) : -1}
items={STIPULATIONS}
onChange={(stipulation) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs[index] = {
id: String(STIPULATIONS.findIndex((item) => item.includes(stipulation))),
vars: request.vars,
};
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
sx={{ marginBottom: "15px" }}
/>
{request.id && (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>Дан ответ</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
<Select
empty
activeItemIndex={-1}
items={ANSWERS}
onChange={(answer) => {
const clonContent = listQuestions[quizId][totalIndex].content;
const answerItemIndex = ANSWERS.findIndex((answerItem) => answerItem === answer);
if (!clonContent.rule.reqs[index].vars.includes(answerItemIndex)) {
listQuestions[quizId][totalIndex].content.rule.reqs[index].vars.push(answerItemIndex);
}
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Условие 1
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
sx={{
marginBottom: "10px",
".MuiSelect-select.MuiInputBase-input": {
color: "transparent",
},
}}
/>
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
{listQuestions[quizId][totalIndex].content.rule.reqs[index].vars.map((item, varIndex) => (
<Chip
key={varIndex}
label={ANSWERS[item]}
variant="outlined"
onDelete={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
const removedItemIndex = clonContent.rule.reqs[index].vars.findIndex(
(varItem) => varItem === item
);
<DeleteIcon style={{ color: "#4D4D4D" }} />
</IconButton>
</Box>
<Select
empty
activeItemIndex={request.id ? Number(request.id) : -1}
items={STIPULATIONS}
onChange={(stipulation) => {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs[index].vars.splice(removedItemIndex, 1);
clonContent.rule.reqs[index] = {
id: String(
STIPULATIONS.findIndex((item) =>
item.includes(stipulation)
)
),
vars: request.vars,
};
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
/>
))}
</Box>
</>
)}
</Box>
))}
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
sx={{ marginBottom: "15px" }}
/>
{request.id && (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography
sx={{ color: "#4D4D4D", fontWeight: "500" }}
>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
<Select
empty
activeItemIndex={-1}
items={ANSWERS}
onChange={(answer) => {
const clonContent =
listQuestions[quizId][totalIndex].content;
const answerItemIndex = ANSWERS.findIndex(
(answerItem) => answerItem === answer
);
if (
!clonContent.rule.reqs[index].vars.includes(
answerItemIndex
)
) {
listQuestions[quizId][totalIndex].content.rule.reqs[
index
].vars.push(answerItemIndex);
}
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
sx={{
marginBottom: "10px",
".MuiSelect-select.MuiInputBase-input": {
color: "transparent",
},
}}
/>
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
{listQuestions[quizId][totalIndex].content.rule.reqs[
index
].vars.map((item, varIndex) => (
<Chip
key={varIndex}
label={ANSWERS[item]}
variant="outlined"
onDelete={() => {
const clonContent =
listQuestions[quizId][totalIndex].content;
const removedItemIndex = clonContent.rule.reqs[
index
].vars.findIndex((varItem) => varItem === item);
clonContent.rule.reqs[index].vars.splice(
removedItemIndex,
1
);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
/>
))}
</Box>
</>
)}
</Box>
)
)}
<Box
sx={{
display: "flex",
@ -288,9 +341,12 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
<FormControl>
<RadioGroup
aria-labelledby="demo-controlled-radio-buttons-group"
value={listQuestions[quizId][totalIndex].content.rule.or ? 1 : 0}
value={
listQuestions[quizId][totalIndex].content.rule.or ? 1 : 0
}
onChange={(_, value) => {
const clonContent = listQuestions[quizId][totalIndex].content;
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.or = Boolean(Number(value));
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
@ -302,7 +358,12 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
key={index}
sx={{ color: theme.palette.grey2.main }}
value={index}
control={<Radio checkedIcon={<RadioCheck />} icon={<RadioIcon />} />}
control={
<Radio
checkedIcon={<RadioCheck />}
icon={<RadioIcon />}
/>
}
label={condition}
/>
))}
@ -310,10 +371,18 @@ export default function BranchingQuestions({ totalIndex }: BranchingQuestionsPro
</FormControl>
</Box>
<Box sx={{ display: "flex", justifyContent: "end", gap: "10px" }}>
<Button variant="outlined" onClick={handleClose} sx={{ width: "100%", maxWidth: "130px" }}>
<Button
variant="outlined"
onClick={handleClose}
sx={{ width: "100%", maxWidth: "130px" }}
>
Отмена
</Button>
<Button variant="contained" sx={{ width: "100%", maxWidth: "130px" }} onClick={handleClose}>
<Button
variant="contained"
sx={{ width: "100%", maxWidth: "130px" }}
onClick={handleClose}
>
Готово
</Button>
</Box>

@ -1,18 +1,18 @@
import {Link, useParams} from "react-router-dom";
import {Box, Button, useTheme} from "@mui/material";
import { Link, useParams } from "react-router-dom";
import { Box, Button, useTheme } from "@mui/material";
import CreationFullCard from "./CreationFullCard";
import Info from "../../assets/icons/Info";
import image from "../../assets/Rectangle 110.png";
import {quizStore} from "@root/quizes";
import { quizStore } from "@root/quizes";
export const Result = () => {
const {listQuizes, updateQuizesList} = quizStore();
const params = Number(useParams().quizId);
const handleNext = () => {
updateQuizesList(params, {step: listQuizes[params].step + 1})
}
const { listQuizes, updateQuizesList } = quizStore();
const params = Number(useParams().quizId);
const handleNext = () => {
updateQuizesList(params, { createResult: true });
};
const theme = useTheme();
return (
<Box component="section">
@ -22,16 +22,16 @@ export const Result = () => {
image={image}
/>
<Box sx={{ mt: "30px", alignItems: "center" }}>
<Button
variant="contained"
sx={{
mr: "23px",
minWidth: "258px",
}}
onClick={handleNext}
>
Создать результаты
</Button>
<Button
variant="contained"
sx={{
mr: "23px",
minWidth: "258px",
}}
onClick={handleNext}
>
Создать результаты
</Button>
<Info />
</Box>

@ -2,7 +2,16 @@ import Stepper from "@ui_kit/Stepper";
import SwitchStepPages from "@ui_kit/switchStepPages";
import React, { useState } from "react";
import PenaLogo from "@ui_kit/PenaLogo";
import { Box, Button, Container, FormControl, IconButton, TextField, useMediaQuery, useTheme } from "@mui/material";
import {
Box,
Button,
Container,
FormControl,
IconButton,
TextField,
useMediaQuery,
useTheme,
} from "@mui/material";
import BackArrowIcon from "@icons/BackArrowIcon";
import NavMenuItem from "@ui_kit/Header/NavMenuItem";
import EyeIcon from "@icons/EyeIcon";
@ -14,6 +23,15 @@ import { Burger } from "@icons/Burger";
import { PenaLogoIcon } from "@icons/PenaLogoIcon";
import { SidebarMobile } from "./Sidebar/SidebarMobile";
const DESCRIPTIONS = [
"Настройка стартовой страницы",
"Задайте вопросы",
"Настройте авторезультаты",
"Настройте форму контактов",
"Установите квиз",
"Запустите рекламу",
] as const;
export default function StartPage() {
const { listQuizes, updateQuizesList, removeQuiz, createBlank } = quizStore();
const params = Number(useParams().quizId);
@ -24,10 +42,6 @@ export default function StartPage() {
const [mobileSidebar, setMobileSidebar] = useState<boolean>(false);
const handleNext = () => {
updateQuizesList(params, { step: listQuizes[params].step + 1 });
};
const handleBack = () => {
let result = listQuizes[params].step - 1;
updateQuizesList(params, { step: result ? result : 1 });
@ -50,7 +64,11 @@ export default function StartPage() {
zIndex: theme.zIndex.drawer + 1,
}}
>
{isMobile ? <PenaLogoIcon style={{ fontSize: "39px", color: "white" }} /> : <PenaLogo width={124} />}
{isMobile ? (
<PenaLogoIcon style={{ fontSize: "39px", color: "white" }} />
) : (
<PenaLogo width={124} />
)}
<Box
sx={{
display: isMobile ? "none" : "flex",
@ -104,7 +122,12 @@ export default function StartPage() {
/>
) : (
<CustomAvatar
sx={{ ml: "11px", backgroundColor: theme.palette.orange.main, height: "36px", width: "36px" }}
sx={{
ml: "11px",
backgroundColor: theme.palette.orange.main,
height: "36px",
width: "36px",
}}
/>
)}
</Box>
@ -157,7 +180,12 @@ export default function StartPage() {
Опубликовать
</Button>
<CustomAvatar
sx={{ ml: "11px", backgroundColor: theme.palette.orange.main, height: "36px", width: "36px" }}
sx={{
ml: "11px",
backgroundColor: theme.palette.orange.main,
height: "36px",
width: "36px",
}}
/>
</Box>
</>
@ -180,8 +208,16 @@ export default function StartPage() {
boxSizing: "border-box",
}}
>
<Stepper activeStep={activeStep} desc={"Настройка стартовой страницы"} />
<SwitchStepPages activeStep={activeStep} handleNext={handleNext} />
<Stepper
activeStep={activeStep}
desc={DESCRIPTIONS[activeStep - 1]}
/>
<SwitchStepPages
activeStep={activeStep}
quizType={listQuizes[params].config.type}
startpage={listQuizes[params].startpage}
createResult={listQuizes[params].createResult}
/>
</Box>
</Box>
</>

@ -36,10 +36,6 @@ import AlignCenterIcon from "@icons/AlignCenterIcon";
import DropFav from "./dropfavicon";
import { createQuestion } from "@root/questions";
interface HandleNext {
handleNext: () => void;
}
const designTypes = [
[
"standard",
@ -62,7 +58,7 @@ const designTypes = [
type BackgroundType = "image" | "video";
type AlignType = "left" | "right" | "center";
export default function StartPageSettings({ handleNext }: HandleNext) {
export default function StartPageSettings() {
const { listQuizes, updateQuizesList, removeQuiz, createBlank } = quizStore();
const params = Number(useParams().quizId);
const theme = useTheme();
@ -73,6 +69,10 @@ export default function StartPageSettings({ handleNext }: HandleNext) {
);
const [alignType, setAlignType] = useState<AlignType>("left");
const handleNext = () => {
updateQuizesList(params, { step: listQuizes[params].step + 1 });
};
const videoHC = (videoInp: HTMLInputElement) => {
const file = videoInp.files?.[0];

@ -5,11 +5,7 @@ import quizCreationImage2 from "../../assets/quiz-creation-2.png";
import {useParams} from "react-router-dom";
import {quizStore} from "@root/quizes";
interface HandleNext {
handleNext: () => void;
}
export default function StepOne({ handleNext }: HandleNext) {
export default function StepOne() {
const theme = useTheme();
const params = Number(useParams().quizId);
@ -28,7 +24,6 @@ export default function StepOne({ handleNext }: HandleNext) {
let SPageClone = listQuizes[params].config
SPageClone.type = "quize"
updateQuizesList(params, {config: SPageClone })
handleNext()
}
}>
<CreationCard
@ -42,7 +37,6 @@ export default function StepOne({ handleNext }: HandleNext) {
let SPageClone = listQuizes[params].config
SPageClone.type = "form"
updateQuizesList(params, {config: SPageClone })
handleNext()
}
}>
<CreationCard

@ -6,11 +6,7 @@ import cardImage3 from "../../assets/card-3.png";
import {quizStore} from "@root/quizes";
import {useParams} from "react-router-dom";
interface HandleNext {
handleNext: () => void
}
export default function Steptwo ({handleNext}:HandleNext) {
export default function Steptwo () {
const params = Number(useParams().quizId);
const {listQuizes, updateQuizesList} = quizStore()
return (
@ -27,7 +23,6 @@ export default function Steptwo ({handleNext}:HandleNext) {
<Button variant='text'
onClick={() => {
updateQuizesList(params, {startpage: "standard"})
handleNext()
}}
>
<CardWithImage image={cardImage1} text="Standard" border={listQuizes[params].startpage === "standard" ? "1px solid #7E2AEA" : "none"} />
@ -35,7 +30,6 @@ export default function Steptwo ({handleNext}:HandleNext) {
<Button variant='text'
onClick={() => {
updateQuizesList(params, {startpage: "expanded"})
handleNext()
}}
>
<CardWithImage image={cardImage2} text="Expanded" border={listQuizes[params].startpage === "expanded" ? "1px solid #7E2AEA" : "none"}/>
@ -43,7 +37,6 @@ export default function Steptwo ({handleNext}:HandleNext) {
<Button variant='text'
onClick={() => {
updateQuizesList(params, {startpage: "centered"})
handleNext()
}}
>
<CardWithImage image={cardImage3} text="Centered" border={listQuizes[params].startpage === "centered" ? "1px solid #7E2AEA" : "none"}/>

@ -5,6 +5,7 @@ export type Variants = {
answer: string;
hints: string;
emoji: string;
image: string;
};
type Hint = {
@ -36,7 +37,6 @@ export interface Question {
variants: Variants[];
hint: Hint;
rule: Rule;
images: string[];
largeCheck: boolean;
large: string;
multi: boolean;
@ -100,7 +100,6 @@ export const DEFAULT_QUESTION: Omit<Question, "id"> = {
type: "all",
autofill: true,
default: "",
images: [],
number: false,
single: false,
xy: "",
@ -125,6 +124,7 @@ export const DEFAULT_QUESTION: Omit<Question, "id"> = {
answer: "",
hints: "",
emoji: "",
image: "",
},
],
hint: {

@ -36,6 +36,7 @@ export interface Quizes {
group_id: number,
step: number,
startpage: string,
createResult: boolean,
config: {
type: string,
logo: string,
@ -118,6 +119,7 @@ export const quizStore = create<QuizStore>()(
"group_id": 0,
"step": 1,
"startpage": "",
"createResult": false,
"config": {
"noStartPage": false,
"type": "", // quiz или form

@ -1,5 +1,15 @@
import { useState } from "react";
import { Container, Box, useTheme, List, Typography, IconButton } from "@mui/material";
import { useParams } from "react-router-dom";
import {
Container,
Box,
useTheme,
List,
Typography,
IconButton,
} from "@mui/material";
import { quizStore } from "@root/quizes";
import MegaphoneIcon from "../assets/icons/MegaphoneIcon";
import QuestionIcon from "../assets/icons/QuestionIcon";
@ -33,8 +43,9 @@ const quizSettingsMenuItems = [
export default function Sidebar() {
const theme = useTheme();
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false);
const [activeMenuItemIndex, setActiveMenuItemIndex] = useState<number>(0);
const [progress, setProgress] = useState<number>(1 / 6);
const quizId = Number(useParams().quizId);
const { listQuizes, updateQuizesList } = quizStore();
const handleMenuCollapseToggle = () => setIsMenuCollapsed((prev) => !prev);
return (
@ -76,7 +87,10 @@ export default function Sidebar() {
Создание квиза
</Typography>
)}
<IconButton onClick={handleMenuCollapseToggle} sx={{ ml: isMenuCollapsed ? undefined : "auto" }}>
<IconButton
onClick={handleMenuCollapseToggle}
sx={{ ml: isMenuCollapsed ? undefined : "auto" }}
>
<CollapseMenuIcon
height="16px"
width="16px"
@ -90,15 +104,17 @@ export default function Sidebar() {
const Icon = menuItem[0];
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(index)}
onClick={() => {
updateQuizesList(quizId, { step: index + 1 });
}}
key={menuItem[1]}
text={menuItem[1]}
isCollapsed={isMenuCollapsed}
isActive={activeMenuItemIndex === index}
isActive={listQuizes[quizId].step === index + 1}
icon={
<Icon
color={
activeMenuItemIndex === index
listQuizes[quizId].step === index + 1
? theme.palette.brightPurple.main
: isMenuCollapsed
? "white"
@ -131,10 +147,10 @@ export default function Sidebar() {
{quizSettingsMenuItems.map((menuItem, index) => {
const Icon = menuItem[0];
const totalIndex = index + createQuizMenuItems.length;
const isActive = activeMenuItemIndex === totalIndex;
const isActive = listQuizes[quizId].step === totalIndex + 1;
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(totalIndex)}
onClick={() => updateQuizesList(quizId, { step: totalIndex + 1 })}
key={menuItem[1]}
text={menuItem[1]}
isActive={isActive}
@ -142,7 +158,11 @@ export default function Sidebar() {
icon={
<Icon
color={
isActive ? theme.palette.brightPurple.main : isMenuCollapsed ? "white" : theme.palette.grey2.main
isActive
? theme.palette.brightPurple.main
: isMenuCollapsed
? "white"
: theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}

@ -10,27 +10,34 @@ import { Setting } from "../pages/Result/Setting";
interface Props {
activeStep: number;
handleNext: () => void;
quizType: string;
startpage: string;
createResult: boolean;
}
export default function SwitchStepPages({ activeStep = 1, handleNext }: Props) {
export default function SwitchStepPages({
activeStep = 1,
quizType,
startpage,
createResult,
}: Props) {
switch (activeStep) {
case 1:
return <StepOne handleNext={handleNext} />;
if (!quizType) return <StepOne />;
if (!startpage) return <Steptwo />;
return <StartPageSettings />;
case 2:
return <Steptwo handleNext={handleNext} />;
case 3:
return <StartPageSettings handleNext={handleNext} />;
case 4:
return <QuestionsPage />;
case 5:
return <Result />;
case 6:
case 3:
if (!createResult) return <Result />;
return <Setting />;
case 7:
case 4:
return <ContactFormPage />;
case 8:
case 5:
return <InstallQuiz />;
case 6:
return <>Реклама</>;
default:
return <></>;
}