fix: Stepper

This commit is contained in:
IlyaDoronin 2023-10-05 13:12:56 +03:00
parent bdc7438378
commit eb88eeb440
10 changed files with 131 additions and 84 deletions

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

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

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

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

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

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

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

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

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

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