скелетоны для листа

This commit is contained in:
Tamara 2024-05-28 23:39:21 +03:00
parent f71127d4d9
commit a19efe1e99
8 changed files with 293 additions and 174 deletions

@ -40,6 +40,7 @@ import { InfoPrivilege } from "./pages/InfoPrivilege";
import OutdatedLink from "./pages/auth/OutdatedLink";
import { useAfterpay } from "@utils/hooks/useAfterpay";
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
import ListPageDummy from "./components/Dummys/pageDummys/listPageDummy";
const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull"));
@ -208,7 +209,7 @@ export default function App() {
/>
<Route
path="/list"
element={<LazyLoading children={<MyQuizzesFull />} />}
element={<LazyLoading children={<MyQuizzesFull />} fallback={<ListPageDummy/>} />}
/>
<Route
path={"/view/:quizId"}

@ -0,0 +1,25 @@
import {Box, Skeleton, Typography} from "@mui/material";
import React from "react";
export default function AvailablePrivilegeDummy() {
return (
<Box
sx={{
padding: "20px",
backgroundColor: "#9A9AAF17",
width: "100%",
borderRadius: "12px",
display: "flex",
gap: "20px",
flexWrap: "wrap",
}}
>
<Typography variant={"body1"} sx={{ color: "#9A9AAF" }}>
Вам доступно:
</Typography>
<Skeleton variant="text" sx={{ maxWidth: "260px", width: "100%", height: "30px"}} />
<Skeleton variant="text" sx={{ maxWidth: "130px", width: "100%", height: "30px"}} />
<Skeleton variant="text" sx={{ maxWidth: "340px", width: "100%", height: "30px"}} />
</Box>
);
}

@ -0,0 +1,126 @@
import {Box, Button, IconButton, Skeleton, Typography, useMediaQuery, useTheme} from "@mui/material";
import LinkIcon from "@icons/LinkIcon";
import PencilIcon from "@icons/PencilIcon";
import ChartIcon from "@icons/ChartIcon";
import CopyIcon from "@icons/CopyIcon";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import React from "react";
export default function QuizCardDummy() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(600));
return (
<Box
sx={{
display: "flex",
flexDirection: "column",
backgroundColor: "white",
width: isMobile ? "100%" : "560px",
height: "280px",
p: "20px",
borderRadius: "12px",
boxSizing: "border-box",
boxShadow: `0px 100px 309px rgba(210, 208, 225, 0.24),
0px 41.7776px 129.093px rgba(210, 208, 225, 0.172525),
0px 22.3363px 69.0192px rgba(210, 208, 225, 0.143066),
0px 12.5216px 38.6916px rgba(210, 208, 225, 0.12),
0px 6.6501px 20.5488px rgba(210, 208, 225, 0.0969343),
0px 2.76726px 8.55082px rgba(210, 208, 225, 0.0674749)`,
}}
>
<Skeleton variant="text" sx={{ fontSize: "24px", width: "100%", height: "30px" }} />
<Box
sx={{
display: "flex",
alignItems: "center",
mt: "10px",
gap: "10px",
}}
>
<LinkIcon bgcolor="#EEE4FC" color={theme.palette.brightPurple.main} />
<Skeleton variant="text" sx={{ fontSize: "18px", maxWidth: "300px", width: "100%", height: "30px"}} />
</Box>
<Box
sx={{
display: "flex",
mt: "32px",
mr: "22px",
}}
>
<Box sx={{ flex: "1 1 0" }}>
<Skeleton variant="text" sx={{ width: "100%", height: "30px", maxWidth: "100px", }} />
<Typography color={theme.palette.grey3.main}>Открытий</Typography>
</Box>
<Box sx={{ flex: "1 1 0" }}>
<Skeleton variant="text" sx={{ maxWidth: "100px", width: "100%", height: "30px"}} />
<Typography color={theme.palette.grey3.main}>Заявок</Typography>
</Box>
<Box sx={{ flex: "1 1 0" }}>
<Skeleton variant="text" sx={{ maxWidth: "100px", width: "100%", height: "30px"}} />
<Typography color={theme.palette.grey3.main}>Конверсия</Typography>
</Box>
</Box>
<Box
sx={{
mt: "auto",
display: "flex",
gap: isMobile ? "10px" : "20px",
}}
>
<Button
variant="contained"
sx={{
padding: "10px 39px",
}}
>
Заявки
</Button>
<Button
variant="outlined"
startIcon={<PencilIcon />}
sx={{
padding: isMobile ? "10px" : "10px 20px",
minWidth: "unset",
color: theme.palette.brightPurple.main,
"& .MuiButton-startIcon": {
marginRight: isMobile ? 0 : "4px",
marginLeft: 0,
},
}}
>
{isMobile ? "" : "Редактировать"}
</Button>
<IconButton
sx={{
height: "44px",
width: "44px",
border: `${theme.palette.brightPurple.main} 1px solid`,
borderRadius: "6px",
}}
>
<ChartIcon />
</IconButton>
<IconButton
sx={{
height: "44px",
width: "44px",
borderRadius: "6px",
}}
>
<CopyIcon
color={theme.palette.brightPurple.main}
bgcolor={"#EEE4FC"}
/>
</IconButton>
<IconButton
sx={{
color: theme.palette.brightPurple.main,
ml: "auto",
}}
>
<MoreHorizIcon sx={{ transform: "scale(1.75)" }} />
</IconButton>
</Box>
</Box>
);
}

@ -0,0 +1,32 @@
import {
Box,
Button,
SxProps,
Theme,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import SectionWrapper from "@ui_kit/SectionWrapper";
import React from "react";
import HeaderFull from "@ui_kit/Header/HeaderFull";
import QuizCardDummy from "../QuizCardDummy";
import AvailablePrivilegeDummy from "../AvailablePrivilegeDummy";
export default function ListPageDummy() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(500));
return (
<>
<HeaderFull isRequest={false} />
<SectionWrapper
maxWidth="lg"
sx={{ padding: isMobile ? "0 16px" : "20px" }}
>
</SectionWrapper>
</>
);
}

@ -0,0 +1,58 @@
import {Link, useNavigate} from "react-router-dom";
import {Box, Button, Typography, useMediaQuery, useTheme} from "@mui/material";
import {ReactComponent as TemplateIcon} from "@/assets/quiz-templates/template.svg";
import {createQuiz, resetEditConfig} from "@root/quizes/actions";
import React from "react";
export default function CreateButtons ({mt}: string) {
const navigate = useNavigate();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(500));
return(
<Box
sx={{
display: "flex",
gap: "20px",
flexWrap: "wrap",
marginTop: mt,
}}
>
<Link to="/gallery" style={{ textDecoration: "none" }}>
<Button
sx={{
display: "flex",
gap: "10px",
padding: "13px",
borderRadius: "8px",
background: "#9A9AAF17",
color: theme.palette.brightPurple.main,
transition: ".2s",
"&:hover": {
color: theme.palette.background.paper,
background: theme.palette.brightPurple.main,
"& svg path": { stroke: theme.palette.background.paper },
},
}}
>
<TemplateIcon />
<Typography>Посмотреть шаблоны</Typography>
</Button>
</Link>
<Button
variant="contained"
sx={{
padding: isMobile ? "10px" : "10px 47px",
minWidth: "44px",
}}
onClick={() => {
resetEditConfig();
createQuiz(navigate);
}}
data-cy="create-quiz"
>
{isMobile ? "+" : "Создать +"}
</Button>
</Box>
)
}

@ -1,66 +0,0 @@
import { Box, Button, Typography, useTheme } from "@mui/material";
import SectionWrapper from "@ui_kit/SectionWrapper";
import ComplexNavText from "./ComplexNavText";
import { createQuiz } from "@root/quizes/actions";
import { Link, useNavigate } from "react-router-dom";
import { resetEditConfig } from "@root/quizes/actions";
import AvailablePrivilege from "./AvailablePrivilege";
import { ReactComponent as TemplateIcon } from "@/assets/quiz-templates/template.svg";
export default function FirstQuiz() {
const navigate = useNavigate();
const theme = useTheme();
return (
<SectionWrapper
maxWidth="lg"
sx={{ mt: "25px", mb: "40px", padding: "10px" }}
>
<Typography variant="h4" sx={{ mt: "20px", mb: "30px" }}>
Создайте свой первый quiz
</Typography>
<AvailablePrivilege />
<Box
sx={{
display: "flex",
gap: "20px",
flexWrap: "wrap",
marginTop: "20px",
}}
>
<Button
variant="contained"
data-cy="create-quiz"
onClick={() => {
resetEditConfig();
createQuiz(navigate);
}}
>
Создать +
</Button>
<Link to="/gallery" style={{ textDecoration: "none" }}>
<Button
sx={{
display: "flex",
gap: "10px",
padding: "13px",
borderRadius: "8px",
background: "#9A9AAF17",
color: theme.palette.brightPurple.main,
transition: ".2s",
"&:hover": {
color: theme.palette.background.paper,
background: theme.palette.brightPurple.main,
"& svg path": { stroke: theme.palette.background.paper },
},
}}
>
<TemplateIcon />
<Typography>Посмотреть шаблоны</Typography>
</Button>
</Link>
</Box>
</SectionWrapper>
);
}

@ -1,22 +0,0 @@
import { useTheme, Box } from "@mui/material";
import ExpandableQuizBlock from "./ExpandableQuizBlock";
import MyQuizzesFull from "./MyQuizzesFull";
export default function MyQuizzes() {
const theme = useTheme();
return (
<MyQuizzesFull>
<Box
sx={{
display: "flex",
flexDirection: "column",
gap: "40px",
}}
>
<ExpandableQuizBlock name="Название" />
<ExpandableQuizBlock name="Название" />
</Box>
</MyQuizzesFull>
);
}

@ -1,31 +1,28 @@
import {
Box,
Button,
Skeleton,
SxProps,
Theme,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { Link } from "react-router-dom";
import {
copyQuiz,
createQuiz,
resetEditConfig,
updateQuiz,
} from "@root/quizes/actions";
import { mutate } from "swr";
import { useQuizes } from "@root/quizes/hooks";
import SectionWrapper from "@ui_kit/SectionWrapper";
import React from "react";
import { useNavigate } from "react-router-dom";
import FirstQuiz from "./FirstQuiz";
import QuizCard from "./QuizCard";
import HeaderFull from "@ui_kit/Header/HeaderFull";
import QuizgenegationName from "@utils/quizgenegationName";
import AvailablePrivilege from "./AvailablePrivilege";
import { ReactComponent as TemplateIcon } from "@/assets/quiz-templates/template.svg";
import AvailablePrivilegeDummy from "@/components/Dummys/AvailablePrivilegeDummy";
import QuizCardDummy from "@/components/Dummys/QuizCardDummy";
import CreateButtons from "@/pages/createQuize/CreateButtons";
interface Props {
outerContainerSx?: SxProps<Theme>;
@ -36,8 +33,7 @@ export default function MyQuizzesFull({
outerContainerSx: sx,
children,
}: Props) {
const { quizes } = useQuizes();
const navigate = useNavigate();
const { quizes, isLoading } = useQuizes();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(500));
@ -49,9 +45,6 @@ export default function MyQuizzesFull({
return (
<>
<HeaderFull isRequest={false} />
{quizes.length === 0 ? (
<FirstQuiz />
) : (
<SectionWrapper
maxWidth="lg"
sx={{ padding: isMobile ? "0 16px" : "20px" }}
@ -65,51 +58,12 @@ export default function MyQuizzesFull({
mb: "30px",
}}
>
<Typography variant="h4">Мои quiz</Typography>
<Box
sx={{
display: "flex",
gap: "20px",
flexWrap: "wrap",
marginTop: "20px",
}}
>
<Link to="/gallery" style={{ textDecoration: "none" }}>
<Button
sx={{
display: "flex",
gap: "10px",
padding: "13px",
borderRadius: "8px",
background: "#9A9AAF17",
color: theme.palette.brightPurple.main,
transition: ".2s",
"&:hover": {
color: theme.palette.background.paper,
background: theme.palette.brightPurple.main,
"& svg path": { stroke: theme.palette.background.paper },
},
}}
>
<TemplateIcon />
<Typography>Посмотреть шаблоны</Typography>
</Button>
</Link>
<Button
variant="contained"
sx={{
padding: isMobile ? "10px" : "10px 47px",
minWidth: "44px",
}}
onClick={() => {
resetEditConfig();
createQuiz(navigate);
}}
data-cy="create-quiz"
>
{isMobile ? "+" : "Создать +"}
</Button>
</Box>
{isLoading ? <Skeleton variant="text" sx={{ fontSize: "24px", width: "300px", height: "50px" }} /> :
<Typography variant="h4">{quizes.length === 0 ? "Создайте свой первый quiz" : "Мои quiz"}</Typography>
}
{quizes.length !== 0 &&
<CreateButtons mt={"20px"}/>
}
</Box>
<Box
sx={{
@ -121,38 +75,49 @@ export default function MyQuizzesFull({
width: isMobile ? "100%" : undefined,
}}
>
<AvailablePrivilege />
{quizes.map((quiz) => {
if (quiz.name.length === 0 || quiz.name === " ") {
updateQuiz(quiz.id, (quiz) => {
quiz.name = QuizgenegationName({ quiz });
});
}
{isLoading ?
<>
<AvailablePrivilegeDummy/>
<QuizCardDummy/>
<QuizCardDummy/>
<QuizCardDummy/>
</>
:
<>
<AvailablePrivilege />
{quizes.length === 0 &&
<CreateButtons mt={"0px"}/>}
{quizes.map((quiz) => {
if (quiz.name.length === 0 || quiz.name === " ") {
updateQuiz(quiz.id, (quiz) => {
quiz.name = QuizgenegationName({ quiz });
});
}
return (
<QuizCard
key={quiz.id}
quiz={quiz}
openCount={quiz.session_count}
applicationCount={quiz.passed_count}
conversionPercent={
quiz.session_count
? parseFloat(
(
(quiz.passed_count / quiz.session_count) *
100
).toFixed(2),
)
: 0
}
onClickCopy={onClickCopy}
/>
);
})}
return (
<QuizCard
key={quiz.id}
quiz={quiz}
openCount={quiz.session_count}
applicationCount={quiz.passed_count}
conversionPercent={
quiz.session_count
? parseFloat(
(
(quiz.passed_count / quiz.session_count) *
100
).toFixed(2),
)
: 0
}
onClickCopy={onClickCopy}
/>
);
})}
</>}
</Box>
{children}
</SectionWrapper>
)}
</>
);
}