Generateurv2/frontend/pages/exercices/[[...exo]].jsx
Kilton937342 035af2a3b7 modifs
2022-06-11 23:39:03 +02:00

554 lines
16 KiB
JavaScript

import axios from "axios";
import Layout from "../../components/Layout.js";
import { useState, useEffect, useCallback, useRef } from "react";
import { Card } from "../../components/exos/Card.jsx";
import {
getExos,
getPublicExos,
getTags,
getUserExos,
} from "../../requests/requests.exos.js";
import { useQuery, useQueryClient } from "react-query";
import styles from "../../styles/exos/ExercicesPage.module.scss";
import Modal from "../../components/Modal.jsx";
import ModalCard from "../../components/exos/ModalCard.jsx";
import { useRouter } from "next/router";
import ExoCreateForm from "../../components/exos/ExoCreateForm.jsx";
import TagSelect from "../../components/exos/TagSelect.jsx";
import { FiLink } from "react-icons/fi";
import { isBrowser, parseClassName } from "../../utils/utils.js";
import useFilter from "../../hooks/useFilter.hook.jsx";
import { Pagination } from "../../components/exos/Pagination.jsx";
export default function ExercicesPage() {
const isAuth = isBrowser ? localStorage.getItem("token") != null : false;
const router = useRouter();
const { exo } = router.query;
const [page, setPage] = useState(1); //correspond à l'index
const [paginationData, setPagination] = useState({
publicPages: null,
userExosPages: null,
});
const [publicDataS, setPublicData] = useState([]);
const [userExosDataS, setUserExosData] = useState([]);
const [selectFilter, setSelectFilter] = useState(
null
/* router.query.exo == "user"
? "user"
: router.query.exo == "public"
? "all"
: !isAuth
? "user"
: "all" */
);
const queryClient = useQueryClient()
const [search, setSearch] = useState("");
const [tmpSearch, setTmpSearch] = useState("");
useEffect(() => {
const timeOutId = setTimeout(() => setSearch(tmpSearch), 500);
return () => {
clearInterval(timeOutId);
};
}, [tmpSearch]);
const [selectedOption, setSelectedOption] = useState([]);
const {
isLoading,
isError,
data: publicData,
isFetching,
} = useQuery(
["public-data", parseInt(page), { search, tags: selectedOption.map((t) => t.value) }],
async () =>
await getPublicExos("all", page, {
search,
tags: selectedOption.map((t) => t.value),
}),
{
refetchOnWindowFocus: false,
enabled: selectFilter == "all",
staleTime: 60000,
keepPreviousData: true,
}
);
const {
isLoading: userLoading,
isError: userError,
data: userExosData,
isFetching: userFetching,
} = useQuery(
["user-data", parseInt(page), { search, tags: selectedOption.map((t) => t.value) }],
async () =>
await getUserExos("all", page, {
search,
tags: selectedOption.map((t) => t.value),
}),
{
refetchOnWindowFocus: false,
enabled: selectFilter == "user",
staleTime: 60000,
keepPreviousData: true,
}
);
const { data: tagsData } = useQuery(
["tags"],
async () => {
return await getTags();
},
{
initialData: [],
staleTime: 2 * 60 * 1000,
initialDataUpdatedAt: 10 * 1000 * 60,
}
);
const [activeData, setActiveData] = useState({
active: false,
data: null /*
exo == undefined || !publicData
? null
: [...publicData.publicList, ...publicData.userExos].filter(
(e) => e.id_code == exo
)[0], */,
});
const [sortMode, setSortMode] = useState(false); // false == au moins 1 / true = tous
const [create, setCreate] = useState(false);
useEffect(() => {
if (publicData && router.query.page && selectFilter == "all") {
if (publicData.pages && parseInt(router.query.page) <= publicData.pages) {
setPage(parseInt(router.query.page));
} else if (
publicData.pages &&
parseInt(router.query.page) > publicData.pages
) {
var exo = router.query.exo || [];
router.push(
{
pathname: "/exercices/" + exo.join("/"),
query: { page: publicData.pages },
},
undefined,
{ shallow: true }
);
} else if (parseInt(router.query.page) == 0) {
var exo = router.query.exo || [];
router.push(
{
pathname: "/exercices/" + exo.join("/"),
query: { page: 1 },
},
undefined,
{ shallow: true }
);
}
}
if (userExosData && router.query.page && selectFilter == "user") {
if (
userExosData.pages &&
parseInt(router.query.page) <= userExosData.pages
) {
setPage(parseInt(router.query.page));
} else if (
userExosData.pages &&
parseInt(router.query.page) > userExosData.pages
) {
var exo = router.query.exo || [];
router.push(
{
pathname: "/exercices/" + exo.join("/"),
query: { page: userExosData.pages },
},
undefined,
{ shallow: true }
);
}
}
}, [router.query.page, publicData, userExosData]);
const isLoad = useRef(false)
useEffect(() => {
if (exo !== undefined) {
if (exo[0] == "public") {
setSelectFilter("all");
} else if (exo[0] == "user") {
if (isAuth) {
setSelectFilter("user");
} else {
router.push({ pathname: "/exercices/public", query: { page: 1 } });
}
} else {
if (selectFilter === null) {
setSelectFilter(isAuth ? "user" : "public");
}
getExos(exo[0]).then((res) => {
setActiveData({ active: true, data: { ...res } });
});
}
} else if (exo === undefined && isLoad) {
router.push({
pathname: "/exercices/" + (isAuth ? "user" : "public"),
query: { page: 1 },
});
}/*
if (isLoad) {
setActiveData({
active: exo != undefined,
data:
exo == undefined
? null
: [...publicDataS, ...userExosData].filter(
(e) => e.id_code == exo
)[0],
});
} */
isLoad.current = true
return () => {
setActiveData({ active: false, data: null });
};
}, [exo]);
const inPage = 22;
const filterData = (dataToFilter) => {
return dataToFilter
.filter((s) => {
if (!sortMode) {
return selectedOption.length != 0
? s.tags
.map((t) => t.id_code)
.some((r) => selectedOption.map((tt) => tt.value).includes(r))
: s;
} else {
return selectedOption
.map((opt) => opt.value)
.every((r) => s.tags.map((tt) => tt.id_code).includes(r));
}
})
.filter((s) => {
return search
.toLowerCase()
.sansAccent()
.split(" ")
.every((n) => s.name.toLowerCase().sansAccent().includes(n));
});
};
const [deleted, setDeleted] = useState([]);
useEffect(() => {
if (publicDataS.length != 0) {
setPublicData([
...publicDataS.sort(function (a, b) {
if (a.tags.length == 0 || b.tags.length == 0) {
return 1;
}
return (
tagsData.map((t) => t.id_code).indexOf(a.tags[0].id_code) -
tagsData.map((t) => t.id_code).indexOf(b.tags[0].id_code)
);
}),
]);
}
return () => {
setPublicData([]);
};
}, [publicDataS.length]);
const onClose = () => {
if (activeData.active == true) {
setActiveData({ active: false, data: { ...activeData.data } });
queryClient.invalidateQueries(
selectFilter == "all" ? "public-data" : "user-data"
);
router.push(
{
pathname: "/exercices/" + (selectFilter == "all" ? "public" : "user"),
query: { page: page },
},
undefined,
{ shallow: true }
);
setTimeout(() => {
setActiveData({ active: false, data: null });
}, 300); // le temps de la transition
} else if (create == true) {
setCreate(false);
}
};
return (
<Layout page="Tous les exercices">
<main
className={parseClassName([
styles["all_exos--full_container"],
"container",
])}
>
{isLoading ||
isFetching ||
((userLoading || userFetching) && (
<p
style={{
textAlign: "center",
position: "absolute",
width: "100%",
}}
>
<span className="loader"></span>
</p>
))}
<div className={styles["all_exos--head"]}>
<div className={styles["new-container"]}>
<button
onClick={() => {
setCreate(true);
}}
>
Nouveau +
</button>
</div>
<div className={styles["search-full-container"]}>
<input
placeholder="Rechercher..."
type="text"
className="exo-input"
value={tmpSearch}
onChange={(e) => {
setTmpSearch(e.target.value);
setPage(1);
}}
/>
<div style={{ display: "flex" }}>
<TagSelect
tags={tagsData}
onChange={(e) => {
console.log(
"EEEEEEEEEE",
e.map((ee) => ee.value)
);
setSelectedOption(e);
setPage(1);
}}
select={selectedOption}
/>
{/* <div
onClick={() => {
setSortMode(!sortMode);
}}
title={
sortMode == true
? "Doit avoir au moins tous les tags"
: "Doit avoir au moins un tag"
}
className={parseClassName([
styles["toggler-sort"],
sortMode
? styles["toggler-active"]
: styles["toggler-inactive"],
])}
>
<FiLink />
</div> */}
</div>
{isAuth && (
<select
onChange={(e) => {
console.log(
"lilian",
e.target.value,
"/exercices/" +
(e.target.value == "user" ? "user" : "public")
);
router.push(
{
pathname:
"/exercices/" +
(e.target.value == "user" ? "user" : "public"),
query: { page: 1 },
},
undefined,
{ shallow: true }
);
setSelectFilter(e.target.value);
setPage(1);
}}
value={selectFilter}
>
<option value="user">User</option>
<option value="all">Tous</option>
</select>
)}
</div>
</div>
<div className={styles["all_exos--container"]}>
<div className={styles["all_exos--title"]}>
{selectFilter == "all" && (
<h1>
Tous les <span className="primary">exercices</span>
</h1>
)}
{selectFilter == "user" && (
<h1>
Tous vos <span className="primary">exercices</span>
</h1>
)}
{selectFilter == "user" && (
<p>
Vous retrouverez ici tous les exercices que vous avez créé ou
copié depuis les exercices publics
</p>
)}
{selectFilter == "all" && (
<p>
Vous retrouverez ici tous les exercices crées par les autres
utilisateurs
</p>
)}
</div>
{selectFilter == "all" &&
publicData &&
publicData.results
//.sort((a, b) => a.id - b.id)
//.slice(page * inPage, (page + 1) * inPage)
.map((step) => {
return (
<Card
queryKey={[
"public-data",
parseInt(page),
{
search,
tags: selectedOption.map((e) => e.value),
},
]}
key={step.id}
step={step}
setActive={setActiveData}
deleted={deleted.includes(step.id_code)}
tags={tagsData}
setRegistered={(reg) => {
console.log("SETREFI", reg);
setPublicData((t) => [
...t.filter((p) => p.id_code != step.id_code),
{ ...step, isRegistered: reg },
]);
}}
/>
);
})}
{selectFilter == "user" &&
userExosData &&
userExosData.results.map((step) => {
return (
<Card
queryKey={[
"user-data",
parseInt(page),
{
search,
tags: selectedOption.map((e) => e.value),
},
]}
key={step.id}
step={step}
setActive={setActiveData}
deleted={deleted.includes(step.id_code)}
tags={tagsData}
setRegistered={(reg) => {}}
/>
);
})}
{publicData &&
publicData.results.length == 0 &&
selectFilter == "all" && <p>Aucun résultat</p>}
{userExosData &&
userExosData.results.length == 0 &&
selectFilter == "user" && <p>Aucun résultat</p>}
</div>
{selectFilter == "all" && publicData && publicData.pages != 1 && (
<Pagination setPage={setPage} page={page} pages={publicData.pages} />
)}
{selectFilter == "user" && userExosData && userExosData.pages != 1 && (
<Pagination
setPage={setPage}
page={page}
pages={userExosData.pages}
/>
)}
</main>
<Modal active={activeData.active || create} onClose={onClose}>
{activeData.data != null && create == false && (
<ModalCard
queryKey={[
selectFilter == 'all'? 'public-data': 'user-data',
parseInt(page),
{
search,
tags: selectedOption.map((e) => e.value),
},
]}
step={activeData.data}
setActive={setActiveData}
modal={true}
onClose={onClose}
onDelete={(id) => {
if (!deleted.includes(id)) {
setDeleted([...deleted, id]);
} else {
setDeleted([...deleted.filter((d) => d !== id)]);
}
}}
tags={tagsData}
/>
)}
{create == true && activeData.data == null && (
<ExoCreateForm
cancel={() => {
setCreate(false);
}}
addExo={(newExo) => {
setUserExosData((s) => [...s, newExo]);
}}
/>
)}
</Modal>
</Layout>
);
}
/* export async function getStaticProps() {
const exos = await getExos();
const tags = await getTags();
return {
props: {
exos: exos,
tags: tags,
},
revalidate: 60,
};
} */
/* export const getStaticPaths = async () => {
return {
paths: [], //indicates that no page needs be created at build time
fallback: "blocking", //indicates the type of fallback
};
}; */