переписаны запросы и способы извлечения информации (страница результатов)
This commit is contained in:
parent
868bcf02a8
commit
3de2c035c6
@ -1,38 +1,27 @@
|
||||
import { makeRequest } from "@frontend/kitui";
|
||||
import { DeleteQuizRequest, DeleteQuizResponse } from "@model/quiz/delete";
|
||||
|
||||
export const getResultsList = async (quizId, body?: any) => {
|
||||
try {
|
||||
const response = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/results/getResults/${quizId}`,
|
||||
method: "POST",
|
||||
body: { page: 0, limit: 10, ...body },
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.log("ощибка", e);
|
||||
}
|
||||
};
|
||||
async function getResultList(quizId, body?: any) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/results/getResults/${quizId}`,
|
||||
method: "POST",
|
||||
body: { page: 0, limit: 10, ...body },
|
||||
});
|
||||
}
|
||||
|
||||
export const deleteResult = async (resultId: number) => {
|
||||
try {
|
||||
const response = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/results/delete/${resultId}`,
|
||||
body: {},
|
||||
method: "DELETE",
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.log("ошибка", e);
|
||||
}
|
||||
};
|
||||
function deleteResult(resultId: number) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/results/delete/${resultId}`,
|
||||
body: {},
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
answers: idResultArray,
|
||||
},
|
||||
method: "PATCH",
|
||||
});
|
||||
@ -42,30 +31,28 @@ export const obsolescenceResult = async (idResultArray: string[]) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getAnswerResultList = async (resultId: number) => {
|
||||
try {
|
||||
const response = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/result/${resultId}`,
|
||||
method: "GET"
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.log("ошибка", e);
|
||||
}
|
||||
};
|
||||
function getAnswerResultList(resultId: number) {
|
||||
return makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + `/squiz/result/${resultId}`,
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
export const AnswerResultListEx = async (quizId: number) => {
|
||||
try {
|
||||
const response = await 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"),
|
||||
new: true}
|
||||
});
|
||||
return response;
|
||||
} catch (e) {
|
||||
console.log("ошибка", e);
|
||||
}
|
||||
function AnswerResultListEx(quizId: number) {
|
||||
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"),
|
||||
new: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export const resultApi = {
|
||||
getList: getResultList,
|
||||
delete: deleteResult,
|
||||
getAnswerList: getAnswerResultList,
|
||||
export: AnswerResultListEx,
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ export interface ResultContent {
|
||||
name?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
adress?: string;
|
||||
address?: string;
|
||||
telegram?: string;
|
||||
wechat?: string;
|
||||
viber?: string;
|
||||
@ -25,7 +25,7 @@ export const defaultResultContent: ResultContent = {
|
||||
name: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
adress: "",
|
||||
address: "",
|
||||
telegram: "",
|
||||
wechat: "",
|
||||
viber: "",
|
||||
|
@ -17,9 +17,9 @@ import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||
import homeImg from "./images/home.png";
|
||||
import videoFrame from "./images/videoFrame.png";
|
||||
import { EyeIcon } from "./icons/EyeIcon";
|
||||
import { DeleteModal } from "./DeleteModal";
|
||||
import {deleteResult, getAnswerResultList, obsolescenceResult} from "@api/result";
|
||||
import {useObsolescenceIdResult} from "@root/results/store";
|
||||
import { deleteResult } from "@root/results/actions";
|
||||
import { resultApi } from "@api/result";
|
||||
|
||||
interface Props {
|
||||
isNew: boolean;
|
||||
idResult: string;
|
||||
@ -29,7 +29,7 @@ interface Props {
|
||||
name?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
onLossNew: (id:string) => void
|
||||
onLossNew: (id: string) => void;
|
||||
}
|
||||
|
||||
export const CardAnswer = ({
|
||||
@ -40,18 +40,19 @@ export const CardAnswer = ({
|
||||
idResult,
|
||||
timeResult,
|
||||
dayResult,
|
||||
onLossNew
|
||||
onLossNew,
|
||||
}: 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([]);
|
||||
|
||||
return (
|
||||
return (
|
||||
<Box
|
||||
onClick={()=> {
|
||||
if (isNew) onLossNew(idResult)
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isNew) onLossNew(idResult);
|
||||
}}
|
||||
sx={{
|
||||
borderRadius: "12px",
|
||||
maxWidth: isTablet ? "450px" : "auto",
|
||||
@ -113,18 +114,25 @@ export const CardAnswer = ({
|
||||
>
|
||||
{idResult}
|
||||
</Box>
|
||||
<IconButton onClick={() => {
|
||||
<IconButton
|
||||
onClick={async () => {
|
||||
setIsOpen(!isOpen);
|
||||
getAnswerResultList(Number(idResult))
|
||||
}}>
|
||||
<ArrowDownIcon
|
||||
style={{
|
||||
transform: isOpen ? "rotate(180deg)" : "rotate(360deg)",
|
||||
}}
|
||||
fontSize="10px"
|
||||
/>
|
||||
if (isOpen) {
|
||||
let resAnswer = await resultApi.getAnswerList(
|
||||
Number(idResult),
|
||||
);
|
||||
setResultsAnswer(resAnswer);
|
||||
console.log("тут хранятся ответы", resultsAnswer);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArrowDownIcon
|
||||
style={{
|
||||
transform: isOpen ? "rotate(180deg)" : "rotate(360deg)",
|
||||
}}
|
||||
fontSize="10px"
|
||||
/>
|
||||
</IconButton>
|
||||
|
||||
</Box>
|
||||
|
||||
<Typography
|
||||
@ -261,7 +269,7 @@ export const CardAnswer = ({
|
||||
sx={{ minWidth: "150px" }}
|
||||
onClick={() => {
|
||||
deleteResult(Number(idResult));
|
||||
setOpenDelete(false)
|
||||
setOpenDelete(false);
|
||||
}}
|
||||
>
|
||||
Подтвердить
|
||||
|
@ -19,7 +19,12 @@ import { FilterIcon } from "./icons/FilterIcon";
|
||||
import { FilterModal } from "@ui_kit/Modal/FilterModal/FilterModal";
|
||||
import { ExportContactsModal } from "@ui_kit/Modal/ExportContactsModal";
|
||||
|
||||
import { AnswerResultListEx, getResultsList, obsolescenceResult } from "@api/result";
|
||||
import {
|
||||
AnswerResultListEx,
|
||||
getResultsList,
|
||||
obsolescenceResult,
|
||||
resultApi,
|
||||
} from "@api/result";
|
||||
import { useObsolescenceIdResult, useResultStore } from "@root/results/store";
|
||||
import { setResults } from "@root/results/actions";
|
||||
|
||||
@ -33,24 +38,22 @@ const options = [
|
||||
{ label: "Москва (1)", value: "option2" },
|
||||
];
|
||||
|
||||
let lossDebouncer: null | ReturnType<typeof setTimeout> = null
|
||||
let lossId: string[] = [] as string[]
|
||||
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 (!lossId.includes(id)) lossId.push(id);
|
||||
//Если таймер есть - сбрасываем
|
||||
if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
|
||||
//Назначем новый таймер
|
||||
lossDebouncer = setTimeout(async() => {
|
||||
lossDebouncer = setTimeout(async () => {
|
||||
//стреляем на лишение новизны
|
||||
await obsolescenceResult(lossId)
|
||||
await obsolescenceResult(lossId);
|
||||
//сбрасываем массив
|
||||
lossId = []
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
|
||||
lossId = [];
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
export const QuizAnswersPage: FC = () => {
|
||||
const theme = useTheme();
|
||||
@ -58,8 +61,9 @@ export const QuizAnswersPage: FC = () => {
|
||||
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 [exportContactsModalOpen, setExportContactsModalOpen] =
|
||||
useState<boolean>(false);
|
||||
const [filterNew, setFilterNew] = useState<string>("За всё время");
|
||||
|
||||
const quizList = useQuizStore();
|
||||
const quiz = useCurrentQuiz();
|
||||
@ -74,12 +78,8 @@ export const QuizAnswersPage: FC = () => {
|
||||
const quizes = await quizApi.getList();
|
||||
setQuizes(quizes);
|
||||
|
||||
const result = await getResultsList(editQuizId);
|
||||
console.log("Это данные с сервера", result);
|
||||
const result = await resultApi.getList(editQuizId);
|
||||
setResults(result);
|
||||
|
||||
const resAnswer = await AnswerResultListEx(editQuizId)
|
||||
console.log("щтветы респондентов на экспорт в юз эффекте", resAnswer)
|
||||
}
|
||||
};
|
||||
getData();
|
||||
@ -114,7 +114,7 @@ export const QuizAnswersPage: FC = () => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<HeaderFull isRequest={true}/>
|
||||
<HeaderFull isRequest={true} />
|
||||
<SectionWrapper
|
||||
sx={{ padding: isMobile ? "0 16px" : "20px" }}
|
||||
maxWidth="lg"
|
||||
@ -157,8 +157,8 @@ export const QuizAnswersPage: FC = () => {
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
//setExportContactsModalOpen(true)
|
||||
const resAnswer = AnswerResultListEx(quizList.editQuizId)
|
||||
console.log("ответы респондентов на экспорт по клику", resAnswer)
|
||||
// const resAnswer = AnswerResultListEx(quizList.editQuizId)
|
||||
// console.log("ответы респондентов на экспорт по клику", resAnswer)
|
||||
}}
|
||||
sx={{
|
||||
width: "44px",
|
||||
@ -176,8 +176,10 @@ export const QuizAnswersPage: FC = () => {
|
||||
borderRadius: "8px",
|
||||
border: "1px solid #7E2AEA",
|
||||
}}
|
||||
onClick={() => {
|
||||
getResultsList(quizList.editQuizId);
|
||||
onClick={async () => {
|
||||
const result = await resultApi.getList(editQuizId);
|
||||
console.log(result);
|
||||
setResults(result);
|
||||
}}
|
||||
>
|
||||
<UpdateIcon />
|
||||
|
@ -34,7 +34,7 @@ export default function MyQuizzesFull({
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeaderFull isRequest={false}/>
|
||||
<HeaderFull isRequest={false} />
|
||||
{quizes.length === 0 ? (
|
||||
<FirstQuiz />
|
||||
) : (
|
||||
|
@ -1,6 +1,14 @@
|
||||
import { produce } from "immer";
|
||||
import { ResultStore, useResultStore } from "@root/results/store";
|
||||
import { RawResult, rawResultToResult } from "@model/result/result";
|
||||
import { RequestQueue } from "@utils/requestQueue";
|
||||
import { resultApi } from "@api/result";
|
||||
import { devlog, getMessageFromFetchError } from "@frontend/kitui";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
const REQUEST_DEBOUNCE = 200;
|
||||
const requestQueue = new RequestQueue();
|
||||
let requestTimeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
export const setResults = (results: RawResult[] | null) =>
|
||||
setProducedState(
|
||||
@ -17,6 +25,32 @@ export const setResults = (results: RawResult[] | null) =>
|
||||
},
|
||||
);
|
||||
|
||||
const removeResult = (resultId: string) =>
|
||||
setProducedState((state) => {
|
||||
const index = state.results.findIndex((r) => r.id === resultId);
|
||||
if (index === -1) return;
|
||||
|
||||
state.results.splice(index, 1);
|
||||
});
|
||||
|
||||
export const deleteResult = async (resultId: number) =>
|
||||
requestQueue.enqueue(async () => {
|
||||
const result = useResultStore
|
||||
.getState()
|
||||
.results.find((r) => r.id === resultId);
|
||||
if (!result) return;
|
||||
|
||||
try {
|
||||
await resultApi.delete(Number(result.id));
|
||||
removeResult(resultId);
|
||||
} catch (error) {
|
||||
devlog("Error delete result", error);
|
||||
|
||||
const message = getMessageFromFetchError(error) ?? "";
|
||||
enqueueSnackbar(`Не удалось удалить результат. ${message}`);
|
||||
}
|
||||
});
|
||||
|
||||
function setProducedState<A extends string | { type: unknown }>(
|
||||
recipe: (state: ResultStore) => void,
|
||||
action?: A,
|
||||
|
@ -2,13 +2,13 @@ import useSWR from "swr";
|
||||
import { isAxiosError } from "axios";
|
||||
import { devlog } from "@frontend/kitui";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { getResultsList } from "@api/result";
|
||||
import { resultApi } from "@api/result";
|
||||
import { useResultStore } from "@root/results/store";
|
||||
|
||||
export function useResults(quizId: string) {
|
||||
const { isLoading, error, isValidating } = useSWR(
|
||||
"results",
|
||||
() => getResultsList(quizId),
|
||||
() => resultApi.getList(quizId),
|
||||
{
|
||||
// onSuccess: setResults,
|
||||
onError: (error: unknown) => {
|
||||
@ -25,3 +25,10 @@ export function useResults(quizId: string) {
|
||||
|
||||
return { results, isLoading, error, isValidating };
|
||||
}
|
||||
|
||||
// export function useAnswerList() {
|
||||
// const { isLoading, error, isValidating } = useSWR(
|
||||
// "answers",
|
||||
// () => resultApi.getAnswerList()
|
||||
// )
|
||||
// }
|
||||
|
@ -34,36 +34,25 @@ export const useResultStore = create<ResultStore>()(
|
||||
);
|
||||
|
||||
//сохранение id результата в массив для отправки на сервер и снятия пометки new с карточки
|
||||
export const useObsolescenceIdResult = create()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
idResultArray: [],
|
||||
addIdResult: (idResult:number) => {
|
||||
const state = get()["idResultArray"] || [];
|
||||
console.log(state)
|
||||
const newState = [
|
||||
...state,
|
||||
idResult
|
||||
];
|
||||
set({idResultArray: newState})
|
||||
},
|
||||
clearIdResultArray: () => {
|
||||
const state = get()["idResultArray"] || {};
|
||||
export const useObsolescenceIdResult = create()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
idResultArray: [],
|
||||
addIdResult: (idResult: number) => {
|
||||
const state = get()["idResultArray"] || [];
|
||||
console.log(state);
|
||||
const newState = [...state, idResult];
|
||||
set({ idResultArray: newState });
|
||||
},
|
||||
clearIdResultArray: () => {
|
||||
const state = get()["idResultArray"] || {};
|
||||
|
||||
const newState = []
|
||||
set({idResultArray:newState});
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "idResultArr",
|
||||
}
|
||||
)
|
||||
const newState = [];
|
||||
set({ idResultArray: newState });
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "idResultArr",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ import { LogoutButton } from "@ui_kit/LogoutButton";
|
||||
import { ToTariffsButton } from "@ui_kit/Toolbars/ToTariffsButton";
|
||||
import ArrowLeft from "@icons/questionsPage/arrowLeft";
|
||||
|
||||
export default function HeaderFull({isRequest}: boolean) {
|
||||
export default function HeaderFull({ isRequest }: boolean) {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
@ -58,11 +58,11 @@ export default function HeaderFull({isRequest}: boolean) {
|
||||
<Link to="/">
|
||||
<Logotip width={124} />
|
||||
</Link>
|
||||
{isRequest &&
|
||||
(<IconButton onClick={() => navigate("/list")}>
|
||||
<ArrowLeft color="black" />
|
||||
</IconButton>)
|
||||
}
|
||||
{isRequest && (
|
||||
<IconButton onClick={() => navigate("/list")}>
|
||||
<ArrowLeft color="black" />
|
||||
</IconButton>
|
||||
)}
|
||||
<Box sx={{ display: "flex", ml: "auto" }}>
|
||||
<ToTariffsButton />
|
||||
<LogoutButton
|
||||
|
Loading…
Reference in New Issue
Block a user