отделение логики от верстки на странице результатов
This commit is contained in:
parent
dfa690685a
commit
d74b9159a8
@ -25,6 +25,7 @@ import { useQuestionsStore } from "@root/questions/store";
|
|||||||
import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
|
import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
|
||||||
|
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
|
import { DeleteModal } from "./DeleteModal";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isNew: boolean;
|
isNew: boolean;
|
||||||
@ -277,49 +278,14 @@ export const CardAnswer = ({
|
|||||||
<DeleteIcon color="#4D4D4D" fontSize="34px" />
|
<DeleteIcon color="#4D4D4D" fontSize="34px" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
<Modal open={openDelete} onClose={() => setOpenDelete(false)}>
|
<DeleteModal
|
||||||
<Box
|
openDelete={openDelete}
|
||||||
sx={{
|
handleClose={() => setOpenDelete(false)}
|
||||||
position: "absolute",
|
onClick={() => {
|
||||||
top: "50%",
|
deleteResult(Number(idResult));
|
||||||
left: "50%",
|
setOpenDelete(false);
|
||||||
transform: "translate(-50%, -50%)",
|
}}
|
||||||
padding: "30px",
|
/>
|
||||||
borderRadius: "10px",
|
|
||||||
background: "#FFFFFF",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography variant="h6" sx={{ textAlign: "center" }}>
|
|
||||||
Вы уверены, что хотите удалить этот результат?
|
|
||||||
</Typography>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
marginTop: "30px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: "15px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
sx={{ minWidth: "150px" }}
|
|
||||||
onClick={() => setOpenDelete(false)}
|
|
||||||
>
|
|
||||||
Отмена
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
sx={{ minWidth: "150px" }}
|
|
||||||
onClick={() => {
|
|
||||||
deleteResult(Number(idResult));
|
|
||||||
setOpenDelete(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Подтвердить
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Modal>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@ import { Box, Button, Modal, Typography } from "@mui/material";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
openDelete: boolean;
|
openDelete: boolean;
|
||||||
setOpenDelete: (open: boolean) => void;
|
handleClose: () => void;
|
||||||
|
onClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeleteModal = ({ openDelete, setOpenDelete }: Props) => {
|
export const DeleteModal = ({ openDelete, handleClose, onClick }: Props) => {
|
||||||
return (
|
return (
|
||||||
<Modal open={openDelete} onClose={() => setOpenDelete(false)}>
|
<Modal open={openDelete} onClose={handleClose}>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@ -33,18 +34,14 @@ export const DeleteModal = ({ openDelete, setOpenDelete }: Props) => {
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{ minWidth: "150px" }}
|
sx={{ minWidth: "150px" }}
|
||||||
onClick={() => setOpenDelete(false)}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Отмена
|
Отмена
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{ minWidth: "150px" }}
|
sx={{ minWidth: "150px" }}
|
||||||
onClick={() => {
|
onClick={onClick}
|
||||||
// deleteQuestionWithTimeout(question.id, () =>
|
|
||||||
// DeleteFunction(questions, question, quiz),
|
|
||||||
// );
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Подтвердить
|
Подтвердить
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,44 +1,32 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
|
||||||
IconButton,
|
|
||||||
Typography,
|
Typography,
|
||||||
MenuItem,
|
|
||||||
useTheme,
|
useTheme,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
Skeleton,
|
Skeleton,
|
||||||
FormControl,
|
|
||||||
Pagination,
|
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Select } from "../../pages/Questions/Select";
|
|
||||||
import moment from "moment";
|
|
||||||
import HeaderFull from "@ui_kit/Header/HeaderFull";
|
import HeaderFull from "@ui_kit/Header/HeaderFull";
|
||||||
import SectionWrapper from "@ui_kit/SectionWrapper";
|
import SectionWrapper from "@ui_kit/SectionWrapper";
|
||||||
import { FC, useEffect, useState } from "react";
|
import { FC, useEffect, useState } from "react";
|
||||||
import { FileExportIcon } from "./icons/FileExporIcon";
|
|
||||||
import { UpdateIcon } from "./icons/UpdateIcon";
|
|
||||||
import { CheckboxSelect } from "../../ui_kit/CheckboxSelect";
|
|
||||||
import { CardAnswer } from "./CardAnswer";
|
import { CardAnswer } from "./CardAnswer";
|
||||||
import { FilterIcon } from "./icons/FilterIcon";
|
|
||||||
import { PrePaymentModal } from "./PrePaymentModal";
|
import { PrePaymentModal } from "./PrePaymentModal";
|
||||||
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
|
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
|
||||||
import { ExportContactsModal } from "@ui_kit/Modal/ExportContactsModal";
|
|
||||||
|
|
||||||
import { resultApi } from "@api/result";
|
import { resultApi } from "@api/result";
|
||||||
import { useResultStore } from "@root/results/store";
|
import { useResultStore } from "@root/results/store";
|
||||||
import { setResults } from "@root/results/actions";
|
import { ExportResults, setResults } from "@root/results/actions";
|
||||||
|
|
||||||
import { quizApi } from "@api/quiz";
|
import { quizApi } from "@api/quiz";
|
||||||
import { setQuizes } from "@root/quizes/actions";
|
import { setQuizes } from "@root/quizes/actions";
|
||||||
import { useCurrentQuiz, useQuizes } from "@root/quizes/hooks";
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
import { useQuizStore } from "@root/quizes/store";
|
import { useQuizStore } from "@root/quizes/store";
|
||||||
import { questionApi } from "@api/question";
|
import { questionApi } from "@api/question";
|
||||||
import { setQuestions } from "@root/questions/actions";
|
import { setQuestions } from "@root/questions/actions";
|
||||||
import { useUserStore } from "@root/user";
|
import { useUserStore } from "@root/user";
|
||||||
|
|
||||||
import type { AxiosError } from "axios";
|
|
||||||
import CustomPagination from "@ui_kit/CustomPagination";
|
import CustomPagination from "@ui_kit/CustomPagination";
|
||||||
import SettingResults from "./SettingResults";
|
import SettingResults from "./SettingResults";
|
||||||
|
import { DateDefinition, parseFilters, TimeDefinition } from "./helper";
|
||||||
|
|
||||||
const itemsCities = [
|
const itemsCities = [
|
||||||
{ label: "Муром (1)", value: "option1" },
|
{ label: "Муром (1)", value: "option1" },
|
||||||
@ -55,10 +43,6 @@ const itemsTime = [
|
|||||||
];
|
];
|
||||||
const itemsNews = ["Все заявки", "Новые"];
|
const itemsNews = ["Все заявки", "Новые"];
|
||||||
|
|
||||||
const resetTime = () => {
|
|
||||||
return Math.round(Number(moment().format("X")) / 86400 - 1) * 86400 - 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const QuizAnswersPage: FC = () => {
|
export const QuizAnswersPage: FC = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
@ -81,7 +65,6 @@ export const QuizAnswersPage: FC = () => {
|
|||||||
setFilterDate(value);
|
setFilterDate(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const quizList = useQuizStore();
|
|
||||||
const quiz = useCurrentQuiz();
|
const quiz = useCurrentQuiz();
|
||||||
const { editQuizId } = useQuizStore();
|
const { editQuizId } = useQuizStore();
|
||||||
const { results, total_count } = useResultStore();
|
const { results, total_count } = useResultStore();
|
||||||
@ -111,54 +94,6 @@ export const QuizAnswersPage: FC = () => {
|
|||||||
setPrePaymentModalOpen(false);
|
setPrePaymentModalOpen(false);
|
||||||
}, [userAccount]);
|
}, [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 () => {
|
const getData = async () => {
|
||||||
if (editQuizId !== null) {
|
if (editQuizId !== null) {
|
||||||
const quizes = await quizApi.getList();
|
const quizes = await quizApi.getList();
|
||||||
@ -167,7 +102,11 @@ export const QuizAnswersPage: FC = () => {
|
|||||||
const questions = await questionApi.getList({ quiz_id: editQuizId });
|
const questions = await questionApi.getList({ quiz_id: editQuizId });
|
||||||
setQuestions(questions);
|
setQuestions(questions);
|
||||||
|
|
||||||
const result = await resultApi.getList(editQuizId, 0, parseFilters());
|
const result = await resultApi.getList(
|
||||||
|
editQuizId,
|
||||||
|
0,
|
||||||
|
parseFilters(filterNew, filterDate),
|
||||||
|
);
|
||||||
setResults(result);
|
setResults(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -177,7 +116,7 @@ export const QuizAnswersPage: FC = () => {
|
|||||||
const result = await resultApi.getList(
|
const result = await resultApi.getList(
|
||||||
editQuizId,
|
editQuizId,
|
||||||
value - 1,
|
value - 1,
|
||||||
parseFilters(),
|
parseFilters(filterNew, filterDate),
|
||||||
);
|
);
|
||||||
setResults(result);
|
setResults(result);
|
||||||
};
|
};
|
||||||
@ -235,34 +174,20 @@ export const QuizAnswersPage: FC = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SettingResults
|
<SettingResults
|
||||||
onclickExport={async () => {
|
onclickExport={() =>
|
||||||
try {
|
ExportResults(
|
||||||
const data = await resultApi.export(
|
filterNew,
|
||||||
editQuizId,
|
filterDate,
|
||||||
parseFilters(),
|
() => setPrePaymentModalOpen(true),
|
||||||
);
|
editQuizId,
|
||||||
console.log(typeof data);
|
)
|
||||||
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onclickUpdate={async () => {
|
onclickUpdate={async () => {
|
||||||
const result = await resultApi.getList(
|
const result = await resultApi.getList(
|
||||||
editQuizId,
|
editQuizId,
|
||||||
page - 1,
|
page - 1,
|
||||||
parseFilters(),
|
parseFilters(filterNew, filterDate),
|
||||||
);
|
);
|
||||||
console.log(result);
|
|
||||||
setResults(result);
|
setResults(result);
|
||||||
}}
|
}}
|
||||||
onclickFilterTablet={() => setFilterModalOpen(true)}
|
onclickFilterTablet={() => setFilterModalOpen(true)}
|
||||||
|
55
src/pages/QuizAnswersPage/helper.ts
Normal file
55
src/pages/QuizAnswersPage/helper.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
const resetTime = () => {
|
||||||
|
return Math.round(Number(moment().format("X")) / 86400 - 1) * 86400 - 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseFilters = (filterNew: string, filterDate: string) => {
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
export 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;
|
||||||
|
};
|
||||||
|
export const TimeDefinition = (result: string) => {
|
||||||
|
//достаём время
|
||||||
|
let timeResult = new Date(result).toLocaleTimeString().slice(0, -3);
|
||||||
|
return timeResult;
|
||||||
|
};
|
@ -6,6 +6,8 @@ import { resultApi } from "@api/result";
|
|||||||
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { useQuizStore } from "@root/quizes/store";
|
import { useQuizStore } from "@root/quizes/store";
|
||||||
|
import { AxiosError } from "axios";
|
||||||
|
import { parseFilters } from "../../pages/QuizAnswersPage/helper";
|
||||||
|
|
||||||
const REQUEST_DEBOUNCE = 200;
|
const REQUEST_DEBOUNCE = 200;
|
||||||
const requestQueue = new RequestQueue();
|
const requestQueue = new RequestQueue();
|
||||||
@ -81,34 +83,31 @@ export const obsolescenceResult = async (
|
|||||||
setResults(resultList);
|
setResults(resultList);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const answerResultListExport = async (
|
export const ExportResults = async (
|
||||||
editQuizId: number,
|
filterNew: string,
|
||||||
toDate: string,
|
filterDate: string,
|
||||||
fromDate: string,
|
openPrePaymentModal: () => void,
|
||||||
|
editQuizId: number | null,
|
||||||
) => {
|
) => {
|
||||||
const resAnswer = await resultApi.export(editQuizId, toDate, fromDate);
|
try {
|
||||||
const download = function () {
|
const data = await resultApi.export(
|
||||||
// Creating a Blob for having a csv file format
|
editQuizId,
|
||||||
// and passing the data with type
|
parseFilters(filterNew, filterDate),
|
||||||
const blob = new Blob([resAnswer], { type: "application/json" });
|
);
|
||||||
|
console.log(typeof data);
|
||||||
|
|
||||||
// Creating an object for downloading url
|
const blob = data;
|
||||||
const url = window.URL.createObjectURL(blob);
|
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;
|
||||||
|
|
||||||
// Creating an anchor(a) tag of HTML
|
if (error.response?.statusText === "Payment Required") {
|
||||||
const a = document.createElement("a");
|
openPrePaymentModal();
|
||||||
|
}
|
||||||
// Passing the blob downloading url
|
}
|
||||||
a.setAttribute("href", url);
|
|
||||||
|
|
||||||
// Setting the anchor tag attribute for downloading
|
|
||||||
// and passing the download file name
|
|
||||||
a.setAttribute("download", "download.csv");
|
|
||||||
|
|
||||||
// Performing a download with click
|
|
||||||
a.click();
|
|
||||||
};
|
|
||||||
download();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function setProducedState<A extends string | { type: unknown }>(
|
function setProducedState<A extends string | { type: unknown }>(
|
||||||
|
@ -188,9 +188,9 @@ export const ExportContactsModal: FC<Iprops> = ({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={() =>
|
// onClick={() =>
|
||||||
answerResultListExport(editQuizId, toDate, fromDate)
|
// answerResultListExport(editQuizId, toDate, fromDate)
|
||||||
}
|
// }
|
||||||
sx={{
|
sx={{
|
||||||
width: isMobile ? "100%" : "130px",
|
width: isMobile ? "100%" : "130px",
|
||||||
height: "48px",
|
height: "48px",
|
||||||
|
Loading…
Reference in New Issue
Block a user