Generateurv2/frontend/components/exos/ExoEditForm.jsx
2022-05-18 10:15:54 +02:00

204 lines
6.4 KiB
JavaScript

import { useState } from "react";
import { useMutation, useQueryClient } from "react-query";
import { editExo } from "../../requests/requests.exos.js";
import { notificationService } from "../../services/notification.service.js";
import styles from "../../styles/exos/ExoEditForm.module.scss";
import { parseClassName } from "../../utils/utils.js";
import ModelInput from "./modelInput.jsx";
import { AlertType, useAlert } from "../../context/alert.context.js";
import { RiErrorWarningFill } from "react-icons/ri";
import { CODE_SEPARATOR } from "../../utils/constant.js";
export function ExoEditForm({ step, cancel, setFull, full }) {
const [spec, setSpec] = useState({
name: step.name,
consigne: step.consigne,
exo_model: step.exo_model,
});
const alert = useAlert();
const queryClient = useQueryClient();
const [errors, setErrors] = useState({
name: null,
exo_model: null,
consigne: null,
});
const { mutate, isLoading, data } = useMutation(
() => {
const dataToSend = new FormData()
var blob = new Blob([spec.exo_model.data], { type: "text/x-python" });
var file = new File([blob], spec.exo_model.filename != null ? spec.exo_model.filename: 'main.py', { type: "text/x-python" });
dataToSend.append("file", file);
dataToSend.append("name",spec.name);
dataToSend.append("consigne",spec.consigne);
dataToSend.append("id_code", step.id_code);
return editExo(dataToSend);
},
{
onSuccess: (data) => {
queryClient.invalidateQueries("exo-data");
notificationService.success(
"Modification !",
`L'exercice ${spec.name} a bien été modifié !`,
{ autoClose: true, keepAfterRouteChange: true }
);
cancel();
},
onError: (err) => {
console.log(err.response.data.errors, {
...errors,
...err.response.data.errors
});
var resetErrors = { name: null, exo_model: null, consigne: null };
var newError = { ...resetErrors, ...err.response.data.errors };
setErrors({...newError})
notificationService.error(
"Erreur",
"La modification n'a pu être enregistrée ! Réessayez plus tard !",
{ autoClose: true, keepAfterRouteChange: true }
);
},
}
);
return (
<>
{!full && (
<>
<span
className={parseClassName([
styles["input-container"],
styles["ex_card--title"],
"marginb-p0",
])}
>
<span>
<input
type="text"
className={parseClassName([
"exo-input",
styles["ex_card--title"],
styles.input,
errors.name !== null ? styles["exo-input-error"] : undefined,
])}
value={spec.name}
onChange={(e) => {
setSpec({ ...spec, name: e.target.value });
}}
placeholder="Nom..."
/>
{spec.name !== step.name && (
<RiErrorWarningFill className="red" />
)}{" "}
</span>
{errors.name !== null &&
errors.name.map((err, i) => {
return (
<p className="error-msg" key={i}>
{err}
</p>
);
})}
</span>
<span
className={[
parseClassName([styles["input-container"], "marginb-p0"]),
]}
>
<span>
<input
type="text"
className={parseClassName([
"exo-input",
styles.input,
errors.consigne !== null
? styles["exo-input-error"]
: undefined,
])}
style={{ gridColumn: "1/3" }}
value={spec.consigne}
onChange={(e) => {
setSpec({ ...spec, consigne: e.target.value });
}}
placeholder="Consigne..."
/>
{spec.consigne !== step.consigne && (
<RiErrorWarningFill className="red" />
)}{" "}
</span>
{errors.consigne !== null &&
errors.consigne.map((err, i) => {
return (
<p className="error-msg" key={i}>
{err}
</p>
);
})}
</span>
</>
)}
<div
style={{ /* gridColumn: "1/3" */ height: full && "100%" }}
className={!full ? styles["modelinput-container"] : undefined}
>
<ModelInput
model={spec.exo_model}
setModel={(n)=>{setSpec({...spec,exo_model: n})}}
setFull={setFull}
full={full}
step={step}
onChange={(new_model) => {
setSpec({ ...spec, exo_model: new_model});
}}
tempSpec={spec}
/>
{errors.exo_model !== null &&
errors.exo_model.map((err, i) => {
return (
<p className="error-msg margint-p0" key={i}>
{err}
</p>
);
})}
</div>
{!full && (
<div className={styles["btn-container"]}>
<button
className={parseClassName(["exo-btn", styles["btn"]])}
onClick={mutate}
>
{!isLoading ? (
"Valider !"
) : (
<div className={styles["loader-btn-container"]}>
<span className="loader"></span>
</div>
)}
</button>
<button
className={parseClassName(["cancel-btn", styles["btn"]])}
onClick={() => {
if (
spec.consigne != step.consigne ||
spec.name != step.name ||
step.exo_model != spec.exo_model
) {
alert.alert({
title: "Êtes-vous sûr ?",
active: true,
message: `Vous avez des modifications non enregistrée, voulez vous annuler ?`,
type: AlertType.Warning,
validate: cancel,
});
} else cancel();
}}
>
Annuler !
</button>
</div>
)}
</>
);
}