Добавил папки pages - в ней desktop 22-26

папку ui_kit - в ней stepper и отдельные элементы по шагам desktop 33, 35, 37.
Вывел sidebar отдельно в компонент
This commit is contained in:
beliberda 2023-01-23 00:02:27 +10:00
parent 0a232d26c0
commit 5933d6f418
10 changed files with 462 additions and 115 deletions

@ -21,6 +21,7 @@ import cardImage2 from "../../assets/card-2.png";
import cardImage3 from "../../assets/card-3.png"; import cardImage3 from "../../assets/card-3.png";
import StartPageSettings from "./StartPageSettings"; import StartPageSettings from "./StartPageSettings";
import CustomButton from "../CustomButton"; import CustomButton from "../CustomButton";
import SidebarCreateQuize from "../../ui_kit/sidebarCreateQuize";
const createQuizMenuItems = [ const createQuizMenuItems = [
@ -56,112 +57,7 @@ export default function CreateQuiz() {
minHeight: "calc(100vh - 80px)", minHeight: "calc(100vh - 80px)",
}} }}
> >
<Box <SidebarCreateQuize></SidebarCreateQuize>
sx={{
backgroundColor: theme.palette.lightPurple.main,
minWidth: isMenuCollapsed ? "80px" : "230px",
width: isMenuCollapsed ? "80px" : "230px",
display: "flex",
flexDirection: "column",
py: "19px",
transitionProperty: "width, min-width",
transitionDuration: "200ms",
overflow: "hidden",
whiteSpace: "nowrap",
}}
>
<Box
sx={{
display: "flex",
pl: isMenuCollapsed ? undefined : "16px",
pr: isMenuCollapsed ? undefined : "8px",
mb: isMenuCollapsed ? "5px" : undefined,
alignItems: "center",
justifyContent: isMenuCollapsed ? "center" : undefined,
}}
>
{!isMenuCollapsed &&
<Typography
sx={{
fontSize: "14px",
lineHeight: "20px",
fontWeight: 500,
color: theme.palette.grey2.main,
}}
>Создание квиза</Typography>
}
<IconButton onClick={handleMenuCollapseToggle} sx={{ ml: isMenuCollapsed ? undefined : "auto" }}>
<CollapseMenuIcon height="16px" width="16px" color={theme.palette.grey2.main} transform={isMenuCollapsed ? "rotate(180deg)" : ""} />
</IconButton>
</Box>
<List disablePadding>
{createQuizMenuItems.map((menuItem, index) => {
const Icon = menuItem[0];
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(index)}
key={menuItem[1]}
text={menuItem[1]}
isCollapsed={isMenuCollapsed}
isActive={activeMenuItemIndex === index}
icon={<Icon
color={activeMenuItemIndex === index ?
theme.palette.brightPurple.main
:
isMenuCollapsed ?
"white"
:
theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}
/>}
/>
);
})}
</List>
{!isMenuCollapsed &&
<Typography
sx={{
px: "16px",
mt: "16px",
mb: "11px",
fontSize: "14px",
lineHeight: "20px",
fontWeight: 500,
color: theme.palette.grey2.main,
}}
>Настройки квиза</Typography>
}
<List disablePadding>
{quizSettingsMenuItems.map((menuItem, index) => {
const Icon = menuItem[0];
const totalIndex = index + createQuizMenuItems.length;
const isActive = activeMenuItemIndex === totalIndex;
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(totalIndex)}
key={menuItem[1]}
text={menuItem[1]}
isActive={isActive}
isCollapsed={isMenuCollapsed}
icon={<Icon
color={isActive ?
theme.palette.brightPurple.main
:
isMenuCollapsed ?
"white"
:
theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}
/>}
/>
);
})}
</List>
</Box>
<Container <Container
maxWidth="lg" maxWidth="lg"
disableGutters disableGutters

@ -3,14 +3,17 @@ import ReactDOM from 'react-dom/client';
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { BrowserRouter, Route, Routes } from 'react-router-dom';
import FirstQuiz from './components/FirstQuiz';
import lightTheme from "./utils/themes/light"; import lightTheme from "./utils/themes/light";
import { ThemeProvider } from '@mui/material'; import { ThemeProvider } from '@mui/material';
import Navbar from './components/Navbar/Navbar';
import CreateQuiz from './components/CreateQuiz/CreateQuiz'; import CreateQuiz from './components/CreateQuiz/CreateQuiz';
import NavbarCreateQuiz from './components/Navbar/NavbarCreateQuiz'; import NavbarCreateQuiz from './components/Navbar/NavbarCreateQuiz';
import MyQuizzes from './components/MyQuizzes';
import QuizGallery from './components/QuizGallery';
import HorizontalLinearStepper from './ui_kit/Stepper';
import Create from './pages/createQuize/Create';
import Quizes from './pages/createQuize/Quizes';
import Projects from './pages/createQuize/Projects';
import Gallery from './pages/createQuize/Gallery';
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement document.getElementById('root') as HTMLElement
@ -21,13 +24,15 @@ root.render(
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route path="/" element={ <App /> } /> <Route path="/" element={ <App /> } />
<Route path="/create" element={<><Navbar isLoggedIn={true} /><FirstQuiz/></>} /> <Route path="/create" element={<Create/>} />
<Route path="/quizes" element={<><Navbar isLoggedIn={true} /></>}/> <Route path="/quizes" element={<Quizes/>}/>
<Route path="/projects" element={<><Navbar isLoggedIn={true} /> <MyQuizzes /></>} /> <Route path="/projects" element={<Projects/>} />
<Route path="/gallery" element={<><Navbar isLoggedIn={true} /><QuizGallery /></>} /> <Route path="/gallery" element={<Gallery/>} />
<Route path="/create/type" element={<><NavbarCreateQuiz /></>} /> <Route path="/create/quiz" element={<><NavbarCreateQuiz /></>} />
<Route path="/create/start" element={<><NavbarCreateQuiz /></>} /> <Route path="/create/start" element={<><NavbarCreateQuiz /></>} />
<Route path="/create/settings" element={<><NavbarCreateQuiz /><CreateQuiz /></>} /> <Route path="/create/settings" element={<><NavbarCreateQuiz /><CreateQuiz /></>} />
<Route path="/create/stepper" element={<><NavbarCreateQuiz /><HorizontalLinearStepper/></>} />
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
</ThemeProvider> </ThemeProvider>

@ -0,0 +1,8 @@
import FirstQuiz from "../../components/FirstQuiz";
import Navbar from "../../components/Navbar/Navbar";
export default function Create(){
return (
<><Navbar isLoggedIn={true} /><FirstQuiz/></>
)
}

@ -0,0 +1,9 @@
import Navbar from "../../components/Navbar/Navbar";
import QuizGallery from "../../components/QuizGallery";
export default function Gallery(){
return (
<><Navbar isLoggedIn={true} /><QuizGallery /></>
)
}

@ -0,0 +1,10 @@
import MyQuizzes from "../../components/MyQuizzes";
import Navbar from "../../components/Navbar/Navbar";
export default function Projects() {
return (
<>
<Navbar isLoggedIn={true} /> <MyQuizzes />
</>
);
}

@ -0,0 +1,8 @@
import Navbar from "../../components/Navbar/Navbar";
export default function Quizes(){
return (
<><Navbar isLoggedIn={true} /></>
)
}

76
src/ui_kit/CreateCard.tsx Normal file

@ -0,0 +1,76 @@
import { Box, Typography, useTheme } from "@mui/material";
import CreationCard from "../components/CreateQuiz/CreationCard";
import quizCreationImage1 from "../assets/quiz-creation-1.png";
import quizCreationImage2 from "../assets/quiz-creation-2.png";
import { useState } from "react";
export default function CreateCard() {
const theme = useTheme();
const [progress, setProgress] = useState<number>(1 / 6);
return (<>
<Box
sx={{
border: `1px solid ${theme.palette.brightPurple.main}`,
borderRadius: "12px",
overflow: "hidden",
px: "20px",
pt: "20px",
pb: "10px",
position: "relative",
}}
>
<Box
sx={{
backgroundColor: "white",
height: "10px",
position: "absolute",
top: 0,
left: 0,
width: "100%",
boxShadow: `0px 6.6501px 20.5488px rgba(210, 208, 225, 0.0969343), 0px 2.76726px 8.55082px rgba(210, 208, 225, 0.0674749)`,
}}
/>
<Box
sx={{
backgroundColor: theme.palette.brightPurple.main,
height: "10px",
position: "absolute",
top: 0,
left: 0,
width: `${(progress * 100).toFixed(3)}%`,
}}
/>
<Typography
sx={{
fontSize: "12px",
lineHeight: "14px",
color: "#4D4D4D",
}}
>Шаг 1 из 6</Typography>
<Typography
sx={{
fontSize: "18px",
lineHeight: "24px",
color: "#4D4D4D",
mt: "5px",
}}
>Настройка стартовой страницы</Typography>
</Box>
<Box sx={{
display: "flex",
gap: "3.4%",
mt: "60px",
}}>
<CreationCard
header="Создание квиз-опроса"
text="У стартовой страницы одна ключевая задача - заинтересовать посетителя пройти квиз. С ней сложно ошибиться, сформулируйте суть предложения и подберите живую фотографию, остальное мы сделаем за вас"
image={quizCreationImage1}
/>
<CreationCard
header="Создание анкеты"
text="У стартовой страницы одна ключевая задача - заинтересовать посетителя пройти квиз. С ней сложно ошибиться, сформулируйте суть предложения и подберите живую фотографию, остальное мы сделаем за вас"
image={quizCreationImage2}
/>
</Box>
</>
)
}

25
src/ui_kit/StartPage.tsx Normal file

@ -0,0 +1,25 @@
import { Box, Typography } from "@mui/material";
import CardWithImage from "../components/CreateQuiz/CardWithImage";
import cardImage1 from "../assets/card-1.png";
import cardImage2 from "../assets/card-2.png";
import cardImage3 from "../assets/card-3.png";
export default function StartPage() {
return (
<>
<Box sx={{
mt: "60px",
}}>
<Typography variant="h5">Стартовая страница</Typography>
<Box sx={{
display: "flex",
gap: "3.4%",
mt: "40px",
}}>
<CardWithImage image={cardImage1} text="Standart" />
<CardWithImage image={cardImage2} text="Expanded" />
<CardWithImage image={cardImage3} text="Centered" />
</Box>
</Box>
</>
)
}

159
src/ui_kit/Stepper.tsx Normal file

@ -0,0 +1,159 @@
import * as React from "react";
import Box from "@mui/material/Box";
import Stepper from "@mui/material/Stepper";
import Step from "@mui/material/Step";
import StepLabel from "@mui/material/StepLabel";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Navbar from "../components/Navbar/Navbar";
import Create from "../pages/createQuize/Create";
import { Container, useTheme } from "@mui/material";
import Projects from "../pages/createQuize/Projects";
import MyQuizzes from "../components/MyQuizzes";
import SidebarCreateQuize from "./sidebarCreateQuize";
import CreateCard from "./CreateCard";
import StartPage from "./StartPage";
const steps = ["Step 34", "Step 2", "Step 3"];
export default function HorizontalLinearStepper() {
const [activeStep, setActiveStep] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set<number>());
const theme = useTheme();
const isStepOptional = (step: number) => {
return step === 1;
};
const isStepSkipped = (step: number) => {
return skipped.has(step);
};
const handleNext = () => {
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// You probably want to guard against something like this,
// it should never occur unless someone's actively trying to break something.
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped((prevSkipped) => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const handleReset = () => {
setActiveStep(0);
};
let component = null
switch (activeStep) {
case 0:
component = <></>
break;
case 1:
component = <CreateCard/>
break;
case 2:
component = <StartPage/>
break;
default:
break;
}
return (<>
<Container maxWidth={false}
disableGutters
sx={{
display:'flex',
minHeight: "calc(100vh - 80px)",
}}>
<SidebarCreateQuize/>
<Container
maxWidth="lg"
disableGutters
sx={{
p: "25px",
[theme.breakpoints.up("lg")]: {
maxWidth: "1210px",
}
}}
>
{component}
</Container>
</Container>
{activeStep === steps.length ? (
<React.Fragment>
<Typography sx={{ mt: 2, mb: 1 }}>
All steps completed - you&apos;re finished
</Typography>
<Box sx={{ display: "flex", flexDirection: "row", pt: 2 }}>
<Box sx={{ flex: "1 1 auto" }} />
<Button onClick={handleReset}>Reset</Button>
</Box>
</React.Fragment>
) : (
//Тут отображаемые компоненты
<React.Fragment>
<Box sx={{ display: "flex", flexDirection: "row", pt: 2 }}>
<Button
color="inherit"
disabled={activeStep === 0}
onClick={handleBack}
sx={{ mr: 1 }}
>
Back
</Button>
<Box sx={{ flex: "1 1 auto" }} />
{isStepOptional(activeStep) && (
<Button color="inherit" onClick={handleSkip} sx={{ mr: 1 }}>
Skip
</Button>
)}
<Button onClick={handleNext}>
{activeStep === steps.length - 1 ? "Finish" : "Next"}
</Button>
</Box>
</React.Fragment>
)}
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps: { completed?: boolean } = {};
const labelProps: {
optional?: React.ReactNode;
} = {};
if (isStepOptional(index)) {
labelProps.optional = (
<Typography variant="caption">Optional</Typography>
);
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
</>
);
}

@ -0,0 +1,151 @@
import { useState } from "react";
import { Container, Box, useTheme, List, Typography, IconButton } from "@mui/material";
import MegaphoneIcon from "../components/icons/MegaphoneIcon";
import QuestionIcon from "../components/icons/QuestionIcon";
import ChartPieIcon from "../components/icons/ChartPieIcon";
import ContactBookIcon from "../components/icons/ContactBookIcon";
import FlowArrowIcon from "../components/icons/FlowArrowIcon";
import CollapseMenuIcon from "../components/icons/CollapseMenuIcon";
import TagIcon from "../components/icons/TagIcon";
import PencilCircleIcon from "../components/icons/PencilCircleIcon";
import PuzzlePieceIcon from "../components/icons/PuzzlePieceIcon";
import GearIcon from "../components/icons/GearIcon";
import LayoutIcon from "../components/icons/LayoutIcon";
import MenuItem from "../components/CreateQuiz/MenuItem";
const createQuizMenuItems = [
[LayoutIcon, "Стартовая страница"],
[QuestionIcon, "Вопросы"],
[ChartPieIcon, "Результаты"],
[ContactBookIcon, "Форма контактов"],
[FlowArrowIcon, "Установка квиза"],
[MegaphoneIcon, "Запуск рекламы"],
] as const;
const quizSettingsMenuItems = [
[TagIcon, "Дополнения"],
[PencilCircleIcon, "Дизайн"],
[PuzzlePieceIcon, "Интеграции"],
[GearIcon, "Настройки"],
] as const;
export default function SidebarCreateQuize() {
const theme = useTheme();
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false);
const [activeMenuItemIndex, setActiveMenuItemIndex] = useState<number>(0);
const [progress, setProgress] = useState<number>(1 / 6);
const handleMenuCollapseToggle = () => setIsMenuCollapsed(prev => !prev);
return (
<Box
sx={{
backgroundColor: theme.palette.lightPurple.main,
minWidth: isMenuCollapsed ? "80px" : "230px",
width: isMenuCollapsed ? "80px" : "230px",
display: "flex",
flexDirection: "column",
py: "19px",
transitionProperty: "width, min-width",
transitionDuration: "200ms",
overflow: "hidden",
whiteSpace: "nowrap",
}}
>
<Box
sx={{
display: "flex",
pl: isMenuCollapsed ? undefined : "16px",
pr: isMenuCollapsed ? undefined : "8px",
mb: isMenuCollapsed ? "5px" : undefined,
alignItems: "center",
justifyContent: isMenuCollapsed ? "center" : undefined,
}}
>
{!isMenuCollapsed &&
<Typography
sx={{
fontSize: "14px",
lineHeight: "20px",
fontWeight: 500,
color: theme.palette.grey2.main,
}}
>Создание квиза</Typography>
}
<IconButton onClick={handleMenuCollapseToggle} sx={{ ml: isMenuCollapsed ? undefined : "auto" }}>
<CollapseMenuIcon height="16px" width="16px" color={theme.palette.grey2.main} transform={isMenuCollapsed ? "rotate(180deg)" : ""} />
</IconButton>
</Box>
<List disablePadding>
{createQuizMenuItems.map((menuItem, index) => {
const Icon = menuItem[0];
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(index)}
key={menuItem[1]}
text={menuItem[1]}
isCollapsed={isMenuCollapsed}
isActive={activeMenuItemIndex === index}
icon={<Icon
color={activeMenuItemIndex === index ?
theme.palette.brightPurple.main
:
isMenuCollapsed ?
"white"
:
theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}
/>}
/>
);
})}
</List>
{!isMenuCollapsed &&
<Typography
sx={{
px: "16px",
mt: "16px",
mb: "11px",
fontSize: "14px",
lineHeight: "20px",
fontWeight: 500,
color: theme.palette.grey2.main,
}}
>Настройки квиза</Typography>
}
<List disablePadding>
{quizSettingsMenuItems.map((menuItem, index) => {
const Icon = menuItem[0];
const totalIndex = index + createQuizMenuItems.length;
const isActive = activeMenuItemIndex === totalIndex;
return (
<MenuItem
onClick={() => setActiveMenuItemIndex(totalIndex)}
key={menuItem[1]}
text={menuItem[1]}
isActive={isActive}
isCollapsed={isMenuCollapsed}
icon={<Icon
color={isActive ?
theme.palette.brightPurple.main
:
isMenuCollapsed ?
"white"
:
theme.palette.grey2.main
}
height={isMenuCollapsed ? "35px" : "24px"}
width={isMenuCollapsed ? "35px" : "24px"}
/>}
/>
);
})}
</List>
</Box>
)
}