frontPanel/src/pages/QuizAnswersPage/QuizAnswersPage.tsx

457 lines
14 KiB
TypeScript
Raw Normal View History

2024-01-20 10:27:21 +00:00
import {
Box,
Button,
IconButton,
Typography,
MenuItem,
2024-01-20 10:27:21 +00:00
useTheme,
useMediaQuery,
Skeleton,
FormControl,
Pagination,
2024-01-20 10:27:21 +00:00
} from "@mui/material";
import { Select } from "../../pages/Questions/Select";
import moment from "moment";
2024-01-20 10:27:21 +00:00
import HeaderFull from "@ui_kit/Header/HeaderFull";
import SectionWrapper from "@ui_kit/SectionWrapper";
import { FC, useEffect, useState } from "react";
2024-01-20 10:27:21 +00:00
import { FileExportIcon } from "./icons/FileExporIcon";
import { UpdateIcon } from "./icons/UpdateIcon";
import { CheckboxSelect } from "../../ui_kit/CheckboxSelect";
import { CardAnswer } from "./CardAnswer";
import { FilterIcon } from "./icons/FilterIcon";
2024-02-20 11:54:08 +00:00
import { PrePaymentModal } from "./PrePaymentModal";
2024-01-21 22:09:26 +00:00
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
import { ExportContactsModal } from "@ui_kit/Modal/ExportContactsModal";
import { resultApi } from "@api/result";
import { useResultStore } from "@root/results/store";
import { setResults } from "@root/results/actions";
import { quizApi } from "@api/quiz";
import { setQuizes } from "@root/quizes/actions";
import { useCurrentQuiz, useQuizes } from "@root/quizes/hooks";
import { useQuizStore } from "@root/quizes/store";
import { questionApi } from "@api/question";
import { setQuestions } from "@root/questions/actions";
2024-02-20 11:54:08 +00:00
import { useUserStore } from "@root/user";
import type { AxiosError } from "axios";
2024-01-20 10:27:21 +00:00
const itemsCities = [
2024-01-20 10:27:21 +00:00
{ label: "Муром (1)", value: "option1" },
{ label: "Москва (1)", value: "option2" },
];
const itemsTime = [
"За всё время",
"Сегодня",
"Вчера",
"Последние 7 дней",
"Последние 30 дней",
"Этот месяц",
];
const itemsNews = ["Все заявки", "Новые"];
const resetTime = () => {
return Math.round(Number(moment().format("X")) / 86400 - 1) * 86400 - 0;
};
2024-01-20 10:27:21 +00:00
export const QuizAnswersPage: FC = () => {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
2024-01-21 22:09:26 +00:00
const isMobile = useMediaQuery(theme.breakpoints.down(600));
2024-01-21 22:09:26 +00:00
const [filterModalOpen, setFilterModalOpen] = useState<boolean>(false);
const [page, setPage] = useState(1);
const [exportContactsModalOpen, setExportContactsModalOpen] =
useState<boolean>(false);
const [filterNew, setFilterNew] = useState<string>("Все заявки");
const [filterDate, setFilterDate] = useState<string>("За всё время");
2024-02-20 11:54:08 +00:00
const [prePaymentModalOpen, setPrePaymentModalOpen] =
useState<boolean>(false);
const { userAccount } = useUserStore();
const filterNewHC = (value: string) => {
setFilterNew(value);
};
const filterDateHC = (value: string) => {
setFilterDate(value);
};
const quizList = useQuizStore();
const quiz = useCurrentQuiz();
const { editQuizId } = useQuizStore();
2024-02-16 21:19:35 +00:00
const { results, total_count } = useResultStore();
console.log("Перерендер компонента ", results);
2024-02-16 21:19:35 +00:00
const countPagination = Math.ceil(total_count / 10);
// const {idResultArray, addIdResult, clearIdResultArray} = useObsolescenceIdResult()
useEffect(() => {
getData();
}, [filterNew, filterDate]);
2024-02-20 11:54:08 +00:00
useEffect(() => {
if (userAccount?.privileges[""].amount === 0) {
setPrePaymentModalOpen(true);
}
}, [userAccount]);
const DateDefinition = (result: string) => {
//определяем когда был получен результат - вчера, сегодня или число и месяц
let restime = new Date(result);
let timeCompleting = Date.parse(String(result));
const timeNow = Date.now();
let dayResult;
if (timeNow - timeCompleting < 86400000) {
dayResult = "Сегодня";
}
if (172800000 > timeNow - timeCompleting > 86400000) {
dayResult = "Вчера";
} else {
dayResult = restime.toLocaleDateString();
}
return dayResult;
};
const TimeDefinition = (result: string) => {
//достаём время
let timeResult = new Date(result).toLocaleTimeString().slice(0, -3);
return timeResult;
};
const parseFilters = () => {
const filters: any = {};
if (filterNew === "Новые") filters.new = true;
if (filterDate.length !== 0 && filterDate !== "За всё время") {
console.log(filterDate);
filters.to = new Date();
let resetedCurrentTime = Number(resetTime());
if (filterDate === "Сегодня")
filters.from = moment.unix(resetedCurrentTime)._d;
if (filterDate === "Вчера")
filters.from = moment.unix(resetedCurrentTime - 86400)._d;
if (filterDate === "Последние 7 дней")
filters.from = moment.unix(resetedCurrentTime - 604800)._d;
if (filterDate === "Последние 30 дней")
filters.from = moment.unix(resetedCurrentTime - 2592000)._d;
if (filterDate === "Этот месяц") {
let date = new Date(),
y = date.getFullYear(),
m = date.getMonth();
filters.from = new Date(y, m, 1);
}
}
return filters;
};
const getData = async () => {
if (editQuizId !== null) {
const quizes = await quizApi.getList();
setQuizes(quizes);
const questions = await questionApi.getList({ quiz_id: editQuizId });
setQuestions(questions);
const result = await resultApi.getList(editQuizId, 0, parseFilters());
setResults(result);
}
};
if (quiz === undefined)
return (
<Skeleton sx={{ width: "100vw", height: "100vh", transform: "none" }} />
);
2024-01-20 10:27:21 +00:00
return (
<Box>
<HeaderFull isRequest={true} />
2024-01-21 22:09:26 +00:00
<SectionWrapper
sx={{ padding: isMobile ? "0 16px" : "20px" }}
maxWidth="lg"
>
2024-01-20 10:27:21 +00:00
<Typography
sx={{
fontSize: "36px",
fontWeight: "500",
mb: "50px",
mt: "60px",
lineHeight: "normal",
}}
2024-01-20 10:27:21 +00:00
>
{quiz.name}
2024-01-20 10:27:21 +00:00
</Typography>
<Box
sx={{
width: "100%",
display: isTablet ? "flex" : "-moz-initial",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Box sx={{ display: "flex", alignItems: "center", gap: "8px" }}>
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>
Ответы на квиз
</Typography>
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
({total_count})
2024-01-20 10:27:21 +00:00
</Typography>
</Box>
<Box
sx={{
mt: "20px",
mb: "31px",
gap: "30px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: isTablet ? "auto" : "100%",
}}
>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<IconButton
onClick={async () => {
2024-02-20 11:54:08 +00:00
try {
const data = await resultApi.export(
editQuizId,
parseFilters(),
);
console.log(typeof data);
2024-02-10 16:31:27 +00:00
2024-02-20 11:54:08 +00:00
const blob = data;
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = `report_${new Date().getTime()}.xlsx`;
link.click();
} catch (nativeError) {
const error = nativeError as AxiosError;
if (error.response?.statusText === "Payment Required") {
setPrePaymentModalOpen(true);
}
}
}}
2024-01-20 10:27:21 +00:00
sx={{
width: "44px",
height: "44px",
borderRadius: "8px",
border: "1px solid #7E2AEA",
}}
>
<FileExportIcon />
</IconButton>
<IconButton
sx={{
width: "44px",
height: "44px",
borderRadius: "8px",
border: "1px solid #7E2AEA",
}}
onClick={async () => {
const result = await resultApi.getList(
editQuizId,
page - 1,
parseFilters(),
);
console.log(result);
setResults(result);
}}
2024-01-20 10:27:21 +00:00
>
<UpdateIcon />
</IconButton>
{isTablet && (
<IconButton
2024-01-21 22:09:26 +00:00
onClick={() => setFilterModalOpen(true)}
2024-01-20 10:27:21 +00:00
sx={{
2024-01-21 22:09:26 +00:00
background: "#fff",
2024-01-20 10:27:21 +00:00
width: "44px",
height: "44px",
borderRadius: "8px",
border: "1px solid #7E2AEA",
}}
>
<FilterIcon />
</IconButton>
)}
</Box>
{!isTablet && (
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "20px",
width: "100%",
justifyContent: "flex-end",
}}
>
<Select
items={itemsTime}
data={filterDate}
onChange={filterDateHC}
placeholder="За всё время"
/>
<Select
items={itemsNews}
data={filterNew}
onChange={filterNewHC}
placeholder="Все заявки"
/>
2024-01-20 10:27:21 +00:00
<Button
onClick={() => {
setFilterNew("Все заявки");
setFilterDate("За всё время");
}}
2024-01-20 10:27:21 +00:00
sx={{
maxWidth: "200px",
width: "100%",
height: "48px",
borderRadius: "8px",
border: "1px solid #7E2AEA",
color: "#7E2AEA",
}}
>
Сбросить фильтры
</Button>
</Box>
)}
</Box>
</Box>
<Pagination
variant="pena-pagination"
count={countPagination}
page={page}
onChange={async (e, value) => {
setPage(value);
const result = await resultApi.getList(
editQuizId,
value - 1,
parseFilters(),
);
setResults(result);
}}
sx={{
marginRight: "-15px",
marginLeft: "-15px",
marginBottom: "20px",
"& .MuiPaginationItem-root": {
height: "30px",
width: "30px",
minWidth: "30px",
marginLeft: "5px",
marginRight: "5px",
backgroundColor: "white",
color: "black",
fontSize: "16px",
lineHeight: "20px",
fontWeight: 400,
borderRadius: "5px",
"&.Mui-selected": {
backgroundColor: "white",
color: "#7E2AEA",
fontWeight: 500,
},
"&:hover": {
backgroundColor: "#ffffff55",
},
"&:active": {
backgroundColor: "#7F2CEA",
color: "white",
},
boxShadow: `
0px 77.2727px 238.773px rgba(210, 208, 225, 0.24),
0px 32.2827px 99.7535px rgba(210, 208, 225, 0.172525),
0px 17.2599px 53.333px rgba(210, 208, 225, 0.143066),
0px 9.67574px 29.8981px rgba(210, 208, 225, 0.12),
0px 5.13872px 15.8786px rgba(210, 208, 225, 0.0969343),
0px 2.13833px 6.60745px rgba(210, 208, 225, 0.0674749)
`,
},
"& .MuiPaginationItem-previousNext": {
backgroundColor: "#7E2AEA",
color: "white",
marginLeft: "15px",
marginRight: "15px",
"&:hover": {
backgroundColor: "#995DED",
},
},
}}
/>
2024-01-20 10:27:21 +00:00
{!isTablet && (
<Box
sx={{
display: "flex",
width: "100%",
alignItems: "center",
mb: "15px",
}}
>
<Typography sx={{ fontSize: "18px", color: "#9A9AAF", mr: "40px" }}>
заявки
</Typography>
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
Дата
</Typography>
<Typography
sx={{ fontSize: "18px", color: "#9A9AAF", ml: "288px" }}
>
Контакты
</Typography>
</Box>
)}
<Box
sx={{
display: "flex",
alignItems: "flex-start",
flexDirection: isTablet ? "-moz-initial" : "column",
flexWrap: isTablet ? "wrap" : "nowrap",
gap: "20px",
}}
>
{results.map((result) => {
const dataResult = new Date(result.created_at);
let dayResult = DateDefinition(result.created_at);
let timeResult = TimeDefinition(result.created_at);
return (
<CardAnswer
name={result.content.name}
email={result.content.email}
phone={result.content.phone}
address={result.content.address}
isNew={result.new}
idResult={result.id}
dayResult={dayResult}
timeResult={timeResult}
2024-02-20 11:54:08 +00:00
openPrePaymentModal={() => setPrePaymentModalOpen(true)}
/>
);
})}
2024-01-20 10:27:21 +00:00
</Box>
</SectionWrapper>
2024-01-21 22:09:26 +00:00
<FilterModal
open={filterModalOpen}
handleClose={() => setFilterModalOpen(false)}
filterNew={filterNew}
filterDate={filterDate}
setFilterNew={filterNewHC}
setFilterDate={filterDateHC}
itemsTime={itemsTime}
itemsNews={itemsNews}
2024-01-21 22:09:26 +00:00
/>
2024-02-20 11:54:08 +00:00
<PrePaymentModal
open={prePaymentModalOpen}
setOpen={setPrePaymentModalOpen}
/>
2024-01-20 10:27:21 +00:00
</Box>
);
};