frontPanel/src/pages/Analytics/Answers/Answers.tsx

266 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
};