Generateurv2/frontend/pages/exercices/[[...exo]].jsx

482 lines
14 KiB
React
Raw Normal View History

2022-05-18 10:15:54 +02:00
import axios from "axios";
import Layout from "../../components/Layout.js";
2022-06-11 23:39:03 +02:00
import { useState, useEffect, useCallback, useRef } from "react";
2022-05-18 10:15:54 +02:00
import { Card } from "../../components/exos/Card.jsx";
2022-06-11 23:39:03 +02:00
import {
getExos,
getPublicExos,
getTags,
getUserExos,
} from "../../requests/requests.exos.js";
import { useQuery, useQueryClient } from "react-query";
2022-05-18 10:15:54 +02:00
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";
2022-06-11 23:39:03 +02:00
import { isBrowser, parseClassName } from "../../utils/utils.js";
2022-05-18 10:15:54 +02:00
import useFilter from "../../hooks/useFilter.hook.jsx";
import { Pagination } from "../../components/exos/Pagination.jsx";
2022-06-24 13:42:16 +02:00
import { useSessionContext } from "../../context/session.context.js";
import { isEmpty } from "../../utils/utils.js";
import { notificationService } from "../../services/notification.service.js";
2022-05-18 10:15:54 +02:00
2022-06-11 23:39:03 +02:00
export default function ExercicesPage() {
2022-06-24 13:42:16 +02:00
const { authData } = useSessionContext();
2022-06-11 23:39:03 +02:00
const router = useRouter();
const { exo } = router.query;
const [page, setPage] = useState(1); //correspond à l'index
2022-06-24 13:42:16 +02:00
const [selectFilter, setSelectFilter] = useState(null);
const queryClient = useQueryClient();
2022-06-11 23:39:03 +02:00
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(
2022-06-24 13:42:16 +02:00
[
"public-data",
parseInt(page),
{ search, tags: selectedOption.map((t) => t.value) },
],
2022-06-11 23:39:03 +02:00
async () =>
await getPublicExos("all", page, {
search,
tags: selectedOption.map((t) => t.value),
}),
2022-05-18 10:15:54 +02:00
{
refetchOnWindowFocus: false,
2022-06-11 23:39:03 +02:00
enabled: selectFilter == "all",
staleTime: 60000,
2022-05-18 10:15:54 +02:00
keepPreviousData: true,
}
);
2022-06-11 23:39:03 +02:00
const {
isLoading: userLoading,
isError: userError,
data: userExosData,
isFetching: userFetching,
} = useQuery(
2022-06-24 13:42:16 +02:00
[
"user-data",
parseInt(page),
{ search, tags: selectedOption.map((t) => t.value) },
],
2022-06-11 23:39:03 +02:00
async () =>
await getUserExos("all", page, {
search,
tags: selectedOption.map((t) => t.value),
}),
{
refetchOnWindowFocus: false,
2022-06-24 13:42:16 +02:00
enabled: selectFilter == "user" && !isEmpty(authData),
2022-06-11 23:39:03 +02:00
staleTime: 60000,
keepPreviousData: true,
}
);
2022-05-18 10:15:54 +02:00
const { data: tagsData } = useQuery(
["tags"],
async () => {
return await getTags();
},
{
2022-06-24 13:42:16 +02:00
enabled: !isEmpty(authData),
2022-06-11 23:39:03 +02:00
initialData: [],
staleTime: 2 * 60 * 1000,
initialDataUpdatedAt: 10 * 1000 * 60,
2022-05-18 10:15:54 +02:00
}
);
const [activeData, setActiveData] = useState({
2022-06-11 23:39:03 +02:00
active: false,
2022-06-24 13:42:16 +02:00
data: null,
2022-05-18 10:15:54 +02:00
});
2022-06-11 23:39:03 +02:00
2022-05-18 10:15:54 +02:00
const [create, setCreate] = useState(false);
2022-06-11 23:39:03 +02:00
2022-06-24 13:42:16 +02:00
const isLoad = useRef(false);
useEffect(() => {
console.log(
"AUTH DATA",
authData,
isLoad,
isLoad.current || authData !== undefined
);
if (exo !== undefined && (/* isLoad.current || */authData !== undefined)) {
if (exo[0] == "public") {
setSelectFilter("all");
} else if (exo[0] == "user") {
if (!isEmpty(authData)) {
setSelectFilter("user");
} else {
router.push({ pathname: "/exercices/public", query: { page: 1 } });
}
} else {
if (selectFilter === null) {
setSelectFilter(!isEmpty(authData) ? "user" : "public");
}
getExos(exo[0])
.then((res) => {
setActiveData({ active: true, data: { ...res } });
})
.catch(() => {
router.push({
pathname:
"/exercices/" + (!isEmpty(authData) ? "user" : "public"),
query: { page: 1 },
});
notificationService.error("Erreur", "Exercice introuvable", {
keepAfterRouteChange: true,
});
});
}
} else if (exo === undefined && (/* isLoad.current || */ authData !== undefined)) {
if (selectFilter === null) {
router.push({
pathname: "/exercices/" + (!isEmpty(authData) ? "user" : "public"),
query: { page: 1 },
});
}
}
if (!isLoad.current) {
isLoad.current = true;
}
return () => {
setActiveData({ active: false, data: null });
};
}, [router.asPath, authData, isLoad, selectFilter]);
2022-05-18 10:15:54 +02:00
useEffect(() => {
2022-06-11 23:39:03 +02:00
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 }
);
}
}
2022-06-24 13:42:16 +02:00
}, [router.asPath, publicData, userExosData, selectFilter]);
2022-05-18 10:15:54 +02:00
2022-06-11 23:39:03 +02:00
const [deleted, setDeleted] = useState([]);
2022-05-18 10:15:54 +02:00
2022-06-11 23:39:03 +02:00
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);
}
};
2022-05-18 10:15:54 +02:00
return (
<Layout page="Tous les exercices">
2022-06-24 13:42:16 +02:00
<div className={parseClassName([styles["all_exos--full_container"]])}>
2022-06-11 23:39:03 +02:00
{isLoading ||
isFetching ||
2022-06-24 13:42:16 +02:00
userLoading ||
(userFetching && (
2022-06-11 23:39:03 +02:00
<p
style={{
textAlign: "center",
position: "absolute",
width: "100%",
}}
>
<span className="loader"></span>
</p>
))}
2022-06-24 13:42:16 +02:00
2022-05-18 10:15:54 +02:00
<div className={styles["all_exos--head"]}>
<div className={styles["new-container"]}>
2022-06-24 13:42:16 +02:00
{!isEmpty(authData) && (
<button
onClick={() => {
setCreate(true);
}}
>
Nouveau +
</button>
)}
2022-05-18 10:15:54 +02:00
</div>
2022-06-24 13:42:16 +02:00
2022-05-18 10:15:54 +02:00
<div className={styles["search-full-container"]}>
<input
placeholder="Rechercher..."
type="text"
className="exo-input"
2022-06-11 23:39:03 +02:00
value={tmpSearch}
2022-05-18 10:15:54 +02:00
onChange={(e) => {
2022-06-11 23:39:03 +02:00
setTmpSearch(e.target.value);
setPage(1);
2022-05-18 10:15:54 +02:00
}}
/>
2022-06-24 13:42:16 +02:00
<div style={{ display: "flex", width: '100%' }}>
{!isEmpty(authData) && (
<TagSelect
tags={tagsData ? tagsData: []}
onChange={(e) => {
setSelectedOption(e);
setPage(1);
}}
select={selectedOption}
/>
)}
2022-05-18 10:15:54 +02:00
</div>
2022-06-24 13:42:16 +02:00
{!isEmpty(authData) && (
2022-06-11 23:39:03 +02:00
<select
onChange={(e) => {
router.push(
{
pathname:
"/exercices/" +
(e.target.value == "user" ? "user" : "public"),
query: { page: 1 },
},
undefined,
{ shallow: true }
);
setSelectFilter(e.target.value);
setPage(1);
}}
value={selectFilter}
2022-06-24 13:42:16 +02:00
className={styles.select}
2022-06-11 23:39:03 +02:00
>
2022-06-24 13:42:16 +02:00
<option value="user">Vos exercices</option>
<option value="all">Tous les exercices</option>
2022-06-11 23:39:03 +02:00
</select>
)}
2022-05-18 10:15:54 +02:00
</div>
</div>
<div className={styles["all_exos--container"]}>
<div className={styles["all_exos--title"]}>
2022-06-11 23:39:03 +02:00
{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>
)}
2022-05-18 10:15:54 +02:00
</div>
2022-06-11 23:39:03 +02:00
{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}
/>
);
})}
{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>}
2022-05-18 10:15:54 +02:00
</div>
2022-06-11 23:39:03 +02:00
{selectFilter == "all" && publicData && publicData.pages != 1 && (
<Pagination setPage={setPage} page={page} pages={publicData.pages} />
)}
{selectFilter == "user" && userExosData && userExosData.pages != 1 && (
2022-05-18 10:15:54 +02:00
<Pagination
setPage={setPage}
2022-06-11 23:39:03 +02:00
page={page}
pages={userExosData.pages}
2022-05-18 10:15:54 +02:00
/>
)}
2022-06-24 13:42:16 +02:00
</div>
2022-06-11 23:39:03 +02:00
<Modal active={activeData.active || create} onClose={onClose}>
2022-05-18 10:15:54 +02:00
{activeData.data != null && create == false && (
<ModalCard
2022-06-11 23:39:03 +02:00
queryKey={[
2022-06-24 13:42:16 +02:00
selectFilter == "all" ? "public-data" : "user-data",
2022-06-11 23:39:03 +02:00
parseInt(page),
{
search,
tags: selectedOption.map((e) => e.value),
},
]}
2022-05-18 10:15:54 +02:00
step={activeData.data}
setActive={setActiveData}
modal={true}
2022-06-11 23:39:03 +02:00
onClose={onClose}
2022-05-18 10:15:54 +02:00
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);
}}
2022-06-24 13:42:16 +02:00
resetFilter={() => {
setSelectedOption([])
setSearch('')
}}
2022-06-11 23:39:03 +02:00
addExo={(newExo) => {
setUserExosData((s) => [...s, newExo]);
}}
2022-05-18 10:15:54 +02:00
/>
)}
</Modal>
</Layout>
);
}
2022-06-11 23:39:03 +02:00
/* export async function getStaticProps() {
2022-05-18 10:15:54 +02:00
const exos = await getExos();
const tags = await getTags();
return {
props: {
exos: exos,
tags: tags,
},
revalidate: 60,
};
2022-06-11 23:39:03 +02:00
} */
2022-05-18 10:15:54 +02:00
2022-06-11 23:39:03 +02:00
/* export const getStaticPaths = async () => {
2022-05-18 10:15:54 +02:00
return {
paths: [], //indicates that no page needs be created at build time
fallback: "blocking", //indicates the type of fallback
};
2022-06-11 23:39:03 +02:00
}; */