MinervaFrontend/src/pages/NewForm.jsx
kuwsh1n 86854956eb
All checks were successful
publish-main / release-image (push) Successful in 6m32s
actions by users
2024-06-21 19:39:42 +03:00

339 lines
13 KiB
JavaScript

import React, { useState, useContext, useEffect } from "react";
import { useNavigate, useLocation, useParams } from 'react-router-dom';
import { useCookies } from "react-cookie";
import classes from "../assets/styles/newForm.module.scss";
import MyButton from "../components/MyButton.jsx";
import AnswerModal from "../components/AnswerModal.jsx";
import PreviewModal from "../components/PreviewModal.jsx";
import Loading from "../components/Loading.jsx";
import { FormsData, TypeAnswerData } from "../context";
import { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi, updateOrderBlockApi, removeBlockApi, getBlockApi } from "../hooks/api/formApi.js";
import { responseDataToListBlock, numberingBlocks } from "../hooks/sundry/parseListBlock.js";
import MyInput from "../components/MyInput.jsx";
const NewForm = () => {
const navigate = useNavigate();
const location = useLocation();
const { formId } = useParams();
const [dragElem, setDragElem] = useState(null);
const [dropElem, setDropElem] = useState(null);
const [loading, setLoading] = useState(false);
const [cookies, _, __] = useCookies(["user"]);
const {forms, setForms} = useContext(FormsData);
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
const nextID = (list, param) => {
return list.length ? list.at(-1)[param] + 1 : 1
};
const [question, setQuestion] = useState("");
const [comment, setComment] = useState("");
const [mandatory, setMandatory] = useState(false);
const [optionAnswer, setOptionAnswer] = useState([]);
const [file, setFile] = useState([]);
const [video, setVideo] = useState("");
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
const [datetime, setDatetime] = useState("");
const [newTitleForm, setNewTitleForm] = useState("");
const [oldTitleFrom, setOldTitleForm] = useState("");
const [listBlock, setListBlock] = useState([]);
const [stateModal, setStateModal] = useState(false);
function cleanStates() {
setStateModal(false)
setQuestion("");
setComment("");
setOptionAnswer([])
setFile([]);
setVideo("");
setCurrentTypeAnswer("");
setCurrentOptionAnswer("")
setMandatory(false);
};
useEffect(() => {
async function totalData() {
const responseForms = await listFormsApi(cookies.token);
const responseBlock = await listFormBlockApi(cookies.token, formId);
if (responseBlock.status === 200 && responseBlock.data && responseForms.status === 200) {
setListBlock(responseDataToListBlock(responseBlock.data));
const title = responseForms.data.find(item => item.id === formId).title
setNewTitleForm(title);
setOldTitleForm(title);
}
else {
setListBlock([])
setNewTitleForm("Новыя форма");
setOldTitleForm("Новыя форма");
}
setLoading(true);
};
totalData();
}, []);
function addOptionAnswer() {
setOptionAnswer(numberingBlocks(
[...optionAnswer, {
id: nextID(optionAnswer, "id"),
text: currentOptionAnswer
}],
"id",
1
));
setCurrentOptionAnswer("");
};
function removeOptionAnswer(id) {
setOptionAnswer(numberingBlocks(
[...optionAnswer].filter(answer => answer.id !== id),
"id",
1
));
};
function editAnswerByForm(id) {
const obj = listBlock.find(item => item.id === id);
setQuestion(obj.question);
setComment(obj.comment);
setFile(obj.file);
setVideo(obj.video);
setCurrentTypeAnswer(obj.typeAnswer);
setOptionAnswer(obj.optionAnswer);
setMandatory(obj.mandatory);
setStateModal(obj.id);
};
async function updateBlock() {
const data = {
question: question,
comment: comment,
file: file,
video: video,
mandatory: mandatory,
optionAnswer: optionAnswer,
typeAnswer: currentTypeAnswer,
}
const response = await updateBlockApi(
cookies.token,
formId,
data,
listBlock.find(item => item.id === stateModal).order
);
if (response.status === 200) {
const responseBlock = await listFormBlockApi(cookies.token, formId);
if (responseBlock.status === 200) {
setListBlock(responseDataToListBlock(responseBlock.data));
}
else {
setListBlock([])
}
}
else {
console.log(response)
}
cleanStates();
};
async function removeBlock(order) {
const response = await removeBlockApi(cookies.token, formId, order)
if (response.status === 200) {
setListBlock([...listBlock.filter(item => item.order !== order)]);
}
else {
console.log(response)
}
};
async function addFormBlock() {
console.log(optionAnswer)
const newBlock = {
question: question,
typeAnswer: currentTypeAnswer,
comment: comment,
mandatory: mandatory,
optionAnswer: optionAnswer,
file: file,
video: video
}
const response = await addFormBlockApi(cookies.token, formId, newBlock)
if (response.status === 200) {
const responseBlock = await listFormBlockApi(cookies.token, formId);
if (responseBlock.status === 200) {
setListBlock(responseDataToListBlock(responseBlock.data));
}
else {
setListBlock([])
}
}
else {
console.log(response)
}
cleanStates();
};
// async function updateTitleForm() {
// const response = await updateTitleFormApi(cookies.token, formId, newTitleForm);
// if (response.status === 200) {
// console.log(response)
// }
// else {
// console.log(response)
// }
// };
async function updateOrderBlock() {
const response = await updateOrderBlockApi(cookies.token, formId, {
new: dropElem,
old: dragElem
})
if (response.status === 200) {
const currentElem = listBlock[dragElem];
const tListBlock = [...listBlock];
if (dragElem > dropElem) {
tListBlock.splice(dropElem, 0, currentElem);
tListBlock.splice(dragElem + 1, 1);
}
else {
tListBlock.splice(dropElem + 1, 0, currentElem);
tListBlock.splice(dragElem, 1);
};
setListBlock(numberingBlocks(tListBlock, "order"));
}
};
async function saveForm() {
if (oldTitleFrom !== newTitleForm) {
await updateTitleFormApi(cookies.token, formId, newTitleForm);
}
cleanStates();
navigate("/forms");
};
return (
<div className={classes.main}>
<div className={classes.wrapper}>
<div className={classes.header}>
<div className={classes.header__listInput}>
<div className={classes.header__listInput__date}>
<span>Дедлайн выполнения</span>
<MyInput type={"datetime-local"} value={datetime} change={setDatetime}/>
</div>
<div className={classes.header__listInput__title}>
<span>Название формы</span>
<MyInput type={"text"} value={newTitleForm} change={setNewTitleForm}/>
</div>
</div>
<div className={classes.header__listBtn}>
<MyButton text={'Предпросмотр'} class={"main__white"} toggle={"modal"} target={"#previewModal"}/>
<MyButton text={'Опубликовать'} class={"main__green"} click={location.state ? updateFormByForms : saveForm}/>
</div>
</div>
<div className={classes.content}>
<div className={classes.content__listQuestion}>
<div className={classes.content__listQuestion__list}>
{listTypeAnswer.map((item, i) =>
<div className={classes.content__listQuestion__list__item} data-bs-toggle="modal" data-bs-target="#answerModal" onClick={() => setCurrentTypeAnswer(item.id)} key={i}>
<span>{item.text}</span>
</div>
)}
</div>
</div>
<PreviewModal listBlock={listBlock} listTypeAnswer={listTypeAnswer}/>
<AnswerModal
stateModal={stateModal}
currentTypeAnswer={currentTypeAnswer}
question={question}
comment={comment}
mandatory={mandatory}
optionAnswer={optionAnswer}
setOptionAnswer={setOptionAnswer}
file={file}
video={video}
setVideo={setVideo}
currentOptionAnswer={currentOptionAnswer}
listTypeAnswer={listTypeAnswer}
setQuestion={setQuestion}
setComment={setComment}
setFile={setFile}
setCurrentOptionAnswer={setCurrentOptionAnswer}
setMandatory={setMandatory}
cleanStates={cleanStates}
addFormBlock={addFormBlock}
addOptionAnswer={addOptionAnswer}
updateBlock={updateBlock}
setCurrentTypeAnswer={setCurrentTypeAnswer}
removeOptionAnswer={removeOptionAnswer}
/>
<div className={classes.content__newForm}>
<div className={classes.content__newForm__title}>
<h3>Новая форма</h3>
</div>
<div className={classes.content__newForm__list}>
{loading ? listBlock.map((item, i) =>
<div
className={classes.content__newForm__list__item}
key={i}
id={item.order}
draggable="true"
onDragOver={(event) => {event.preventDefault()}}
onDragStart={(event) => {
if (event.target.id) {
setDragElem(Number(event.target.id))
}
}}
onDragEnter={(event) => {
if (event.target.id) {
setDropElem(Number(event.target.id))
}
}}
onDrop={() => updateOrderBlock()}
>
<div className={classes.content__newForm__list__item__answer}>
<span>{item.question}</span>
<span>{listTypeAnswer.map(typeItem => {
if (typeItem.id === item.typeAnswer) {
return typeItem.text
}
})}</span>
</div>
<div className={classes.content__newForm__list__item__btn}>
<i class="fa-solid fa-pen" data-bs-toggle="modal" data-bs-target="#answerModal" onClick={() => {editAnswerByForm(item.id)}}></i>
<i class="fa-solid fa-trash" onClick={() => removeBlock(item.order)}></i>
</div>
</div>
) :
<Loading/>}
</div>
</div>
</div>
</div>
</div>
)
}
export default NewForm;