Generateurv2/frontend/components/exos/ExoCreateForm.jsx

191 lines
5.8 KiB
JavaScript

import axios from "axios";
import { useEffect, useState } from "react";
import { useMutation, useQueryClient } from "react-query";
import { createExo } from "../../requests/requests.exos.js";
import { notificationService } from "../../services/notification.service.js";
import styles from "../../styles/exos/ExoCreateForm.module.scss";
import { CODE_SEPARATOR, PYTHON_DEFAULT } from "../../utils/constant.js";
import { csrftoken, isEmpty, parseClassName } from "../../utils/utils.js";
import Input from "../Input.jsx";
import ModelInput from "./modelInput.jsx";
export default function ExoCreateForm({ cancel, resetFilter }) {
const [newExo, setNewExo] = useState({
name: "",
consigne: "",
exo_model: { data: PYTHON_DEFAULT, filename: null, download: false },
private: false
});
const [errors, setErrors] = useState({
name: null,
consigne: null,
exo_model: null,
});
const queryClient = useQueryClient()
const { mutate, isLoading, data } = useMutation(
() => {
var data_sent = new FormData();
var blob = new Blob([newExo.exo_model.data], {
type: "text/x-python",
});
var file = new File([blob], newExo.exo_model.filename ? newExo.exo_model.filename: 'main.py', {
type: "text/x-python",
});
data_sent.append("file", file);
data_sent.append("name", newExo.name);
data_sent.append("consigne", newExo.consigne);
data_sent.append("private", newExo.private);
return createExo(data_sent);
},
{
onSuccess: (data) => {
//queryClient.invalidateQueries("exo-data");
resetFilter()
queryClient.invalidateQueries('user-data')
notificationService.success(
"Nouvel exercice",
`Exercice ${newExo.name} crée !`,
{ autoClose: true, keepAfterRouteChange: true }
);
cancel();
},
onError: (err) => {
var resetErrors = {
name: null,
exo_model: null,
consigne: null,
};
var newError = { ...resetErrors, ...err.response.data.errors };
setErrors({ ...newError });
notificationService.error(
"Erreur",
"L'exercice n'a pu être crée ! Réessayez plus tard !",
{ autoClose: true, keepAfterRouteChange: true }
);
},
}
);
const [full, setFull] = useState({ state: false, fade: false });
const fadeFull = (state) => {
setFull({ state: !state, fade: state });
setTimeout(() => {
setFull({ state: state, fade: false });
}, 300);
};
return (
<div className={styles["ex_card--full"]}>
<div
className={parseClassName([
styles["ex_card--body"],
"marginb-p0",
full.fade ? styles["ex_card-fade"] : undefined,
full.fade || full.state ? styles["ex_card--big"] : undefined,
full.state ? "vh-100" : undefined,
full.state == false ? styles["ex_card--body__little"] : undefined,
])}
>
{full.state == false && (
<>
<div className={styles["ex_card--title"]}>Nouvel exercice</div>
<Input
error={errors.name !== null}
type="text"
placeholder="Nom du l'exercice"
value={newExo.name}
onChange={(e) => {
//setErrors({ ...errors, name: null });
setNewExo({
...newExo,
name: e.target.value,
});
}}
/>
{errors.name !== null &&
errors.name.map((err, i) => {
return (
<p className="error-msg margint-p0" key={i}>
{err}
</p>
);
})}
<Input
type="text"
error={errors.consigne !== null}
value={newExo.consigne}
onChange={(e) => {
//setErrors({...errors, consigne: null})
setNewExo({
...newExo,
consigne: e.target.value,
});
}}
placeholder="Consigne"
/>
{errors.consigne !== null &&
errors.consigne.map((err, i) => {
return (
<p className="error-msg margint-p0" key={i}>
{err}
</p>
);
})}
<div>
<label>Private</label>
<input
type="checkbox"
checked={newExo.private}
onChange={(e) => {
setNewExo({ ...newExo, private: !newExo.private });
}}
/>
</div>
</>
)}
<ModelInput
setFull={fadeFull}
full={full.state}
model={newExo.exo_model}
setModel={(n) => {
setNewExo({ ...newExo, exo_model: n });
}}
step={{
...newExo,
name: newExo.name == "" ? "Nouveau" : newExo.name,
}}
onChange={(new_model) => {
setNewExo({ ...newExo, exo_model: new_model });
}}
tempSpec={newExo}
/>
{errors.exo_model !== null &&
errors.exo_model.map((err, i) => {
return (
<p className="error-msg margint-p0" key={i}>
{err}
</p>
);
})}
{full.state == false && (
<div className={styles["btn-container"]}>
<button className="exo-btn" onClick={mutate}>
Valider !
</button>
<button onClick={cancel} className="cancel-btn">
Annuler
</button>
</div>
)}
</div>
</div>
);
}