Generateurv2/frontend/components/pdf_gen/selectExo.jsx

395 lines
13 KiB
React
Raw Normal View History

2022-06-24 13:42:16 +02:00
import { createRef, useEffect, useRef } from "react";
2022-05-18 10:15:54 +02:00
import { useState } from "react";
import { FiLink } from "react-icons/fi";
import useFilter from "../../hooks/useFilter.hook.jsx";
import styles from "../../styles/pdf_gen/selectExo.module.scss";
2022-06-24 13:42:16 +02:00
import { isBrowser, isEmpty, parseClassName } from "../../utils/utils.js";
2022-05-18 10:15:54 +02:00
import TagSelect from "../exos/TagSelect.jsx";
import Modal from "../Modal.jsx";
import Tag from "../Tag.jsx";
import ParamItem from "./ParamItem.jsx";
import TagContainer from "./tagContainer.jsx";
import { AiOutlineClose } from "react-icons/ai";
2022-06-24 13:42:16 +02:00
import { useInfiniteQuery, useQuery } from "react-query";
import {
getExos,
getPublicExos,
getTags,
getUserExos,
} from "../../requests/requests.exos.js";
import { useInView } from "react-intersection-observer";
import { useSessionContext } from "../../context/session.context.js";
2022-05-18 10:15:54 +02:00
export default function SelectExo({
exos,
setExos,
emptyError,
2022-06-24 13:42:16 +02:00
onlyNumber = false,
2022-05-18 10:15:54 +02:00
}) {
2022-06-24 13:42:16 +02:00
const { ref, inView } = useInView();
2022-05-18 10:15:54 +02:00
const [active, setActive] = useState(false);
2022-06-24 13:42:16 +02:00
const { data: tagsData } = useQuery(
["tags"],
async () => {
return await getTags();
},
{ enabled: active, staleTime: 60 * 1000 }
);
const [selectedOption, setSelectedOption] = useState([]);
const [selectFilter, setSelectFilter] = useState(
isBrowser && localStorage.getItem("token") != null ? "user" : "all"
);
2022-05-18 10:15:54 +02:00
const [search, setSearch] = useState("");
2022-06-24 13:42:16 +02:00
const {
isLoading,
isError,
data,
fetchNextPage,
hasNextPage,
isFetching,
isFetchingNextPage,
} = useInfiniteQuery(
["userExo-data", { search, tags: selectedOption.map((t) => t.value) }],
({ pageParam = 0 }) => {
return getUserExos("pdf", pageParam == 0 ? 1 : pageParam, {
search,
tags: selectedOption.map((t) => t.value),
}).then((res) => {
return {
...res,
results: [
...res.results.map((r) => {
return { ...r, numberInExo: 10, numberOfExo: 1 };
}),
],
};
});
},
{
enabled: (active && selectFilter == "user") /* || exos.length != 0 */,
staleTime: 60 * 1000,
refetchOnWindowFocus: false,
keepPreviousData: true,
getPreviousPageParam: (firstPage) =>
firstPage.links.previous ? firstPage.page_number - 1 : undefined,
getNextPageParam: (lastPage) =>
lastPage.links.next ? lastPage.page_number + 1 : undefined,
}
);
const {
isLoading: publicLoading,
isError: publicError,
data: publicData,
fetchNextPage: publicFetchNextPage,
hasNextPage: publicHasNextPage,
isFetching: publicFetching,
isFetchingNextPage: publicIsFetchingNextPage,
} = useInfiniteQuery(
["publicExo-data", { search, tags: selectedOption.map((t) => t.value) }],
({ pageParam = 0 }) => {
return getPublicExos("pdf", pageParam == 0 ? 1 : pageParam, {
search,
tags: selectedOption.map((t) => t.value),
}).then((res) => {
return {
...res,
results: [
...res.results.map((r) => {
return { ...r, numberInExo: 10, numberOfExo: 1 };
}),
],
};
});
},
{
enabled: (active && selectFilter == "all") /* || exos.length != 0 */,
staleTime: 60 * 1000,
refetchOnWindowFocus: false,
keepPreviousData: true,
getPreviousPageParam: (firstPage) =>
firstPage.links.previous ? firstPage.page_number - 1 : undefined,
getNextPageParam: (lastPage) =>
lastPage.links.next ? lastPage.page_number + 1 : undefined,
}
);
useEffect(() => {
if (inView) {
selectFilter == "user" ? fetchNextPage() : publicFetchNextPage();
}
}, [inView]);
2022-05-18 10:15:54 +02:00
2022-06-24 13:42:16 +02:00
const {authData} = useSessionContext()
2022-05-18 10:15:54 +02:00
return (
<>
<div className={styles["exo-select"]}>
<div className={styles["head"]}>
<p>Ajouter exercices</p>
<p className={styles.add} onClick={() => setActive(true)}>
+
</p>
</div>
<div className={styles["exos-selected"]}>
2022-06-24 13:42:16 +02:00
{exos.length === 0 && (
2022-05-18 10:15:54 +02:00
<>
<p
className={parseClassName([
styles["no-select"],
emptyError ? styles["error-empty"] : undefined,
])}
>
Aucun exercice selectionné
</p>
{emptyError == true && (
<p className={parseClassName(["error-msg", styles.error])}>
Veuillez selectionner un exercice au minimum
</p>
)}
</>
)}
2022-06-24 13:42:16 +02:00
{exos.map((s, i) => {
return (
<ParamItem
exo={{
name: s.name,
...exos.filter((ex) => ex.id_code == s.id_code)[0],
}}
unSelect={() => {
setExos((o) => [
...o.filter((ex) => {
return ex.id_code != s.id_code;
}),
]);
}}
setExo={(nbIn, nbOf) => {
setExos((o) => [
...o.map((ex) => {
if (ex.id_code == s.id_code) {
return {
...ex,
numberInExo: nbIn,
numberOfExo: nbOf,
};
}
return ex;
}),
]);
}}
key={i}
onlyNumber={onlyNumber}
/>
);
})}
{/* {[
...(data || { pages: [] }).pages,
...(publicData || { pages: [] }).pages,
]
.map((p) => p.results)
.flat()
2022-05-18 10:15:54 +02:00
.filter((e) => {
2022-06-24 13:42:16 +02:00
return exos.map((ex) => ex.id_code).includes(e.id_code);
2022-05-18 10:15:54 +02:00
})
.sort((a, b) => {
2022-06-24 13:42:16 +02:00
return (
exos.map((ex) => ex.id_code).indexOf(a.id_code) -
exos.map((ex) => ex.id_code).indexOf(b.id_code)
);
2022-05-18 10:15:54 +02:00
})
.map((s, i) => {
return (
<ParamItem
2022-06-24 13:42:16 +02:00
exo={{
name: s.name,
...exos.filter((ex) => ex.id_code == s.id_code)[0],
}}
2022-05-18 10:15:54 +02:00
unSelect={() => {
2022-06-24 13:42:16 +02:00
setExos((o) => [
...o.filter((ex) => {
return ex.id_code != s.id_code;
2022-05-18 10:15:54 +02:00
}),
]);
}}
setExo={(nbIn, nbOf) => {
2022-06-24 13:42:16 +02:00
setExos((o) => [
...o.map((ex) => {
if (ex.id_code == s.id_code) {
return {
...ex,
numberInExo: nbIn,
numberOfExo: nbOf,
};
}
return ex;
}),
2022-05-18 10:15:54 +02:00
]);
}}
key={i}
2022-06-24 13:42:16 +02:00
onlyNumber={onlyNumber}
2022-05-18 10:15:54 +02:00
/>
);
2022-06-24 13:42:16 +02:00
})} */}
2022-05-18 10:15:54 +02:00
</div>
</div>
<Modal active={active} onClose={() => setActive(false)}>
<div className={styles["modal-list-container"]}>
<div className={styles["search-container"]}>
<input
type="text"
className="exo-input"
placeholder="Rechercher..."
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
2022-06-24 13:42:16 +02:00
2022-05-18 10:15:54 +02:00
<div style={{ display: "flex" }}>
2022-06-24 13:42:16 +02:00
{tagsData && !isEmpty(authData) && (
<TagSelect
tags={tagsData}
onChange={setSelectedOption}
select={selectedOption}
/>
)}
{!isEmpty(authData) && (
<select
className={styles.select}
value={selectFilter}
onChange={(e) => {
setSelectFilter(e.target.value);
}}
>
<option value="all">Tous</option>
<option value="user">User</option>
</select>
)}
2022-05-18 10:15:54 +02:00
</div>
</div>
<div>
2022-06-24 13:42:16 +02:00
{selectFilter == "user" &&
data &&
data.pages.map((p) => p.results).flat().length == 0 && (
<p className={styles["no-select"]}>Aucun résultat</p>
)}
{selectFilter == "all" &&
publicData &&
publicData.pages.map((p) => p.results).flat().length == 0 && (
<p className={styles["no-select"]}>Aucun résultat</p>
)}
2022-05-18 10:15:54 +02:00
2022-06-24 13:42:16 +02:00
{selectFilter == "user" &&
data &&
data.pages.map((page) => {
return page.results.map((d, i) => {
return (
<div
key={i}
onClick={() => {
if (!exos.map((ex) => ex.id_code).includes(d.id_code)) {
setExos((o) => [
...o,
{
id_code: d.id_code,
numberInExo: d.numberInExo,
numberOfExo: d.numberOfExo,
name: d.name,
},
]);
} else {
setExos((o) => [
...o.filter((ex) => {
return ex.id_code != d.id_code;
}),
]);
}
}}
className={parseClassName([
exos.map((ex) => ex.id_code).includes(d.id_code)
? styles["selected"]
: undefined,
styles["item-in-modal"],
"pointer",
])}
>
<div className={styles["modal-name"]}>{d.name}</div>
{d.tags.length !== 0 && <TagContainer tags={d.tags} />}
</div>
);
});
})}
{selectFilter == "all" &&
publicData &&
publicData.pages.map((page) => {
return page.results.map((d, i) => {
return (
<div
key={i}
onClick={() => {
if (!exos.map((ex) => ex.id_code).includes(d.id_code)) {
setExos((o) => [
...o,
{
id_code: d.id_code,
numberInExo: d.numberInExo,
numberOfExo: d.numberOfExo,
name: d.name,
},
]);
} else {
setExos((o) => [
...o.filter((ex) => {
return ex.id_code != d.id_code;
}),
]);
}
}}
className={parseClassName([
exos.map((ex) => ex.id_code).includes(d.id_code)
? styles["selected"]
: undefined,
styles["item-in-modal"],
"pointer",
])}
>
<div className={styles["modal-name"]}>{d.name}</div>
{d.tags.length !== 0 && <TagContainer tags={d.tags} />}
</div>
);
});
})}
<span ref={ref}></span>
{isFetchingNextPage ||
(isFetching && (
<div className={styles["loader-container"]}>
<span className="loader"></span>
2022-05-18 10:15:54 +02:00
</div>
2022-06-24 13:42:16 +02:00
))}
{publicIsFetchingNextPage ||
(publicFetching && (
<div className={styles["loader-container"]}>
<span className="loader"></span>
</div>
))}
2022-05-18 10:15:54 +02:00
</div>
</div>
<div className={styles["icon-container"]}>
2022-06-24 13:42:16 +02:00
<AiOutlineClose
className={styles["icon"]}
onClick={() => {
setActive(false);
}}
/>
2022-05-18 10:15:54 +02:00
</div>
</Modal>
</>
);
}