266 lines
7.0 KiB
TypeScript
266 lines
7.0 KiB
TypeScript
import { useState } from "react";
|
||
import {
|
||
Box,
|
||
Paper,
|
||
Typography,
|
||
LinearProgress,
|
||
Pagination as MuiPagination,
|
||
PaginationItem,
|
||
Input,
|
||
ButtonBase,
|
||
useTheme,
|
||
useMediaQuery,
|
||
} from "@mui/material";
|
||
|
||
import { ReactComponent as DoubleCheckIcon } from "@icons/Analytics/doubleCheck.svg";
|
||
import { ReactComponent as NextIcon } from "@icons/Analytics/next.svg";
|
||
import { ReactComponent as LeftArrowIcon } from "@icons/Analytics/leftArrow.svg";
|
||
import { ReactComponent as RightArrowIcon } from "@icons/Analytics/rightArrow.svg";
|
||
|
||
import type { PaginationRenderItemParams } from "@mui/material";
|
||
|
||
type AnswerProps = {
|
||
title: string;
|
||
percent: number;
|
||
highlight?: boolean;
|
||
};
|
||
|
||
const ANSWERS_MOCK: Record<string, number> = {
|
||
"Добавьте ответ": 67,
|
||
"Вопрос пропущен": 7,
|
||
Другое: 27,
|
||
};
|
||
|
||
const Answer = ({ title, percent, highlight }: AnswerProps) => {
|
||
const theme = useTheme();
|
||
|
||
return (
|
||
<Box sx={{ padding: "15px 25px" }}>
|
||
<Box
|
||
sx={{
|
||
position: "relative",
|
||
display: "flex",
|
||
gap: "15px",
|
||
alignItems: "center",
|
||
flexGrow: 1,
|
||
}}
|
||
>
|
||
<LinearProgress
|
||
variant="determinate"
|
||
title={title}
|
||
value={percent}
|
||
sx={{
|
||
width: "100%",
|
||
height: "44px",
|
||
background: theme.palette.background.default,
|
||
borderRadius: "10px",
|
||
border: `1px solid ${highlight ? theme.palette.brightPurple.main : theme.palette.grey2.main}`,
|
||
"& > span": { background: highlight ? "#D9C0F9" : "#9A9AAF1A" },
|
||
"&::before": {
|
||
content: `"${title}"`,
|
||
position: "absolute",
|
||
zIndex: 1,
|
||
left: "20px",
|
||
top: "50%",
|
||
transform: "translateY(-50%)",
|
||
color: highlight
|
||
? theme.palette.brightPurple.main
|
||
: theme.palette.grey3.main,
|
||
},
|
||
}}
|
||
/>
|
||
<Box sx={{ minWidth: 35 }}>
|
||
<Typography
|
||
sx={{
|
||
minWidth: "45px",
|
||
fontWeight: highlight ? "bold" : "normal",
|
||
color: highlight
|
||
? theme.palette.brightPurple.main
|
||
: theme.palette.text.primary,
|
||
}}
|
||
>{`${percent}%`}</Typography>
|
||
</Box>
|
||
</Box>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
const Pagination = () => {
|
||
const [count, setCount] = useState<number>(50);
|
||
const [page, setPage] = useState<number>(1);
|
||
const theme = useTheme();
|
||
const isMobile = useMediaQuery(theme.breakpoints.down(855));
|
||
|
||
const getPaginationItem = (props: PaginationRenderItemParams) => {
|
||
if (props.type === "start-ellipsis" || props.type === "end-ellipsis") {
|
||
return;
|
||
}
|
||
|
||
if (props.type !== "previous" && props.type !== "next" && props.page) {
|
||
if (isMobile) {
|
||
const allowedPages = [
|
||
page - 1 < 1 ? page + 2 : page - 1,
|
||
page,
|
||
page + 1 > count ? page - 2 : page + 1,
|
||
];
|
||
|
||
if (!allowedPages.includes(props.page)) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
const allowedPages = [
|
||
page - 2 < 1 ? page + 3 : page - 2,
|
||
page - 1 < 1 ? page + 4 : page - 1,
|
||
page,
|
||
page + 1 > count ? page - 4 : page + 1,
|
||
page + 2 > count ? page - 3 : page + 2,
|
||
];
|
||
|
||
if (!allowedPages.includes(props.page)) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
return (
|
||
<PaginationItem
|
||
component="div"
|
||
slots={{ previous: LeftArrowIcon, next: RightArrowIcon }}
|
||
{...{ ...props, variant: undefined }}
|
||
/>
|
||
);
|
||
};
|
||
|
||
return (
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
marginTop: "30px",
|
||
}}
|
||
>
|
||
<Input
|
||
disableUnderline
|
||
placeholder="1"
|
||
value={page}
|
||
onChange={({ target }) =>
|
||
setPage(Number(target.value.replace(/\D/, "")))
|
||
}
|
||
sx={{
|
||
height: "30px",
|
||
width: "65px",
|
||
borderRadius: "5px",
|
||
padding: "10px",
|
||
marginRight: "5px",
|
||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||
backgroundColor: theme.palette.background.paper,
|
||
}}
|
||
/>
|
||
<MuiPagination
|
||
page={page}
|
||
count={count}
|
||
siblingCount={isMobile ? 1 : 2}
|
||
boundaryCount={isMobile ? 1 : 2}
|
||
onChange={(_, page) => setPage(page)}
|
||
renderItem={getPaginationItem}
|
||
sx={{
|
||
"& .MuiButtonBase-root": {
|
||
borderRadius: "5px",
|
||
margin: "0 5px",
|
||
height: "30px",
|
||
background: theme.palette.background.paper,
|
||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||
"&.Mui-selected": {
|
||
background: theme.palette.background.paper,
|
||
color: theme.palette.brightPurple.main,
|
||
},
|
||
"&.MuiPaginationItem-previousNext": {
|
||
margin: "0 15px",
|
||
background: theme.palette.brightPurple.main,
|
||
},
|
||
},
|
||
}}
|
||
/>
|
||
</Box>
|
||
);
|
||
};
|
||
|
||
export const Answers = (props) => {
|
||
const theme = useTheme();
|
||
console.log(props.data);
|
||
|
||
if (Object.keys(props.data).length === 0)
|
||
return (
|
||
<Typography textAlign="center" m="10px 0">
|
||
нет данных об ответах
|
||
</Typography>
|
||
);
|
||
return (
|
||
<Box sx={{ flexGrow: 1 }}>
|
||
<Paper
|
||
sx={{
|
||
borderRadius: "12px",
|
||
boxShadow: "0 0 20px rgba(0, 0, 0, 0.15)",
|
||
marginTop: "20px",
|
||
}}
|
||
>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
gap: "10px",
|
||
alignItems: "center",
|
||
padding: "25px",
|
||
}}
|
||
>
|
||
<Typography
|
||
component="h3"
|
||
sx={{
|
||
flexGrow: 1,
|
||
position: "relative",
|
||
fontSize: "18px",
|
||
fontWeight: "bold",
|
||
paddingLeft: "40px",
|
||
color: theme.palette.text.primary,
|
||
"&::before": {
|
||
content: "'1'",
|
||
position: "absolute",
|
||
top: "50%",
|
||
left: "0",
|
||
transform: "translateY(-50%)",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
width: "30px",
|
||
height: "30px",
|
||
borderRadius: "50%",
|
||
fontSize: "14px",
|
||
fontWeight: "normal",
|
||
background: "#EEE4FC",
|
||
color: theme.palette.brightPurple.main,
|
||
},
|
||
}}
|
||
>
|
||
Заголовок вопроса. Варианты ответов
|
||
</Typography>
|
||
<ButtonBase>
|
||
<DoubleCheckIcon />
|
||
</ButtonBase>
|
||
<ButtonBase>
|
||
<NextIcon />
|
||
</ButtonBase>
|
||
</Box>
|
||
{Object.entries(props.data).map(([title, percent], index) => (
|
||
<Answer
|
||
key={title}
|
||
title={title}
|
||
percent={percent}
|
||
highlight={!index}
|
||
/>
|
||
))}
|
||
</Paper>
|
||
<Pagination />
|
||
</Box>
|
||
);
|
||
};
|