2022-05-18 10:15:54 +02:00
|
|
|
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";
|
2022-06-24 13:42:16 +02:00
|
|
|
import { countOccurences, isEmpty, parseTimer } from "../../utils/utils.js";
|
|
|
|
import InputExo from "./InputExo.jsx";
|
2022-05-18 10:15:54 +02:00
|
|
|
import styles from "../../styles/room/parcours.module.scss";
|
|
|
|
import ParcoursExo from "./ParcoursExo.jsx";
|
2022-06-11 23:39:03 +02:00
|
|
|
import Layout from "../Layout.js";
|
2022-06-24 13:42:16 +02:00
|
|
|
import { notificationService } from "../../services/notification.service.js";
|
|
|
|
import { MdRefresh } from "react-icons/md";
|
2022-05-18 10:15:54 +02:00
|
|
|
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);
|
2022-06-24 13:42:16 +02:00
|
|
|
const [correctId, setCorrectId] = useState();
|
2022-05-18 10:15:54 +02:00
|
|
|
const [data, setData] = useState();
|
|
|
|
useEffect(() => {
|
2022-06-24 13:42:16 +02:00
|
|
|
if (!data || isEmpty(data)) {
|
|
|
|
getParcoursChallenge(parcours_id, user.code).then((res) => {
|
|
|
|
setData(res);
|
|
|
|
setTimer(res.timer * 60);
|
|
|
|
setCorrectId(res.correctId);
|
|
|
|
});
|
2022-05-18 10:15:54 +02:00
|
|
|
}
|
2022-06-24 13:42:16 +02:00
|
|
|
return () => {};
|
|
|
|
}, [data]);
|
|
|
|
|
2022-05-18 10:15:54 +02:00
|
|
|
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) {
|
2022-06-24 13:42:16 +02:00
|
|
|
|
2022-05-18 10:15:54 +02:00
|
|
|
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 {
|
2022-06-24 13:42:16 +02:00
|
|
|
...e,
|
|
|
|
inputs: e.inputs.map((i) => {
|
|
|
|
return {
|
|
|
|
...i,
|
|
|
|
value: inputsExos.filter((inp) => {
|
|
|
|
return inp.idCalcul == e.order && inp.idInput == i.order;
|
|
|
|
})[0].value,
|
|
|
|
};
|
|
|
|
}),
|
|
|
|
};
|
2022-05-18 10:15:54 +02:00
|
|
|
}),
|
|
|
|
};
|
|
|
|
});
|
2022-06-24 13:42:16 +02:00
|
|
|
|
|
|
|
|
2022-05-18 10:15:54 +02:00
|
|
|
challengeParcours({
|
|
|
|
user_code: user.code,
|
|
|
|
exos: {
|
|
|
|
result: exosSend,
|
|
|
|
timer: data.timer * 60 - timer,
|
|
|
|
},
|
|
|
|
id_code: parcours_id,
|
2022-06-24 13:42:16 +02:00
|
|
|
correct_code: correctId,
|
|
|
|
})
|
|
|
|
.then((res) => {
|
|
|
|
setData({ ...data, exos: res.exos });
|
|
|
|
setNote(res.note);
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
|
|
|
notificationService.error("Erreur", "Réessayez plus tart");
|
|
|
|
});
|
2022-05-18 10:15:54 +02:00
|
|
|
}
|
|
|
|
return () => {};
|
|
|
|
}, [isCorr]);
|
|
|
|
return (
|
2022-06-24 13:42:16 +02:00
|
|
|
<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}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
})}
|
2022-05-18 10:15:54 +02:00
|
|
|
</div>
|
2022-06-24 13:42:16 +02:00
|
|
|
</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>
|
2022-05-18 10:15:54 +02:00
|
|
|
);
|
|
|
|
}
|