Generateurv2/frontend/components/room/Parcours.jsx
2022-06-24 13:42:16 +02:00

233 lines
7.5 KiB
JavaScript

import { useRouter } from "next/router";
import { useEffect, useLayoutEffect, useRef, useState } from "react";
import { useQuery } from "react-query";
import {
challengeParcours,
getParcoursChallenge,
} from "../../requests/requests.room.js";
import { countOccurences, isEmpty, parseTimer } from "../../utils/utils.js";
import InputExo from "./InputExo.jsx";
import styles from "../../styles/room/parcours.module.scss";
import ParcoursExo from "./ParcoursExo.jsx";
import Layout from "../Layout.js";
import { notificationService } from "../../services/notification.service.js";
import { MdRefresh } from "react-icons/md";
export default function Parcours({ parcours_id, user, roomCode }) {
const router = useRouter();
const [exos, setExos] = useState([]);
const [isCorr, setCorr] = useState({ isCorr: false, DOM: false }); //DOM pour useEffect 2 fois sinon les data-x apparaissent pas bien :(
const [timer, setTimer] = useState(data && data.timer * 60);
const [correctId, setCorrectId] = useState();
const [data, setData] = useState();
useEffect(() => {
if (!data || isEmpty(data)) {
getParcoursChallenge(parcours_id, user.code).then((res) => {
setData(res);
setTimer(res.timer * 60);
setCorrectId(res.correctId);
});
}
return () => {};
}, [data]);
const ref = useRef();
useEffect(() => {
if (data && timer > 0 && !isCorr.isCorr) {
const time = setTimeout(() => {
setTimer(timer - 1);
}, 1000);
return () => clearTimeout(time);
} else if (data && timer <= 0) {
ref.current.click();
}
}, [timer]);
const formRef = useRef();
const first = useRef(true);
const [note, setNote] = useState({ value: null, total: null, isTrust: true });
useLayoutEffect(() => {
if (first.current) {
first.current = false;
return;
}
if (isCorr.isCorr == true && isCorr.DOM == false) {
setCorr({ isCorr: true, DOM: true });
}
if (isCorr.isCorr == true && isCorr.DOM == true) {
var target = formRef.current;
const resultList = [];
for (var i = 0, element; (element = target[i++]); ) {
if (element.type == "text") {
resultList.push({
idInput: element.getAttribute("data-idinput"),
idExo: element.getAttribute("data-idexo"),
idCalcul: element.getAttribute("data-idcalcul"),
value: element.value,
});
}
}
var exosSend = data.exos.map((ex) => {
var inputsExos = resultList.filter((e) => e.idExo == ex.order);
return {
...ex,
exos: ex.exos.map((e) => {
return {
...e,
inputs: e.inputs.map((i) => {
return {
...i,
value: inputsExos.filter((inp) => {
return inp.idCalcul == e.order && inp.idInput == i.order;
})[0].value,
};
}),
};
}),
};
});
challengeParcours({
user_code: user.code,
exos: {
result: exosSend,
timer: data.timer * 60 - timer,
},
id_code: parcours_id,
correct_code: correctId,
})
.then((res) => {
setData({ ...data, exos: res.exos });
setNote(res.note);
})
.catch((err) => {
notificationService.error("Erreur", "Réessayez plus tart");
});
}
return () => {};
}, [isCorr]);
return (
<Layout
page={"Parcours" + (data && data.name && ` - ${data.name}`)}
>
<div>
{data && (
<>
<div className={styles["head"]}>
<h1>
{data.name}
<MdRefresh
onClick={() => {
setData();
setCorr({ isCorr: false, DOM: false });
setNote({ value: null, total: null, isTrust: true });
}}
/>
</h1>{" "}
{note.value !== null && note.total !== null && (
<p
className={
note.isTrust
? (note.value * 20) / note.total >= data.success_condition
? styles["success"]
: styles["fail"]
: styles["notTrust"]
}
>
{note.value}/{note.total}
{note.total != 20 &&
` = ${
Math.round(((note.value * 20) / note.total) * 100) / 100
} / 20`}
{/* Round 2 decimals */}
{!note.isTrust && " (Note provisoire)"}
</p>
)}
<p className={timer < 60 ? styles["red"] : styles["green"]}>
{parseTimer(timer)}
</p>{" "}
</div>
<form
ref={formRef}
onSubmit={(e) => {
e.preventDefault();
setCorr({ isCorr: true, DOM: false });
}}
>
{data.exos &&
data.exos
.sort((a, b) => {
return a["order "] - b["order"];
})
.map((exo, i) => {
return (
<div className={styles["exo-full"]}>
<p>Exercice {exo.order + 1}</p>
<div className={styles["exos-container"]}>
{exo.exos
.sort((a, b) => {
return a.order - b.order;
})
.map((ex) => {
return (
<ParcoursExo
inputs={ex.inputs}
calcul={ex.calcul}
idExo={exo.order}
idCalcul={ex.order}
isCorr={isCorr.DOM}
/>
);
})}
</div>
</div>
);
})}
<div className={styles["btn-container"]}>
{!isCorr.isCorr && (
<button ref={ref} className="exo-btn">
Valider !
</button>
)}
{isCorr.isCorr && (
<button
ref={ref}
onClick={(e) => {
e.preventDefault();
setData();
setCorr({ isCorr: false, DOM: false });
setNote({ value: null, total: null, isTrust: true });
}}
className="exo-btn"
>
Réessayer !
</button>
)}
<button
onClick={(e) => {
e.preventDefault();
router.push(
{
pathname: `/room/${roomCode}/${parcours_id}`,
query: { action: "view" },
},
undefined,
{ shallow: true }
);
}}
className="cancel-btn"
>
Quitter
</button>
</div>
</form>
</>
)}
</div>{" "}
</Layout>
);
}