вывод ответов на вопросы схематично, сохранение и сброс фильтров
This commit is contained in:
parent
7dc9cbe8d2
commit
ccee8eb5e3
@ -16,20 +16,30 @@ function deleteResult(resultId: number) {
|
||||
});
|
||||
}
|
||||
|
||||
export const obsolescenceResult = async (idResultArray: string[]) => {
|
||||
try {
|
||||
const response = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/result/seen`,
|
||||
body: {
|
||||
answers: idResultArray,
|
||||
},
|
||||
method: "PATCH",
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.log("ошибка", e);
|
||||
}
|
||||
};
|
||||
// export const obsolescenceResult = async (idResultArray: string[]) => {
|
||||
// try {
|
||||
// const response = await makeRequest<unknown, unknown>({
|
||||
// url: process.env.REACT_APP_DOMAIN + `/squiz/result/seen`,
|
||||
// body: {
|
||||
// answers: idResultArray,
|
||||
// },
|
||||
// method: "PATCH",
|
||||
// });
|
||||
// return response;
|
||||
// } catch (e) {
|
||||
// console.log("ошибка", e);
|
||||
// }
|
||||
// };
|
||||
|
||||
function obsolescenceResult(idResultArray: string[]) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/result/seen`,
|
||||
body: {
|
||||
answers: idResultArray,
|
||||
},
|
||||
method: "PATCH",
|
||||
});
|
||||
}
|
||||
|
||||
function getAnswerResultList(resultId: number) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
@ -38,13 +48,13 @@ function getAnswerResultList(resultId: number) {
|
||||
});
|
||||
}
|
||||
|
||||
function AnswerResultListEx(quizId: number) {
|
||||
function AnswerResultListEx(quizId: number, fromDate: string, toDate: string) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/results/${quizId}/export`,
|
||||
method: "POST",
|
||||
body: {
|
||||
to: new Date(),
|
||||
from: new Date("2024-01-24"),
|
||||
to: new Date(toDate),
|
||||
from: new Date(fromDate),
|
||||
new: true,
|
||||
},
|
||||
});
|
||||
@ -55,4 +65,5 @@ export const resultApi = {
|
||||
delete: deleteResult,
|
||||
getAnswerList: getAnswerResultList,
|
||||
export: AnswerResultListEx,
|
||||
obsolescence: obsolescenceResult,
|
||||
};
|
||||
|
||||
@ -13,7 +13,7 @@ import "./index.css";
|
||||
import lightTheme from "./utils/themes/light";
|
||||
import { SWRConfig } from "swr";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import moment from "moment"
|
||||
import moment from "moment";
|
||||
|
||||
dayjs.locale("ru");
|
||||
moment.locale("ru");
|
||||
|
||||
@ -17,8 +17,10 @@ import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||
import homeImg from "./images/home.png";
|
||||
import videoFrame from "./images/videoFrame.png";
|
||||
import { EyeIcon } from "./icons/EyeIcon";
|
||||
import { deleteResult } from "@root/results/actions";
|
||||
import { deleteResult, obsolescenceResult } from "@root/results/actions";
|
||||
import { resultApi } from "@api/result";
|
||||
import { useQuizStore } from "@root/quizes/store";
|
||||
import { useQuestionsStore } from "@root/questions/store";
|
||||
|
||||
interface Props {
|
||||
isNew: boolean;
|
||||
@ -29,7 +31,7 @@ interface Props {
|
||||
name?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
onLossNew: (id: string) => void;
|
||||
onLossNew?: (id: string) => void;
|
||||
}
|
||||
|
||||
export const CardAnswer = ({
|
||||
@ -47,11 +49,17 @@ export const CardAnswer = ({
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const [resultsAnswer, setResultsAnswer] = useState([]);
|
||||
|
||||
const { editQuizId } = useQuizStore();
|
||||
const { questions } = useQuestionsStore();
|
||||
console.log(questions);
|
||||
// console.log(questions[0].backendId)
|
||||
// console.log(questions[1].backendId)
|
||||
// console.log(questions[2].backendId)
|
||||
// console.log(questions[3].backendId)
|
||||
return (
|
||||
<Box
|
||||
onClick={() => {
|
||||
if (isNew) onLossNew(idResult);
|
||||
obsolescenceResult(idResult, editQuizId);
|
||||
}}
|
||||
sx={{
|
||||
borderRadius: "12px",
|
||||
@ -121,8 +129,9 @@ export const CardAnswer = ({
|
||||
let resAnswer = await resultApi.getAnswerList(
|
||||
Number(idResult),
|
||||
);
|
||||
resAnswer = resAnswer.filter((res) => res.Result !== true);
|
||||
setResultsAnswer(resAnswer);
|
||||
console.log("тут хранятся ответы", resultsAnswer);
|
||||
console.log("тут хранятся ответы", resAnswer);
|
||||
}
|
||||
}}
|
||||
>
|
||||
@ -319,102 +328,22 @@ export const CardAnswer = ({
|
||||
mt: "20px",
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
1.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 1 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
2.
|
||||
</Typography>
|
||||
<img src={homeImg} style={{ width: "40px", height: "40px" }} />
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
3.
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
color: "#7E2AEA",
|
||||
borderBottom: "1px solid #7E2AEA",
|
||||
}}
|
||||
>
|
||||
ответ.doc
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
4.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 4 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
5.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 5 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
6.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 6 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
{resultsAnswer.map((answer, id) => {
|
||||
console.log(answer.QuizId);
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "15px",
|
||||
mt: "20px",
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
7.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 7 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
8.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 8 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
9.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
Ответ на 9 вопрос
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
10.
|
||||
</Typography>
|
||||
<img
|
||||
src={videoFrame}
|
||||
style={{ width: "40px", height: "40px" }}
|
||||
/>
|
||||
</Box>
|
||||
return (
|
||||
<Box
|
||||
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
|
||||
>
|
||||
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
|
||||
{id + 1}.
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "18px" }}>
|
||||
{answer.content}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
|
||||
@ -3,78 +3,88 @@ import {
|
||||
Button,
|
||||
IconButton,
|
||||
Typography,
|
||||
Select as MuiSelect,
|
||||
MenuItem,
|
||||
useTheme,
|
||||
useMediaQuery,
|
||||
Skeleton,
|
||||
FormControl,
|
||||
Select,
|
||||
} from "@mui/material";
|
||||
import moment from "moment"
|
||||
import moment from "moment";
|
||||
import HeaderFull from "@ui_kit/Header/HeaderFull";
|
||||
import SectionWrapper from "@ui_kit/SectionWrapper";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { FileExportIcon } from "./icons/FileExporIcon";
|
||||
import { UpdateIcon } from "./icons/UpdateIcon";
|
||||
import { Select } from "../../pages/Questions/Select";
|
||||
// import { Select } from "../../pages/Questions/Select";
|
||||
import { CheckboxSelect } from "../../ui_kit/CheckboxSelect";
|
||||
import { CardAnswer } from "./CardAnswer";
|
||||
import { FilterIcon } from "./icons/FilterIcon";
|
||||
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
|
||||
import { ExportContactsModal } from "@ui_kit/Modal/ExportContactsModal";
|
||||
|
||||
import {
|
||||
AnswerResultListEx,
|
||||
getResultsList,
|
||||
obsolescenceResult,
|
||||
resultApi,
|
||||
} from "@api/result";
|
||||
import { resultApi } from "@api/result";
|
||||
import { useObsolescenceIdResult, useResultStore } from "@root/results/store";
|
||||
import { setResults } from "@root/results/actions";
|
||||
import { answerResultListExport, 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";
|
||||
import ArrowDown from "@icons/ArrowDownIcon";
|
||||
|
||||
const options = [
|
||||
{ label: "Муром (1)", value: "option1" },
|
||||
{ label: "Москва (1)", value: "option2" },
|
||||
];
|
||||
|
||||
let lossDebouncer: null | ReturnType<typeof setTimeout> = null;
|
||||
let lossId: string[] = [] as string[];
|
||||
const itemsTime = [
|
||||
"За все время",
|
||||
"Сегодня",
|
||||
"Вчера",
|
||||
"Последние 7 дней",
|
||||
"Последние 30 дней",
|
||||
"Этот месяц",
|
||||
];
|
||||
|
||||
const onLossNew = (id: string) => {
|
||||
//Если в массиве ещё нет такого id - добавляем
|
||||
if (!lossId.includes(id)) lossId.push(id);
|
||||
//Если таймер есть - сбрасываем
|
||||
if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
|
||||
//Назначем новый таймер
|
||||
lossDebouncer = setTimeout(async () => {
|
||||
//стреляем на лишение новизны
|
||||
await obsolescenceResult(lossId);
|
||||
//сбрасываем массив
|
||||
lossId = [];
|
||||
}, 3000);
|
||||
// let lossDebouncer: null | ReturnType<typeof setTimeout> = null;
|
||||
// let lossId: string[] = [] as string[];
|
||||
//
|
||||
// const onLossNew = (id: string) => {
|
||||
// //Если в массиве ещё нет такого id - добавляем
|
||||
// if (!lossId.includes(id)) lossId.push(id);
|
||||
// //Если таймер есть - сбрасываем
|
||||
// if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
|
||||
// //Назначем новый таймер
|
||||
// lossDebouncer = setTimeout(async () => {
|
||||
// //стреляем на лишение новизны
|
||||
// await obsolescenceResult(lossId);
|
||||
// //сбрасываем массив
|
||||
// lossId = [];
|
||||
// }, 3000);
|
||||
// };
|
||||
|
||||
const resetTime = (date: number) => {
|
||||
console.log(date);
|
||||
let a = Math.round(date / 86400) * 86400 - 97200;
|
||||
console.log(a);
|
||||
console.log(moment.unix(a).format("dddd, MMMM Do YYYY, h:mm:ss "));
|
||||
return moment.unix(a).format("dddd, MMMM Do YYYY, h:mm:ss ");
|
||||
};
|
||||
|
||||
const resetTime = (date:number) => {
|
||||
console.log(date)
|
||||
let a = Math.round(date / 86400) * 86400 - 97200
|
||||
console.log(a)
|
||||
console.log(moment.unix(a).format("dddd, MMMM Do YYYY, h:mm:ss "))
|
||||
return(moment.unix(a).format("dddd, MMMM Do YYYY, h:mm:ss "))
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const QuizAnswersPage: FC = () => {
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||
|
||||
const [filterModalOpen, setFilterModalOpen] = useState<boolean>(false);
|
||||
const [exportContactsModalOpen, setExportContactsModalOpen] = useState<boolean>(false);
|
||||
const [filterNew, setFilterNew] = useState<string>("Все заявки")
|
||||
const [filterDate, setFilterDate] = useState<string>("За всё время")
|
||||
const [exportContactsModalOpen, setExportContactsModalOpen] =
|
||||
useState<boolean>(false);
|
||||
const [filterNew, setFilterNew] = useState<string>("Все заявки");
|
||||
const [filterDate, setFilterDate] = useState<string>("За все время");
|
||||
|
||||
const quizList = useQuizStore();
|
||||
const quiz = useCurrentQuiz();
|
||||
@ -82,13 +92,15 @@ export const QuizAnswersPage: FC = () => {
|
||||
const { results } = useResultStore();
|
||||
const { total_count } = useResultStore();
|
||||
// const {idResultArray, addIdResult, clearIdResultArray} = useObsolescenceIdResult()
|
||||
|
||||
useEffect(() => {
|
||||
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);
|
||||
setResults(result);
|
||||
}
|
||||
@ -166,34 +178,9 @@ export const QuizAnswersPage: FC = () => {
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
||||
<IconButton
|
||||
onClick={async () => {
|
||||
//setExportContactsModalOpen(true)
|
||||
const resAnswer = await AnswerResultListEx(quizList.editQuizId)
|
||||
console.log("ответы респондентов на экспорт по клику", resAnswer)
|
||||
const download = function () {
|
||||
|
||||
// Creating a Blob for having a csv file format
|
||||
// and passing the data with type
|
||||
const blob = new Blob([resAnswer], { type: 'text/csv' });
|
||||
|
||||
|
||||
// Creating an object for downloading url
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
|
||||
// Creating an anchor(a) tag of HTML
|
||||
const a = document.createElement('a')
|
||||
|
||||
// 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()
|
||||
onClick={() => {
|
||||
// answerResultListExport(editQuizId)
|
||||
setExportContactsModalOpen(true);
|
||||
}}
|
||||
sx={{
|
||||
width: "44px",
|
||||
@ -246,23 +233,154 @@ export const QuizAnswersPage: FC = () => {
|
||||
justifyContent: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
<FormControl
|
||||
fullWidth
|
||||
sx={{ maxWidth: "223px", width: "100%" }}
|
||||
items={[
|
||||
"За все время",
|
||||
"Сегодня",
|
||||
"Вчера",
|
||||
"Последние 7 дней",
|
||||
"Последние 30 дней",
|
||||
"Этот месяц",
|
||||
]}
|
||||
onChange={(e) => setFilterNew(e.value)}
|
||||
/>
|
||||
<Select
|
||||
>
|
||||
<Select
|
||||
id="display-select"
|
||||
variant="outlined"
|
||||
value={filterDate}
|
||||
onChange={(event) => {
|
||||
setFilterDate(event.target.value as string);
|
||||
}}
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "48px",
|
||||
borderRadius: "8px",
|
||||
"& .MuiOutlinedInput-notchedOutline": {
|
||||
border: `1px solid #7E2AEA !important`,
|
||||
borderRadius: "10px",
|
||||
},
|
||||
}}
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
sx: {
|
||||
mt: "8px",
|
||||
p: "4px",
|
||||
borderRadius: "8px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: "1px solid #EEE4FC",
|
||||
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
||||
},
|
||||
},
|
||||
MenuListProps: {
|
||||
sx: {
|
||||
py: 0,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
"& .Mui-selected": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: "#7E2AEA",
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
inputProps={{
|
||||
sx: {
|
||||
color: "#7E2AEA",
|
||||
display: "block",
|
||||
px: "9px",
|
||||
gap: "20px",
|
||||
width: "90%",
|
||||
},
|
||||
}}
|
||||
IconComponent={(props) => <ArrowDown {...props} />}
|
||||
>
|
||||
{itemsTime.map((item, index) => (
|
||||
<MenuItem
|
||||
key={item + index}
|
||||
value={item}
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "20px",
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
color: "#9A9AAF",
|
||||
whiteSpace: "normal",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
fullWidth
|
||||
sx={{ maxWidth: "223px", width: "100%" }}
|
||||
items={["Все заявки", "Новые", ]}
|
||||
/>
|
||||
|
||||
>
|
||||
<Select
|
||||
id="display-select"
|
||||
variant="outlined"
|
||||
value={filterNew}
|
||||
onChange={(event) => {
|
||||
setFilterNew(event.target.value as string);
|
||||
}}
|
||||
sx={{
|
||||
width: "100%",
|
||||
height: "48px",
|
||||
borderRadius: "8px",
|
||||
"& .MuiOutlinedInput-notchedOutline": {
|
||||
border: `1px solid #7E2AEA !important`,
|
||||
borderRadius: "10px",
|
||||
},
|
||||
}}
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
sx: {
|
||||
mt: "8px",
|
||||
p: "4px",
|
||||
borderRadius: "8px",
|
||||
backgroundColor: theme.palette.background.default,
|
||||
border: "1px solid #EEE4FC",
|
||||
boxShadow: "0px 8px 24px rgba(210, 208, 225, 0.4)",
|
||||
},
|
||||
},
|
||||
MenuListProps: {
|
||||
sx: {
|
||||
py: 0,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
"& .Mui-selected": {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: "#7E2AEA",
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
inputProps={{
|
||||
sx: {
|
||||
color: "#7E2AEA",
|
||||
display: "block",
|
||||
px: "9px",
|
||||
gap: "20px",
|
||||
width: "90%",
|
||||
},
|
||||
}}
|
||||
IconComponent={(props) => <ArrowDown {...props} />}
|
||||
>
|
||||
{["Все заявки", "Новые"].map((item, index) => (
|
||||
<MenuItem
|
||||
key={item + index}
|
||||
value={item}
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "20px",
|
||||
padding: "10px",
|
||||
borderRadius: "5px",
|
||||
color: "#9A9AAF",
|
||||
whiteSpace: "normal",
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
{/* <CheckboxSelect
|
||||
sx={{ maxWidth: "223px", width: "100%" }}
|
||||
placeholder="Выберите город"
|
||||
@ -270,6 +388,10 @@ export const QuizAnswersPage: FC = () => {
|
||||
/> */}
|
||||
|
||||
<Button
|
||||
onClick={() => {
|
||||
setFilterNew("Все заявки");
|
||||
setFilterDate("За все время");
|
||||
}}
|
||||
sx={{
|
||||
maxWidth: "200px",
|
||||
width: "100%",
|
||||
@ -330,7 +452,6 @@ export const QuizAnswersPage: FC = () => {
|
||||
idResult={result.id}
|
||||
dayResult={dayResult}
|
||||
timeResult={timeResult}
|
||||
onLossNew={onLossNew}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -340,12 +461,13 @@ export const QuizAnswersPage: FC = () => {
|
||||
<FilterModal
|
||||
open={filterModalOpen}
|
||||
handleClose={() => setFilterModalOpen(false)}
|
||||
filterNew = {filterNew}
|
||||
filterDate = {filterDate}
|
||||
setFilterNew = {setFilterNew}
|
||||
setFilterDate = {setFilterDate}
|
||||
filterNew={filterNew}
|
||||
filterDate={filterDate}
|
||||
setFilterNew={setFilterNew}
|
||||
setFilterDate={setFilterDate}
|
||||
/>
|
||||
<ExportContactsModal
|
||||
editQuizId={editQuizId}
|
||||
open={exportContactsModalOpen}
|
||||
handleClose={() => setExportContactsModalOpen(false)}
|
||||
/>
|
||||
|
||||
@ -5,6 +5,7 @@ import { RequestQueue } from "@utils/requestQueue";
|
||||
import { resultApi } from "@api/result";
|
||||
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useQuizStore } from "@root/quizes/store";
|
||||
|
||||
const REQUEST_DEBOUNCE = 200;
|
||||
const requestQueue = new RequestQueue();
|
||||
@ -13,8 +14,6 @@ let requestTimeoutId: ReturnType<typeof setTimeout>;
|
||||
export const setResults = (results: RawResult[] | null) =>
|
||||
setProducedState(
|
||||
(state) => {
|
||||
// console.log("!!!!!!!!!!!", results)
|
||||
// console.log("65876567", Object.values(results)[1]?.map(rawResultToResult))
|
||||
state.results = Object.values(results)[1]?.map(rawResultToResult) ?? [];
|
||||
state.total_count = Object.values(results)[0];
|
||||
},
|
||||
@ -51,6 +50,67 @@ export const deleteResult = async (resultId: number) =>
|
||||
}
|
||||
});
|
||||
|
||||
export const obsolescenceResult = async (
|
||||
resultId: string,
|
||||
editQuizId: number,
|
||||
) =>
|
||||
requestQueue.enqueue(async () => {
|
||||
const result = useResultStore
|
||||
.getState()
|
||||
.results.find((r) => r.id === resultId);
|
||||
if (!result) return;
|
||||
if (result.new === false) return;
|
||||
let lossDebouncer: null | ReturnType<typeof setTimeout> = null;
|
||||
let lossId: string[] = [] as string[];
|
||||
if (!lossId.includes(resultId)) lossId.push(resultId);
|
||||
if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
|
||||
lossDebouncer = setTimeout(async () => {
|
||||
//стреляем на лишение новизны
|
||||
try {
|
||||
await resultApi.obsolescence(lossId);
|
||||
//сбрасываем массив
|
||||
lossId = [];
|
||||
} catch (error) {
|
||||
devlog("Error", error);
|
||||
|
||||
const message = getMessageFromFetchError(error) ?? "";
|
||||
enqueueSnackbar(`Ошибка. ${message}`);
|
||||
}
|
||||
}, 3000);
|
||||
const resultList = await resultApi.getList(editQuizId);
|
||||
setResults(resultList);
|
||||
});
|
||||
|
||||
export const answerResultListExport = async (
|
||||
editQuizId: number,
|
||||
toDate: string,
|
||||
fromDate: string,
|
||||
) => {
|
||||
const resAnswer = await resultApi.export(editQuizId, toDate, fromDate);
|
||||
const download = function () {
|
||||
// Creating a Blob for having a csv file format
|
||||
// and passing the data with type
|
||||
const blob = new Blob([resAnswer], { type: "application/json" });
|
||||
|
||||
// Creating an object for downloading url
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
|
||||
// Creating an anchor(a) tag of HTML
|
||||
const a = document.createElement("a");
|
||||
|
||||
// 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 }>(
|
||||
recipe: (state: ResultStore) => void,
|
||||
action?: A,
|
||||
|
||||
@ -6,19 +6,30 @@ import {
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import { FC } from "react";
|
||||
import { FC, useState } from "react";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import CustomCheckbox from "@ui_kit/CustomCheckbox";
|
||||
import CalendarIcon from "@icons/CalendarIcon";
|
||||
import moment from "moment";
|
||||
import { answerResultListExport } from "@root/results/actions";
|
||||
|
||||
interface Iprops {
|
||||
open: boolean;
|
||||
editQuizId: string;
|
||||
handleClose: () => void;
|
||||
}
|
||||
|
||||
export const ExportContactsModal: FC<Iprops> = ({ open, handleClose }) => {
|
||||
export const ExportContactsModal: FC<Iprops> = ({
|
||||
open,
|
||||
handleClose,
|
||||
editQuizId,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(650));
|
||||
const [fromDate, setFromDate] = useState("");
|
||||
const [toDate, setToDate] = useState("");
|
||||
console.log("from", fromDate);
|
||||
console.log("to", toDate);
|
||||
|
||||
const style = {
|
||||
position: "absolute" as "absolute",
|
||||
@ -71,6 +82,9 @@ export const ExportContactsModal: FC<Iprops> = ({ open, handleClose }) => {
|
||||
>
|
||||
<Typography>c</Typography>
|
||||
<DatePicker
|
||||
onChange={(date) => {
|
||||
setFromDate(date);
|
||||
}}
|
||||
slots={{
|
||||
openPickerIcon: () => <CalendarIcon />,
|
||||
}}
|
||||
@ -112,6 +126,9 @@ export const ExportContactsModal: FC<Iprops> = ({ open, handleClose }) => {
|
||||
<Typography>до</Typography>
|
||||
|
||||
<DatePicker
|
||||
onChange={(date) => {
|
||||
setToDate(date);
|
||||
}}
|
||||
slots={{
|
||||
openPickerIcon: () => <CalendarIcon />,
|
||||
}}
|
||||
@ -145,11 +162,11 @@ export const ExportContactsModal: FC<Iprops> = ({ open, handleClose }) => {
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{ p: "0 20px 20px" }}>
|
||||
<Box sx={{ display: "flex", flexDirection: "column", gap: "14px" }}>
|
||||
<CustomCheckbox label="Ответы в отдельных полях" />
|
||||
<CustomCheckbox label="Cookies в отдельных полях" />
|
||||
<CustomCheckbox label="Только верифицированные номера" />
|
||||
</Box>
|
||||
{/*<Box sx={{ display: "flex", flexDirection: "column", gap: "14px" }}>*/}
|
||||
{/* <CustomCheckbox label="Ответы в отдельных полях" />*/}
|
||||
{/* <CustomCheckbox label="Cookies в отдельных полях" />*/}
|
||||
{/* <CustomCheckbox label="Только верифицированные номера" />*/}
|
||||
{/*</Box>*/}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@ -171,6 +188,9 @@ export const ExportContactsModal: FC<Iprops> = ({ open, handleClose }) => {
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() =>
|
||||
answerResultListExport(editQuizId, toDate, fromDate)
|
||||
}
|
||||
sx={{
|
||||
width: isMobile ? "100%" : "130px",
|
||||
height: "48px",
|
||||
|
||||
@ -19,10 +19,10 @@ const options = [
|
||||
interface Iprops {
|
||||
open: boolean;
|
||||
handleClose: () => void;
|
||||
filterNew: boolean
|
||||
filterDate:string
|
||||
setFilterNew: (a:string)=>void
|
||||
setFilterDate:(a:string)=>void
|
||||
filterNew: boolean;
|
||||
filterDate: string;
|
||||
setFilterNew: (a: string) => void;
|
||||
setFilterDate: (a: string) => void;
|
||||
}
|
||||
|
||||
export const FilterModal: FC<Iprops> = ({
|
||||
@ -93,7 +93,7 @@ export const FilterModal: FC<Iprops> = ({
|
||||
/>
|
||||
<Select
|
||||
sx={{ width: "100%" }}
|
||||
items={["Все заявки", "Новые", ]}
|
||||
items={["Все заявки", "Новые"]}
|
||||
data={filterNew}
|
||||
setData={setFilterNew}
|
||||
/>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user