Merge branch 'refactoring-applications-page' into dev

This commit is contained in:
Nastya 2024-03-28 01:36:23 +03:00
commit 30e97416fa
15 changed files with 694 additions and 567 deletions

@ -1,7 +1,36 @@
import { makeRequest } from "@frontend/kitui";
import { RawResult } from "@model/result/result";
async function getResultList(quizId, page: number, body: any) {
return makeRequest<unknown, unknown>({
interface IResultListBody {
to: number;
from: string;
new: boolean;
page: number;
limit: number;
}
export interface IAnswerResult {
Browser: string;
CreatedAt: string;
Deleted: boolean;
Device: string;
DeviceType: string;
Email: string;
Fingerprint: string;
IP: string;
Id: number;
OS: string;
QuizId: number;
Result: boolean;
Session: string;
Start: boolean;
content: string;
new: boolean;
question_id: number;
}
async function getResultList(quizId: number, page: number, body: any) {
return makeRequest<IResultListBody, RawResult>({
url: process.env.REACT_APP_DOMAIN + `/squiz/results/getResults/${quizId}`,
method: "POST",
body: { page: page, limit: 10, ...body },
@ -31,7 +60,7 @@ function deleteResult(resultId: number) {
// }
// };
function obsolescenceResult(idResultArray: string[]) {
function obsolescenceResult(idResultArray: number[]) {
return makeRequest<unknown, unknown>({
url: process.env.REACT_APP_DOMAIN + `/squiz/result/seen`,
body: {
@ -42,7 +71,7 @@ function obsolescenceResult(idResultArray: string[]) {
}
function getAnswerResultList(resultId: number) {
return makeRequest<unknown, unknown>({
return makeRequest<unknown, IAnswerResult[]>({
url: process.env.REACT_APP_DOMAIN + `/squiz/result/${resultId}`,
method: "GET",
});

@ -1,11 +1,13 @@
export interface RawResult {
total_count: number;
results: {
results: RawResultItem[];
}
export interface RawResultItem {
content: string;
id: number;
new: boolean;
created_at: string;
};
}
export interface ResultContent {
name?: string;
@ -35,12 +37,11 @@ export const defaultResultContent: ResultContent = {
messenger: "",
};
export function rawResultToResult(rawResult): RawResult {
export function rawResultToResult(rawResult: RawResultItem) {
let content = defaultResultContent;
try {
content = JSON.parse(rawResult.content);
console.log("Content", content);
} catch (error) {
console.warn(
"Cannot parse result from string, using default config",

@ -0,0 +1,71 @@
import { FC } from "react";
import { Box, Typography } from "@mui/material";
import { DateDefinition, TimeDefinition } from "./helper";
import { CardAnswer } from "./CardAnswer";
import { Result } from "@root/results/store";
interface AnswerListProps {
isTablet: boolean;
results: Result[] | [];
setPrePaymentModalOpen: (value: boolean) => void;
}
export const AnswerList: FC<AnswerListProps> = ({
isTablet,
results,
setPrePaymentModalOpen,
}) => {
return (
<>
{!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 &&
results.map((result) => {
const dayResult = DateDefinition(result.created_at);
const timeResult = TimeDefinition(result.created_at);
return (
<CardAnswer
key={result.id}
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}
openPrePaymentModal={() => setPrePaymentModalOpen(true)}
/>
);
})}
</Box>
</>
);
};

@ -1,25 +1,20 @@
import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon";
import {
Box,
Button,
IconButton,
Link,
Modal,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { FC, useState } from "react";
import { FC, MouseEvent, useState } from "react";
import { ContactIcon } from "./icons/ContactIcon";
import { MessageIcon } from "./icons/MessageIcon";
import { PhoneIcon } from "./icons/PhoneIcon";
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, obsolescenceResult } from "@root/results/actions";
import { resultApi } from "@api/result";
import { IAnswerResult, resultApi } from "@api/result";
import { useQuizStore } from "@root/quizes/store";
import { useQuestionsStore } from "@root/questions/store";
import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
@ -27,21 +22,19 @@ import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
import type { AxiosError } from "axios";
import { DeleteModal } from "./DeleteModal";
interface Props {
interface CardAnswerProps {
isNew: boolean;
idResult: string;
onClick: () => void;
idResult: number;
dayResult: string;
timeResult: string;
name?: string;
phone?: string;
email?: string;
address?: string;
onLossNew?: (id: string) => void;
openPrePaymentModal: () => void;
}
export const CardAnswer = ({
export const CardAnswer: FC<CardAnswerProps> = ({
name,
phone,
email,
@ -50,35 +43,29 @@ export const CardAnswer = ({
idResult,
timeResult,
dayResult,
onLossNew,
openPrePaymentModal,
}: Props) => {
}) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const [openDelete, setOpenDelete] = useState<boolean>(false);
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const [resultsAnswer, setResultsAnswer] = useState([]);
const [resultQuiz, setResultQuiz] = useState([]);
const [resultsAnswer, setResultsAnswer] = useState<IAnswerResult[]>([]);
const [questionsResultState, setQuestionsResultState] = useState([]);
const { editQuizId } = useQuizStore();
const { questions } = useQuestionsStore();
const openResults = async () => {
setIsOpen(!isOpen);
if (!isOpen) {
try {
let resAnswer = await resultApi.getAnswerList(Number(idResult));
let resAnswerOnly = resAnswer.filter((res) => res.Result !== true);
let resQuiz = resAnswer.filter((res) => res.Result === true);
setResultQuiz(resQuiz);
const resAnswer = await resultApi.getAnswerList(idResult);
const resAnswerOnly = resAnswer.filter((res) => res.Result !== true);
const resQuiz = resAnswer.filter((res) => res.Result === true);
setResultsAnswer(resAnswerOnly);
let idResults = resQuiz[0].question_id;
let questionsResult = questions.filter(
const idResults = resQuiz[0].question_id;
const questionsResult = questions.filter(
(q) => q.backendId === idResults,
);
setQuestionsResultState(questionsResult);
console.log("тут хранятся ответы", resAnswerOnly);
} catch (nativeError) {
const error = nativeError as AxiosError;
@ -89,11 +76,19 @@ export const CardAnswer = ({
}
};
const onClickDelete = (e: MouseEvent) => {
e.stopPropagation();
setOpenDelete(true);
};
return (
<>
<Box
onClick={() => {
if (editQuizId !== null) {
obsolescenceResult(idResult, editQuizId);
openResults();
}
}}
sx={{
borderRadius: "12px",
@ -182,7 +177,9 @@ export const CardAnswer = ({
<Box sx={{ display: "flex", flexDirection: "column", gap: "10px" }}>
{name && (
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
<Box
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
>
<ContactIcon />
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>
{name}
@ -190,7 +187,9 @@ export const CardAnswer = ({
</Box>
)}
{email && (
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
<Box
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
>
<MessageIcon />
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>
{email}
@ -198,7 +197,9 @@ export const CardAnswer = ({
</Box>
)}
{phone && (
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
<Box
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
>
<PhoneIcon />
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>
{phone}
@ -206,7 +207,9 @@ export const CardAnswer = ({
</Box>
)}
{address && (
<Box sx={{ display: "flex", alignItems: "center", gap: "13px" }}>
<Box
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
>
<AddressIcon color={"#9A9AAF"} />
<Typography sx={{ fontSize: "18px", color: "#4D4D4D" }}>
{address}
@ -263,24 +266,16 @@ export const CardAnswer = ({
Новая
</Typography>
<Box sx={{ display: "flex", alignItems: "center" }}>
<IconButton onClick={() => setOpenDelete(true)}>
<IconButton onClick={onClickDelete}>
<DeleteIcon color="#4D4D4D" fontSize="34px" />
</IconButton>
</Box>
</>
) : (
<IconButton onClick={() => setOpenDelete(true)}>
<IconButton onClick={onClickDelete}>
<DeleteIcon color="#4D4D4D" fontSize="34px" />
</IconButton>
)}
<DeleteModal
openDelete={openDelete}
handleClose={() => setOpenDelete(false)}
onClick={() => {
deleteResult(Number(idResult));
setOpenDelete(false);
}}
/>
</Box>
</Box>
@ -339,7 +334,12 @@ export const CardAnswer = ({
}
return (
<Box
sx={{ display: "flex", alignItems: "center", gap: "13px" }}
key={answer.id}
sx={{
display: "flex",
alignItems: "center",
gap: "13px",
}}
>
<Typography sx={{ fontSize: "18px", color: "#9A9AAF" }}>
{id + 1}. {titleQuestion}.
@ -414,9 +414,9 @@ export const CardAnswer = ({
</Typography>
</Box>
{questionsResultState.map((res) => {
console.log(questionsResultState, "что за результат тут");
return (
<Box
key={res.id}
sx={{
display: "flex",
flexDirection: "column",
@ -433,7 +433,9 @@ export const CardAnswer = ({
>
{res.description}
</Typography>
<Typography sx={{ fontSize: "18px", wordBreak: "break-word" }}>
<Typography
sx={{ fontSize: "18px", wordBreak: "break-word" }}
>
{res.title}
</Typography>
{res.content.useImage &&
@ -459,5 +461,14 @@ export const CardAnswer = ({
</Box>
)}
</Box>
<DeleteModal
openDelete={openDelete}
handleClose={() => setOpenDelete(false)}
onClick={() => {
deleteResult(Number(idResult));
setOpenDelete(false);
}}
/>
</>
);
};

@ -1,37 +1,22 @@
import {
Box,
Typography,
useTheme,
useMediaQuery,
Skeleton,
} from "@mui/material";
import { Box, Skeleton, useMediaQuery, useTheme } from "@mui/material";
import HeaderFull from "@ui_kit/Header/HeaderFull";
import SectionWrapper from "@ui_kit/SectionWrapper";
import { FC, useEffect, useState } from "react";
import { CardAnswer } from "./CardAnswer";
import { ChangeEvent, FC, useEffect, useState } from "react";
import { PrePaymentModal } from "./PrePaymentModal";
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
import { resultApi } from "@api/result";
import { useResultStore } from "@root/results/store";
import { ExportResults, setResults } from "@root/results/actions";
import { quizApi } from "@api/quiz";
import { setQuizes } from "@root/quizes/actions";
import { setResults } from "@root/results/actions";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { useQuizStore } from "@root/quizes/store";
import { questionApi } from "@api/question";
import { setQuestions } from "@root/questions/actions";
import { useUserStore } from "@root/user";
import CustomPagination from "@ui_kit/CustomPagination";
import SettingResults from "./SettingResults";
import { DateDefinition, parseFilters, TimeDefinition } from "./helper";
const itemsCities = [
{ label: "Муром (1)", value: "option1" },
{ label: "Москва (1)", value: "option2" },
];
import { parseFilters } from "./helper";
import { QuizSettingsMenu } from "./QuizSettingsMenu";
import { AnswerList } from "./AnswerList";
import { useGetData } from "./useGetData";
const itemsTime = [
"За всё время",
@ -50,8 +35,6 @@ export const QuizAnswersPage: FC = () => {
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>("За всё время");
const [prePaymentModalOpen, setPrePaymentModalOpen] =
@ -68,14 +51,13 @@ export const QuizAnswersPage: FC = () => {
const quiz = useCurrentQuiz();
const { editQuizId } = useQuizStore();
const { results, total_count } = useResultStore();
const countPagination =
typeof total_count === "number" ? Math.ceil(total_count / 10) : 0;
useGetData(filterNew, filterDate);
console.log("Перерендер компонента ", results);
const countPagination = Math.ceil(total_count / 10);
// const {idResultArray, addIdResult, clearIdResultArray} = useObsolescenceIdResult()
useEffect(() => {
getData();
}, [filterNew, filterDate]);
return setResults([]);
}, []);
useEffect(() => {
if (!userAccount) {
@ -94,31 +76,20 @@ export const QuizAnswersPage: FC = () => {
setPrePaymentModalOpen(false);
}, [userAccount]);
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(filterNew, filterDate),
);
setResults(result);
}
};
const PaginationHC = async (e, value) => {
const PaginationHC = async (e: ChangeEvent<unknown>, value: number) => {
setPage(value);
try {
if (editQuizId !== null) {
const result = await resultApi.getList(
editQuizId,
value - 1,
parseFilters(filterNew, filterDate),
);
setResults(result);
}
} catch (error) {
console.error("An error occurred while receiving data: ", error);
}
};
if (quiz === undefined)
@ -133,137 +104,34 @@ export const QuizAnswersPage: FC = () => {
sx={{ padding: isMobile ? "115px 16px" : "115px 20px 20px" }}
maxWidth="lg"
>
<Typography
sx={{
fontSize: "36px",
fontWeight: "500",
mb: "50px",
lineHeight: "normal",
wordBreak: "break-word",
}}
>
{quiz.name}
</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})
</Typography>
</Box>
<Box
sx={{
mt: "20px",
mb: "31px",
gap: "30px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: isTablet ? "auto" : "100%",
}}
>
<SettingResults
onclickExport={() =>
ExportResults(
filterNew,
filterDate,
() => setPrePaymentModalOpen(true),
editQuizId,
)
}
onclickUpdate={async () => {
const result = await resultApi.getList(
editQuizId,
page - 1,
parseFilters(filterNew, filterDate),
);
setResults(result);
}}
onclickFilterTablet={() => setFilterModalOpen(true)}
onclickResetFilers={() => {
setFilterNew("Все заявки");
setFilterDate("За всё время");
}}
<QuizSettingsMenu
quiz={quiz}
total_count={total_count}
isTablet={isTablet}
filterNew={filterNew}
filterDate={filterDate}
setPrePaymentModalOpen={setPrePaymentModalOpen}
editQuizId={editQuizId}
page={page}
setFilterModalOpen={setFilterModalOpen}
setFilterNew={setFilterNew}
setFilterDate={setFilterDate}
filterNewHC={filterNewHC}
filterDateHC={filterDateHC}
itemsTime={itemsTime}
itemsNews={itemsNews}
filterDate={filterDate}
filterNew={filterNew}
/>
</Box>
</Box>
<CustomPagination
countPagination={countPagination}
page={page}
onChange={PaginationHC}
/>
{!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}
openPrePaymentModal={() => setPrePaymentModalOpen(true)}
<AnswerList
isTablet={isTablet}
results={results}
setPrePaymentModalOpen={setPrePaymentModalOpen}
/>
);
})}
</Box>
</SectionWrapper>
<FilterModal
open={filterModalOpen}
handleClose={() => setFilterModalOpen(false)}

@ -0,0 +1,127 @@
import SettingResults from "./SettingResults";
import { ExportResults, setResults } from "@root/results/actions";
import { resultApi } from "@api/result";
import { parseFilters } from "./helper";
import { Box, Typography } from "@mui/material";
import { FC } from "react";
import { Quiz } from "@model/quiz/quiz";
interface QuizSettingsMenuProps {
quiz: Quiz;
total_count: number;
isTablet: boolean;
filterNew: string;
filterDate: string;
setPrePaymentModalOpen: (value: boolean) => void;
editQuizId: number | null;
page: number;
setFilterModalOpen: (value: boolean) => void;
setFilterNew: (value: string) => void;
setFilterDate: (value: string) => void;
filterNewHC: (value: string) => void;
filterDateHC: (value: string) => void;
itemsTime: string[];
itemsNews: string[];
}
export const QuizSettingsMenu: FC<QuizSettingsMenuProps> = ({
quiz,
total_count,
isTablet,
filterNew,
filterDate,
setPrePaymentModalOpen,
editQuizId,
page,
setFilterModalOpen,
setFilterNew,
setFilterDate,
filterNewHC,
filterDateHC,
itemsTime,
itemsNews,
}) => {
return (
<>
<Typography
sx={{
fontSize: "36px",
fontWeight: "500",
mb: "50px",
lineHeight: "normal",
wordBreak: "break-word",
}}
>
{quiz.name}
</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})
</Typography>
</Box>
<Box
sx={{
mt: "20px",
mb: "31px",
gap: "30px",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: isTablet ? "auto" : "100%",
}}
>
<SettingResults
onclickExport={() => {
if (editQuizId !== null) {
ExportResults(
filterNew,
filterDate,
() => setPrePaymentModalOpen(true),
editQuizId,
);
} else {
console.error("editQuizId is null");
}
}}
onclickUpdate={async () => {
if (editQuizId !== null) {
const result = await resultApi.getList(
editQuizId,
page - 1,
parseFilters(filterNew, filterDate),
);
setResults(result);
} else {
console.error("editQuizId is null");
}
}}
onclickFilterTablet={() => setFilterModalOpen(true)}
onclickResetFilers={() => {
setFilterNew("Все заявки");
setFilterDate("За всё время");
}}
filterNewHC={filterNewHC}
filterDateHC={filterDateHC}
itemsTime={itemsTime}
itemsNews={itemsNews}
filterDate={filterDate}
filterNew={filterNew}
/>
</Box>
</Box>
</>
);
};

@ -37,7 +37,6 @@ export default function SettingResults({
}: Props) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(600));
return (
<>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>

@ -9,8 +9,6 @@ export const parseFilters = (filterNew: string, filterDate: string) => {
if (filterNew === "Новые") filters.new = true;
if (filterDate.length !== 0 && filterDate !== "За всё время") {
console.log(filterDate);
filters.to = new Date();
let resetedCurrentTime = Number(resetTime());

@ -1,16 +0,0 @@
export const EyeIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
viewBox="0 0 30 30"
fill="none"
>
<path
d="M3.26743 16.0459C2.91085 15.3939 2.91086 14.6059 3.26744 13.9539C5.53334 9.8107 9.93781 7 15 7C20.0622 7 24.4667 9.81079 26.7326 13.9541C27.0891 14.6061 27.0891 15.3941 26.7326 16.0461C24.4667 20.1893 20.0622 23 15 23C9.93782 23 5.53329 20.1892 3.26743 16.0459Z"
stroke="#4D4D4D"
strokeWidth="1.5"
/>
<circle cx="15" cy="15" r="4" stroke="#4D4D4D" strokeWidth="1.5" />
</svg>
);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

@ -0,0 +1,41 @@
import { useEffect } from "react";
import { useQuizStore } from "@root/quizes/store";
import { quizApi } from "@api/quiz";
import { setQuizes } from "@root/quizes/actions";
import { questionApi } from "@api/question";
import { setQuestions } from "@root/questions/actions";
import { resultApi } from "@api/result";
import { parseFilters } from "./helper";
import { setResults } from "@root/results/actions";
export const useGetData = (filterNew: string, filterDate: string): void => {
const { editQuizId } = useQuizStore();
useEffect(() => {
const getData = async (): Promise<void> => {
try {
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(filterNew, filterDate),
);
if (result.total_count === 0) {
console.log("No results found");
}
setResults(result);
}
} catch (error) {
console.error("An error occurred while receiving data: ", error);
}
};
getData();
}, [editQuizId, filterNew, filterDate, setResults]);
};

@ -5,7 +5,6 @@ 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";
import { AxiosError } from "axios";
import { parseFilters } from "../../pages/QuizAnswersPage/helper";
@ -13,7 +12,7 @@ const REQUEST_DEBOUNCE = 200;
const requestQueue = new RequestQueue();
let requestTimeoutId: ReturnType<typeof setTimeout>;
export const setResults = (results: RawResult[] | null) =>
export const setResults = (results: RawResult | []) =>
setProducedState(
(state) => {
state.results = Object.values(results)[1]?.map(rawResultToResult) ?? [];
@ -22,11 +21,10 @@ export const setResults = (results: RawResult[] | null) =>
{
type: "setResults",
results,
// total_count
},
);
const removeResult = (resultId: string) =>
const removeResult = (resultId: number) =>
setProducedState((state) => {
const index = state.results.findIndex((r) => r.id === resultId);
if (index === -1) return;
@ -53,9 +51,9 @@ export const deleteResult = async (resultId: number) =>
});
export const obsolescenceResult = async (
resultId: string,
resultId: number,
editQuizId: number,
) =>
) => {
requestQueue.enqueue(
`obsolescenceResult-${resultId}-${editQuizId}`,
async () => {
@ -65,7 +63,7 @@ export const obsolescenceResult = async (
if (!result) return;
if (result.new === false) return;
let lossDebouncer: null | ReturnType<typeof setTimeout> = null;
let lossId: string[] = [] as string[];
let lossId: number[] = [];
if (!lossId.includes(resultId)) lossId.push(resultId);
if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
lossDebouncer = setTimeout(async () => {
@ -85,12 +83,13 @@ export const obsolescenceResult = async (
setResults(resultList);
},
);
};
export const ExportResults = async (
filterNew: string,
filterDate: string,
openPrePaymentModal: () => void,
editQuizId: number | null,
editQuizId: number,
) => {
try {
const data = await resultApi.export(
@ -101,7 +100,7 @@ export const ExportResults = async (
const blob = data;
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.href = window.URL.createObjectURL(blob as Blob);
link.download = `report_${new Date().getTime()}.xlsx`;
link.click();
} catch (nativeError) {

@ -1,18 +1,17 @@
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
import { ResultContent } from "@model/result/result";
export type ResultStore = {
results: [
{
results: {
content: string;
results: Result[];
total_count: number;
};
export type Result = {
content: ResultContent;
id: number;
new: boolean;
created_at: string;
};
},
];
total_count: number;
};
const initialState: ResultStore = {
@ -40,7 +39,6 @@ export const useObsolescenceIdResult = create()(
idResultArray: [],
addIdResult: (idResult: number) => {
const state = get()["idResultArray"] || [];
console.log(state);
const newState = [...state, idResult];
set({ idResultArray: newState });
},

@ -1,9 +1,10 @@
import { Pagination } from "@mui/material";
import { ChangeEvent } from "react";
interface Props {
countPagination: number;
page: number;
onChange: (e: ChangeEvent, value: number) => void;
onChange: (e: ChangeEvent<unknown>, value: number) => void;
}
export default function CustomPagination({