191 lines
5.8 KiB
JavaScript
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>
|
|
);
|
|
}
|