prod v1
This commit is contained in:
parent
6817f5bf9b
commit
33f27d2efc
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
FROM node:21-alpine
|
||||||
|
WORKDIR /frontend
|
||||||
|
COPY package.json .
|
||||||
|
RUN npm install
|
||||||
|
COPY . .
|
||||||
|
EXPOSE 3000
|
||||||
|
CMD ["npm", "run", "start:dev"]
|
@ -32,9 +32,11 @@
|
|||||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
|
"axios": "^1.6.8",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.10.1",
|
"react-bootstrap": "^2.10.1",
|
||||||
|
"react-cookie": "^7.1.4",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-router-dom": "^6.22.1"
|
"react-router-dom": "^6.22.1"
|
||||||
}
|
}
|
||||||
|
20
src/App.jsx
20
src/App.jsx
@ -1,7 +1,9 @@
|
|||||||
import React, { useState, useEffect, useLayoutEffect } from "react";
|
import React, { useState, useEffect, useLayoutEffect } from "react";
|
||||||
import { Outlet, useNavigate } from "react-router-dom";
|
import { Outlet, useNavigate } from "react-router-dom";
|
||||||
import { FormsData, UserData, TypeAnswerData } from "./context";
|
import { FormsData, UserData, TypeAnswerData } from "./context";
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
import { globalRender } from "./router/protectedRouting.js";
|
import { globalRender } from "./router/protectedRouting.js";
|
||||||
|
import { verifyUserApi } from "./hooks/api/enterAccountApi.js"
|
||||||
import classes from "./assets/styles/app.module.scss"
|
import classes from "./assets/styles/app.module.scss"
|
||||||
import NavBar from "./components/NavBar.jsx";
|
import NavBar from "./components/NavBar.jsx";
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
@ -30,6 +32,24 @@ const App = () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// useEffect(() => globalRender(window.location.pathname, user, navigate));
|
// useEffect(() => globalRender(window.location.pathname, user, navigate));
|
||||||
|
const [cookies, _, __] = useCookies(["user"]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function verifyUser() {
|
||||||
|
const response = await verifyUserApi(cookies.token);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
if (response.status === 200) {
|
||||||
|
setUser(response.data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyUser()
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserData.Provider value={{ user, setUser }}>
|
<UserData.Provider value={{ user, setUser }}>
|
||||||
|
@ -12,9 +12,38 @@
|
|||||||
.header {
|
.header {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 8%;
|
height: 8%;
|
||||||
|
&__date {
|
||||||
|
width: 30%;
|
||||||
|
height: 100%;
|
||||||
|
&__item {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
span {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 8px;
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
top: -40%;
|
||||||
|
left: 2%;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
border: 1px solid rgb(200, 200, 200);
|
||||||
|
padding: 1%;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
&__listBtn {
|
&__listBtn {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -5,9 +5,9 @@ import MyButton from "./MyButton.jsx"
|
|||||||
const AnswerModal = ({
|
const AnswerModal = ({
|
||||||
cleanStates,
|
cleanStates,
|
||||||
currentTypeAnswer,
|
currentTypeAnswer,
|
||||||
updateAnswerByForm,
|
updateBlock,
|
||||||
stateModal,
|
stateModal,
|
||||||
saveStates,
|
addFormBlock,
|
||||||
question,
|
question,
|
||||||
file,
|
file,
|
||||||
listTypeAnswer,
|
listTypeAnswer,
|
||||||
@ -16,17 +16,14 @@ const AnswerModal = ({
|
|||||||
currentOptionAnswer,
|
currentOptionAnswer,
|
||||||
setCurrentOptionAnswer,
|
setCurrentOptionAnswer,
|
||||||
comment,
|
comment,
|
||||||
datetime,
|
|
||||||
mandatory,
|
mandatory,
|
||||||
setMandatory,
|
setMandatory,
|
||||||
addOptionAnswer,
|
addOptionAnswer,
|
||||||
setQuestion,
|
setQuestion,
|
||||||
setComment,
|
setComment,
|
||||||
setDatetime,
|
|
||||||
setCurrentTypeAnswer,
|
setCurrentTypeAnswer,
|
||||||
setFile
|
setFile
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="modal fade myModal" className={classes.myModal} id="answerModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
<div class="modal fade myModal" className={classes.myModal} id="answerModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
||||||
@ -79,14 +76,10 @@ const AnswerModal = ({
|
|||||||
<span className={classes.myModal__dialog__content__body__mandatory__title}>Обязательный вопрос</span>
|
<span className={classes.myModal__dialog__content__body__mandatory__title}>Обязательный вопрос</span>
|
||||||
<input className={classes.myModal__dialog__content__body__mandatory__choice} type="checkbox" checked={mandatory} onChange={() => setMandatory(!mandatory)}/>
|
<input className={classes.myModal__dialog__content__body__mandatory__choice} type="checkbox" checked={mandatory} onChange={() => setMandatory(!mandatory)}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.myModal__dialog__content__body__time}>
|
|
||||||
<span>Дедлайн выполнения</span>
|
|
||||||
<input type="datetime-local" value={datetime} onChange={event => setDatetime(event.target.value)}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer myModal__dialog__content__footer" className={classes.myModal__dialog__content__footer}>
|
<div class="modal-footer myModal__dialog__content__footer" className={classes.myModal__dialog__content__footer}>
|
||||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal" onClick={cleanStates}>Отмена</button>
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal" onClick={cleanStates}>Отмена</button>
|
||||||
<button type="button" class="btn" style={{color: 'white', backgroundColor: 'rgb(150, 209, 158)'}} data-bs-dismiss="modal" onClick={stateModal ? updateAnswerByForm : saveStates}>Сохранить</button>
|
<button type="button" class="btn" style={{color: 'white', backgroundColor: 'rgb(150, 209, 158)'}} data-bs-dismiss="modal" onClick={stateModal ? updateBlock : addFormBlock}>Сохранить</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import classes from "../assets/styles/generatingFormFields.module.scss";
|
import classes from "../assets/styles/generatingFormFields.module.scss";
|
||||||
|
|
||||||
const GeneratingFormFields = ({newForm, listTypeAnswer, answers, updateAnswersForm}) => {
|
const GeneratingFormFields = ({listBlock, listTypeAnswer, answers, updateAnswersForm}) => {
|
||||||
return (
|
return (
|
||||||
newForm.map((item, i) =>
|
listBlock.map((item, i) =>
|
||||||
<div className={classes.item} key={i}>
|
<div className={classes.item} key={i}>
|
||||||
<div className={classes.item__question}>
|
<div className={classes.item__question}>
|
||||||
<p className={classes.item__question__text}>{i + 1}) {item.question}</p>
|
<p className={classes.item__question__text}>{i + 1}) {item.question}</p>
|
||||||
|
@ -16,7 +16,7 @@ const NavBar = ({navigate, auth, setAuth}) => {
|
|||||||
<div className={classes.profile}>
|
<div className={classes.profile}>
|
||||||
{auth ?
|
{auth ?
|
||||||
<div className={classes.profile__authorized}>
|
<div className={classes.profile__authorized}>
|
||||||
<span onClick={() => navigate("/profile")}>Профиль ({auth.name})</span>
|
<span onClick={() => navigate("/profile")}>Профиль ({auth.login})</span>
|
||||||
</div> :
|
</div> :
|
||||||
<div className={classes.profile__nonAuthorized}>
|
<div className={classes.profile__nonAuthorized}>
|
||||||
<span onClick={() => navigate("/enter")}>Вход <i class="fa-solid fa-arrow-right-to-bracket"></i></span>
|
<span onClick={() => navigate("/enter")}>Вход <i class="fa-solid fa-arrow-right-to-bracket"></i></span>
|
||||||
|
@ -2,7 +2,7 @@ import React from "react";
|
|||||||
import classes from "../assets/styles/components/previewModal.module.scss";
|
import classes from "../assets/styles/components/previewModal.module.scss";
|
||||||
import GeneratingFormFields from "./GeneratingFormFields.jsx";
|
import GeneratingFormFields from "./GeneratingFormFields.jsx";
|
||||||
|
|
||||||
const PreviewModal = ({newForm, listTypeAnswer}) => {
|
const PreviewModal = ({listBlock, listTypeAnswer}) => {
|
||||||
return (
|
return (
|
||||||
<div class="modal fade modal-lg" className={classes.myModal} id="previewModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
<div class="modal fade modal-lg" className={classes.myModal} id="previewModal" tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
|
||||||
<div class="modal-dialog" className={classes.myModal__dialog}>
|
<div class="modal-dialog" className={classes.myModal__dialog}>
|
||||||
@ -12,7 +12,7 @@ const PreviewModal = ({newForm, listTypeAnswer}) => {
|
|||||||
<i class="fa-solid fa-xmark" data-bs-dismiss="modal" aria-label="Close"></i>
|
<i class="fa-solid fa-xmark" data-bs-dismiss="modal" aria-label="Close"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" className={classes.myModal__dialog__content__body}>
|
<div class="modal-body" className={classes.myModal__dialog__content__body}>
|
||||||
<GeneratingFormFields newForm={newForm} listTypeAnswer={listTypeAnswer}/>
|
<GeneratingFormFields listBlock={listBlock} listTypeAnswer={listTypeAnswer}/>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer" className={classes.myModal__dialog__content__footer}>
|
<div class="modal-footer" className={classes.myModal__dialog__content__footer}>
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import React, { useState } from "react";
|
|||||||
import classes from "../../assets/styles/components/typeAnswer/dropDownList.module.scss"
|
import classes from "../../assets/styles/components/typeAnswer/dropDownList.module.scss"
|
||||||
|
|
||||||
const DropDownList = ({postfix, optionAnswer, answers, updateAnswersForm}) => {
|
const DropDownList = ({postfix, optionAnswer, answers, updateAnswersForm}) => {
|
||||||
|
console.log(optionAnswer)
|
||||||
return (
|
return (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
<select
|
<select
|
||||||
@ -9,6 +10,7 @@ const DropDownList = ({postfix, optionAnswer, answers, updateAnswersForm}) => {
|
|||||||
onChange={updateAnswersForm ? (e) => updateAnswersForm(Number(e.target.value), postfix) : () => {}}
|
onChange={updateAnswersForm ? (e) => updateAnswersForm(Number(e.target.value), postfix) : () => {}}
|
||||||
>
|
>
|
||||||
{optionAnswer.map((item, i) =>
|
{optionAnswer.map((item, i) =>
|
||||||
|
// <option value={item.id ? item.id : item[0].Value} key={i}>{item.text ? item.text : item[1].Value}</option>
|
||||||
<option value={item.id} key={i}>{item.text}</option>
|
<option value={item.id} key={i}>{item.text}</option>
|
||||||
)}
|
)}
|
||||||
</select>
|
</select>
|
||||||
|
@ -34,6 +34,7 @@ const InputMultipleRadio = ({postfix, optionAnswer, answers, updateAnswersForm})
|
|||||||
checked={answers ? checkRadio(i) : false}
|
checked={answers ? checkRadio(i) : false}
|
||||||
onChange={() => updateStateCheckbox(i)}
|
onChange={() => updateStateCheckbox(i)}
|
||||||
/>
|
/>
|
||||||
|
{/* <label class="form-check-label" for={`inputMultiple_${postfix}`}>{item.text ? item.text : item[1].Value}</label> */}
|
||||||
<label class="form-check-label" for={`inputMultiple_${postfix}`}>{item.text}</label>
|
<label class="form-check-label" for={`inputMultiple_${postfix}`}>{item.text}</label>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -11,10 +11,11 @@ const InputRadio = ({postfix, optionAnswer, answers, updateAnswersForm}) => {
|
|||||||
type="radio"
|
type="radio"
|
||||||
name={`inputRadio_${postfix}`}
|
name={`inputRadio_${postfix}`}
|
||||||
id={`choice_${item.id}`}
|
id={`choice_${item.id}`}
|
||||||
value={i}
|
value={i}
|
||||||
checked={answers ? answers[postfix].answer === i : false}
|
checked={answers ? answers[postfix].answer === i : false}
|
||||||
onChange={updateAnswersForm ? (e) => updateAnswersForm(Number(e.target.value), postfix) : () => {}}
|
onChange={updateAnswersForm ? (e) => updateAnswersForm(Number(e.target.value), postfix) : () => {}}
|
||||||
/>
|
/>
|
||||||
|
{/* <label class="form-check-label" for={`inputRadio_${postfix}`}>{item.text ? item.text : item[1].Value}</label> */}
|
||||||
<label class="form-check-label" for={`inputRadio_${postfix}`}>{item.text}</label>
|
<label class="form-check-label" for={`inputRadio_${postfix}`}>{item.text}</label>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,43 +1,46 @@
|
|||||||
import { totalRegisterValidate } from "../validation/enterAccountValidate.js";
|
import { totalRegisterValidate } from "../validation/enterAccountValidate.js";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
async function logIn(email, password) {
|
async function logIn(login, password) {
|
||||||
return new Promise((resolve, reject) => {
|
try {
|
||||||
setTimeout(() => {
|
const response = await axios.post("http://localhost:8080/auth/signIn", {"login": login, "password": password})
|
||||||
if (true) {
|
return response
|
||||||
resolve({
|
}
|
||||||
email: "senya.bogachev@mail.ru",
|
catch (e) {
|
||||||
phone: "89110128244",
|
return e
|
||||||
name: "Арсений",
|
}
|
||||||
surname: "Богачев",
|
|
||||||
patronymic: "Валерьевич"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reject("Error")
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
}).catch((error) => {
|
|
||||||
console.log(error)
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function completeRegistration(data) {
|
async function completeRegistration(data) {
|
||||||
const validate = totalRegisterValidate(data)
|
const validate = totalRegisterValidate(data);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
if (validate.status) {
|
||||||
setTimeout(() => {
|
try {
|
||||||
if (validate.status) {
|
const response = await axios.post("http://localhost:8080/auth/signUp", {"login": data.login, "password": data.password})
|
||||||
console.log("Отправляем данные на бэк ->", data)
|
return response
|
||||||
resolve({
|
}
|
||||||
status: 201,
|
catch (e) {
|
||||||
data: data
|
return e
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
else {
|
return validate.message
|
||||||
reject(validate.message)
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { logIn, completeRegistration };
|
async function verifyUserApi(token=false) {
|
||||||
|
if (token) {
|
||||||
|
try {
|
||||||
|
const response = await axios.get("http://localhost:8080/auth/me", {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export { logIn, completeRegistration, verifyUserApi };
|
@ -1,65 +1,87 @@
|
|||||||
function saveAnswersApi(id, answers) {
|
import axios from "axios";
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
async function listFormBlockApi(token, formId) {
|
||||||
if (true) {
|
try {
|
||||||
resolve({
|
const response = await axios.get(`http://localhost:8080/formBuilder/edit/${formId}/list`,
|
||||||
id: id,
|
{
|
||||||
answers: answers
|
headers: {
|
||||||
})
|
"Authorization": `Token ${token}`,
|
||||||
}
|
}
|
||||||
else {
|
})
|
||||||
reject("Error")
|
return response
|
||||||
}
|
}
|
||||||
}, 1000)
|
catch (e) {
|
||||||
})
|
return e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFormApi(id) {
|
async function addFormBlockApi(token, formId, data) {
|
||||||
return new Promise((resolve, reject) => {
|
try {
|
||||||
setTimeout(() => {
|
const response = await axios.post(`http://localhost:8080/formBuilder/edit/${formId}/add`,
|
||||||
if (true) {
|
{
|
||||||
resolve({
|
data: data
|
||||||
id: id
|
},
|
||||||
})
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
}
|
}
|
||||||
else {
|
})
|
||||||
reject("Error")
|
return response
|
||||||
}
|
}
|
||||||
}, 200)
|
catch (e) {
|
||||||
})
|
return e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// function removeFormApi(id) {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// if (true) {
|
||||||
|
// resolve({
|
||||||
|
// id: id
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// reject("Error")
|
||||||
|
// }
|
||||||
|
// }, 200)
|
||||||
|
// })
|
||||||
|
// };
|
||||||
|
|
||||||
|
async function updateBlockApi(token, blockId, data) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`http://localhost:8080/formBuilder/edit/${blockId}/set`,
|
||||||
|
{
|
||||||
|
data: data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFormByFormsApi(id, name, questions) {
|
async function saveFormApi(token) {
|
||||||
return new Promise((resolve, reject) => {
|
try {
|
||||||
setTimeout(() => {
|
const response = await axios.post("http://localhost:8080/formBuilder/new",
|
||||||
if (true) {
|
{
|
||||||
resolve({
|
title: "Новая форма"
|
||||||
id: id,
|
},
|
||||||
name: name,
|
{
|
||||||
questions: questions
|
headers: {
|
||||||
})
|
"Authorization": `Token ${token}`
|
||||||
}
|
}
|
||||||
else {
|
})
|
||||||
reject("Error")
|
return response
|
||||||
}
|
}
|
||||||
}, 1000)
|
catch (e) {
|
||||||
})
|
return e
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function saveFormApi(name, questions) {
|
export { addFormBlockApi, listFormBlockApi, saveFormApi, updateBlockApi }
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (true) {
|
|
||||||
resolve({
|
|
||||||
name: name,
|
|
||||||
questions: questions
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reject("Error")
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export { saveAnswersApi, saveFormApi, updateFormByFormsApi, removeFormApi }
|
|
50
src/hooks/api/listFormsApi.js
Normal file
50
src/hooks/api/listFormsApi.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
|
||||||
|
async function listFormsApi(token) {
|
||||||
|
try {
|
||||||
|
const response = await axios.get("http://localhost:8080/formBuilder/list", {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function createFormApi(token) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post("http://localhost:8080/formBuilder/new",
|
||||||
|
{
|
||||||
|
title: "Новая форма"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function removeFormApi(token, formId) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`http://localhost:8080/formBuilder/edit/${formId}/delete`, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Token ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export { listFormsApi, createFormApi, removeFormApi };
|
30
src/hooks/sundry/parseListBlock.js
Normal file
30
src/hooks/sundry/parseListBlock.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function responseDataToListBlock(data) {
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
for (let block of data) {
|
||||||
|
const newParam = {
|
||||||
|
id: block.id,
|
||||||
|
formId: block.form_id,
|
||||||
|
order: block.order
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let param of block.data) {
|
||||||
|
|
||||||
|
if (Array.isArray(param.Value) && param.Value.length) {
|
||||||
|
newParam[param.Key] = param.Value.map(item => ({
|
||||||
|
id: item[0].Value,
|
||||||
|
text: item[1].Value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newParam[param.Key] = param.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(newParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export { responseDataToListBlock }
|
@ -12,12 +12,12 @@ const constructorAnswerValidate = (state, messageReject = "Ошибка", messag
|
|||||||
|
|
||||||
const totalRegisterValidate = (data) => {
|
const totalRegisterValidate = (data) => {
|
||||||
const listValidation = [
|
const listValidation = [
|
||||||
constructorAnswerValidate(data.name.length, "Обязательное поле."),
|
constructorAnswerValidate(data.login.length, "Обязательное поле."),
|
||||||
constructorAnswerValidate(data.surname.length, "Обязательное поле."),
|
// constructorAnswerValidate(data.surname.length, "Обязательное поле."),
|
||||||
constructorAnswerValidate(data.email.length, "Обязательное поле."),
|
// constructorAnswerValidate(data.email.length, "Обязательное поле."),
|
||||||
constructorAnswerValidate(data.phone.length, "Обязательное поле."),
|
// constructorAnswerValidate(data.phone.length, "Обязательное поле."),
|
||||||
constructorAnswerValidate(data.password === data.repiedPassword, "Введенные пароли не совпадают."),
|
constructorAnswerValidate(data.password === data.repiedPassword, "Введенные пароли не совпадают."),
|
||||||
constructorAnswerValidate(data.password < 8, "Пароль должен иметь более 8 символов.")
|
constructorAnswerValidate(data.password >= 8, "Пароль должен иметь более 8 символов.")
|
||||||
]
|
]
|
||||||
|
|
||||||
for (let value of listValidation) {
|
for (let value of listValidation) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext } from "react";
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import classes from "../assets/styles/enterAccount.module.scss";
|
import classes from "../assets/styles/enterAccount.module.scss";
|
||||||
import MyInput from "../components/MyInput.jsx";
|
import MyInput from "../components/MyInput.jsx";
|
||||||
@ -12,18 +13,19 @@ const EnterAccount = () => {
|
|||||||
|
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [phone, setPhone] = useState("");
|
const [phone, setPhone] = useState("");
|
||||||
const [name, setName] = useState("");
|
const [login, setLogin] = useState("");
|
||||||
const [surname, setSurname] = useState("");
|
const [surname, setSurname] = useState("");
|
||||||
const [patronymic, setPatronymic] = useState("");
|
const [patronymic, setPatronymic] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
const [repiedPassword, setRepiedPassword] = useState("");
|
const [repiedPassword, setRepiedPassword] = useState("");
|
||||||
|
|
||||||
const {user, setUser} = useContext(UserData);
|
const {user, setUser} = useContext(UserData);
|
||||||
|
const [cookies, setCookie, removeCookie] = useCookies(["user"]);
|
||||||
|
|
||||||
function cleanState() {
|
function cleanState() {
|
||||||
setEmail("");
|
setEmail("");
|
||||||
setPhone("");
|
setPhone("");
|
||||||
setName("");
|
setLogin("");
|
||||||
setSurname("");
|
setSurname("");
|
||||||
setPatronymic("");
|
setPatronymic("");
|
||||||
setPassword("");
|
setPassword("");
|
||||||
@ -35,26 +37,52 @@ const EnterAccount = () => {
|
|||||||
cleanState();
|
cleanState();
|
||||||
};
|
};
|
||||||
|
|
||||||
function createUser() {
|
async function createUser() {
|
||||||
completeRegistration({
|
const response = await completeRegistration({
|
||||||
email: email,
|
// email: email,
|
||||||
phone: phone,
|
// phone: phone,
|
||||||
name: name,
|
login: login,
|
||||||
surname: surname,
|
// surname: surname,
|
||||||
patronymic: patronymic,
|
// patronymic: patronymic,
|
||||||
password: password,
|
password: password,
|
||||||
repiedPassword: repiedPassword
|
repiedPassword: repiedPassword
|
||||||
}).then((resolve, reject) => {
|
});
|
||||||
if (resolve.status === 201) {
|
|
||||||
setUser(resolve.data)
|
if (response.status === 200) {
|
||||||
cleanState();
|
setUser({
|
||||||
navigate("/");
|
email: email,
|
||||||
}
|
phone: phone,
|
||||||
}).catch((error) => {
|
login: login,
|
||||||
console.log(error)
|
surname: surname,
|
||||||
})
|
patronymic: patronymic,
|
||||||
|
password: password,
|
||||||
|
});
|
||||||
|
setCookie("token", response.data.token);
|
||||||
|
cleanState();
|
||||||
|
navigate("/");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("Error")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function logInToAccount() {
|
||||||
|
const response = await logIn(login, password)
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
setCookie("token", response.data.token);
|
||||||
|
cleanState();
|
||||||
|
setUser({
|
||||||
|
login: login
|
||||||
|
})
|
||||||
|
navigate("/")
|
||||||
|
// window.location.reload()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
@ -75,14 +103,14 @@ const EnterAccount = () => {
|
|||||||
<h3>Войти в аккаунт</h3>
|
<h3>Войти в аккаунт</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.content__wrapper__login__body}>
|
<div className={classes.content__wrapper__login__body}>
|
||||||
<MyInput placeholder={"Email"} otherMainStyle={{width: "100%", height: "20%"}} otherInputStyle={{width: "100%"}} value={email} change={setEmail}/>
|
<MyInput placeholder={"Логин"} otherMainStyle={{width: "100%", height: "20%"}} otherInputStyle={{width: "100%"}} value={login} change={setLogin}/>
|
||||||
<MyInput type={"password"} placeholder={"Пароль"} otherMainStyle={{width: "100%", height: "20%"}} otherInputStyle={{width: "100%"}} value={password} change={setPassword}/>
|
<MyInput type={"password"} placeholder={"Пароль"} otherMainStyle={{width: "100%", height: "20%"}} otherInputStyle={{width: "100%"}} value={password} change={setPassword}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.content__wrapper__login__footer}>
|
<div className={classes.content__wrapper__login__footer}>
|
||||||
<MyButton
|
<MyButton
|
||||||
text={"Войти"}
|
text={"Войти"}
|
||||||
otherStyle={{height: "50%", width: "20%"}}
|
otherStyle={{height: "50%", width: "20%"}}
|
||||||
click={() => logIn(email, password).then((resolve, reject) => setUser(resolve))}
|
click={logInToAccount}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div> :
|
</div> :
|
||||||
@ -94,7 +122,7 @@ const EnterAccount = () => {
|
|||||||
<MyInput placeholder={"Email"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={email} change={setEmail}/>
|
<MyInput placeholder={"Email"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={email} change={setEmail}/>
|
||||||
<MyInput placeholder={"Номер телефона"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={phone} change={setPhone}/>
|
<MyInput placeholder={"Номер телефона"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={phone} change={setPhone}/>
|
||||||
<div className={classes.content__wrapper__register__body__fio}>
|
<div className={classes.content__wrapper__register__body__fio}>
|
||||||
<MyInput placeholder={"Имя"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={name} change={setName}/>
|
<MyInput placeholder={"Логин"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={login} change={setLogin}/>
|
||||||
<MyInput placeholder={"Фамилия"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={surname} change={setSurname}/>
|
<MyInput placeholder={"Фамилия"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={surname} change={setSurname}/>
|
||||||
<MyInput placeholder={"Отчество (при наличии)"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={patronymic} change={setPatronymic}/>
|
<MyInput placeholder={"Отчество (при наличии)"} otherMainStyle={{width: "32%", height: "100%"}} otherInputStyle={{width: "100%"}} value={patronymic} change={setPatronymic}/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import React, { useState, useContext, useEffect } from "react";
|
import React, { useState, useContext, useEffect } from "react";
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import classes from "../assets/styles/forms.module.scss"
|
import classes from "../assets/styles/forms.module.scss"
|
||||||
import MyButton from "../components/MyButton.jsx";
|
import MyButton from "../components/MyButton.jsx";
|
||||||
import MyInput from "../components/MyInput.jsx";
|
import MyInput from "../components/MyInput.jsx";
|
||||||
import { FormsData, UserData } from "../context";
|
import { FormsData, UserData } from "../context";
|
||||||
import { removeFormApi } from "../hooks/api/formApi.js";
|
import { listFormsApi, createFormApi, removeFormApi } from "../hooks/api/listFormsApi.js";
|
||||||
|
|
||||||
const Forms = () => {
|
const Forms = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -12,39 +13,53 @@ const Forms = () => {
|
|||||||
const {user, setUser} = useContext(UserData);
|
const {user, setUser} = useContext(UserData);
|
||||||
const [stateLoading, setStateLoading] = useState(false);
|
const [stateLoading, setStateLoading] = useState(false);
|
||||||
|
|
||||||
const response = ms => {
|
const [cookies, _, __] = useCookies(["user"]);
|
||||||
return new Promise(r => setTimeout(() => r('response end'), ms))
|
|
||||||
};
|
|
||||||
|
|
||||||
function createForm() {
|
useEffect(() => {
|
||||||
setStateLoading(true);
|
async function listForms() {
|
||||||
response(1000)
|
const response = await listFormsApi(cookies.token)
|
||||||
.then((r) => {
|
|
||||||
console.log(r);
|
if (response.data) {
|
||||||
setStateLoading(false);
|
setForms(response.data)
|
||||||
navigate("/forms/edit");
|
|
||||||
}
|
}
|
||||||
)
|
else if (response.status === 200 && response.data) {
|
||||||
|
setForms([])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
listForms();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
async function createForm() {
|
||||||
|
setStateLoading(true);
|
||||||
|
const response = await createFormApi(cookies.token)
|
||||||
|
setStateLoading(false);
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
navigate(`/forms/${response.data.id}/edit`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function editForm(item) {
|
function editForm(item) {
|
||||||
navigate("/forms/edit", {
|
navigate(`/forms/${item.id}/edit`);
|
||||||
state: {
|
|
||||||
id: item.id,
|
|
||||||
data: item.questions
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeForm(id) {
|
async function removeForm(id) {
|
||||||
removeFormApi(id)
|
setForms([...forms.filter(item => item.id !== id)]);
|
||||||
.then((resolve, _) => {
|
// const response = await removeFormApi(cookies.token, id)
|
||||||
console.log(resolve);
|
|
||||||
setForms([...forms.filter(item => {
|
// if (response.status === 200) {
|
||||||
item.id !== id
|
// setForms([...forms.filter(item => item.id !== id)]);
|
||||||
})]);
|
// }
|
||||||
})
|
// else {
|
||||||
.catch(error => console.log(error));
|
// console.log(response)
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
|
import { useNavigate, useLocation, useParams } from 'react-router-dom';
|
||||||
import classes from "../assets/styles/home.module.scss";
|
import classes from "../assets/styles/home.module.scss";
|
||||||
import MyButton from "../components/MyButton.jsx";
|
import MyButton from "../components/MyButton.jsx";
|
||||||
import MyInput from "../components/MyInput.jsx";
|
import MyInput from "../components/MyInput.jsx";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
|
const [token, setToken] = useState("");
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
@ -19,12 +23,12 @@ const Home = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className={classes.content__token}>
|
<div className={classes.content__token}>
|
||||||
<div className={classes.content__token__wrapper}>
|
<div className={classes.content__token__wrapper}>
|
||||||
<MyInput placeholder={"Введите токен формы..."} otherMainStyle={{width: "100%"}} otherInputStyle={{width: "100%"}}/>
|
<MyInput placeholder={"Введите токен формы..."} otherMainStyle={{width: "100%"}} otherInputStyle={{width: "100%"}} value={token} change={(e) => setToken(e)}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.content__search}>
|
<div className={classes.content__search}>
|
||||||
<div className={classes.content__search__wrapper}>
|
<div className={classes.content__search__wrapper}>
|
||||||
<MyButton text={"Найти форму"}/>
|
<MyButton text={"Найти форму"} click={() => navigate(`/forms/${token}`)}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext, useEffect } from "react";
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation, useParams } from 'react-router-dom';
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
import classes from "../assets/styles/newForm.module.scss";
|
import classes from "../assets/styles/newForm.module.scss";
|
||||||
import MyButton from "../components/MyButton.jsx";
|
import MyButton from "../components/MyButton.jsx";
|
||||||
import AnswerModal from "../components/AnswerModal.jsx";
|
import AnswerModal from "../components/AnswerModal.jsx";
|
||||||
import PreviewModal from "../components/PreviewModal.jsx"
|
import PreviewModal from "../components/PreviewModal.jsx"
|
||||||
import { FormsData, TypeAnswerData } from "../context";
|
import { FormsData, TypeAnswerData } from "../context";
|
||||||
import { saveFormApi, updateFormByFormsApi } from "../hooks/api/formApi.js";
|
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi } from "../hooks/api/formApi.js";
|
||||||
|
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
||||||
|
|
||||||
const NewForm = () => {
|
const NewForm = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const { formId } = useParams();
|
||||||
const [dragElem, setDragElem] = useState(null);
|
const [dragElem, setDragElem] = useState(null);
|
||||||
const [dropElem, setDropElem] = useState(null);
|
const [dropElem, setDropElem] = useState(null);
|
||||||
|
|
||||||
|
const [cookies, _, __] = useCookies(["user"]);
|
||||||
|
|
||||||
const {forms, setForms} = useContext(FormsData);
|
const {forms, setForms} = useContext(FormsData);
|
||||||
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
||||||
@ -21,26 +26,26 @@ const NewForm = () => {
|
|||||||
};
|
};
|
||||||
const [question, setQuestion] = useState("");
|
const [question, setQuestion] = useState("");
|
||||||
const [comment, setComment] = useState("");
|
const [comment, setComment] = useState("");
|
||||||
const [datetime, setDatetime] = useState("");
|
|
||||||
const [mandatory, setMandatory] = useState(false);
|
const [mandatory, setMandatory] = useState(false);
|
||||||
const [optionAnswer, setOptionAnswer] = useState([]);
|
const [optionAnswer, setOptionAnswer] = useState([]);
|
||||||
const [file, setFile] = useState([]);
|
const [file, setFile] = useState([]);
|
||||||
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
|
const [currentTypeAnswer, setCurrentTypeAnswer] = useState("");
|
||||||
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
|
const [currentOptionAnswer, setCurrentOptionAnswer] = useState("");
|
||||||
|
|
||||||
const [newForm, setNewForm] = useState(location.state ? location.state.data : []);
|
const [datetime, setDatetime] = useState("");
|
||||||
|
|
||||||
|
const [listBlock, setListBlock] = useState([]);
|
||||||
|
|
||||||
const [stateModal, setStateModal] = useState(false);
|
const [stateModal, setStateModal] = useState(false);
|
||||||
|
|
||||||
function removeAnswerByForm(id) {
|
function removeAnswerByForm(id) {
|
||||||
setNewForm([...newForm.filter(item => item.id !== id)]);
|
setListBlock([...listBlock.filter(item => item.id !== id)]);
|
||||||
};
|
};
|
||||||
|
|
||||||
function cleanStates() {
|
function cleanStates() {
|
||||||
setStateModal(false)
|
setStateModal(false)
|
||||||
setQuestion("");
|
setQuestion("");
|
||||||
setComment("");
|
setComment("");
|
||||||
setDatetime("");
|
|
||||||
setOptionAnswer([])
|
setOptionAnswer([])
|
||||||
setFile([]);
|
setFile([]);
|
||||||
setCurrentTypeAnswer("");
|
setCurrentTypeAnswer("");
|
||||||
@ -48,6 +53,21 @@ const NewForm = () => {
|
|||||||
setMandatory(false);
|
setMandatory(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function listFormBlock() {
|
||||||
|
const response = await listFormBlockApi(cookies.token, formId);
|
||||||
|
|
||||||
|
if (response.status === 200 && response.data) {
|
||||||
|
setListBlock(responseDataToListBlock(response.data));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
listFormBlock();
|
||||||
|
}, []);
|
||||||
|
|
||||||
function addOptionAnswer(text) {
|
function addOptionAnswer(text) {
|
||||||
setOptionAnswer([...optionAnswer, {
|
setOptionAnswer([...optionAnswer, {
|
||||||
id: nextID(optionAnswer),
|
id: nextID(optionAnswer),
|
||||||
@ -57,56 +77,81 @@ const NewForm = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function editAnswerByForm(id) {
|
function editAnswerByForm(id) {
|
||||||
const obj = newForm.find(item => item.id === id);
|
const obj = listBlock.find(item => item.id === id);
|
||||||
setQuestion(obj.question);
|
setQuestion(obj.question);
|
||||||
setComment(obj.comment);
|
setComment(obj.comment);
|
||||||
setDatetime(obj.datetime);
|
|
||||||
setFile(obj.file);
|
setFile(obj.file);
|
||||||
setCurrentTypeAnswer(obj.typeAnswer);
|
setCurrentTypeAnswer(obj.typeAnswer);
|
||||||
setOptionAnswer(obj.optionAnswer);
|
setOptionAnswer(obj.optionAnswer);
|
||||||
setMandatory(obj.mandatory);
|
setMandatory(obj.mandatory);
|
||||||
setStateModal(id);
|
setStateModal(obj.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateAnswerByForm() {
|
async function updateBlock() {
|
||||||
setNewForm(newForm.map(item => {
|
const data = {
|
||||||
|
id: stateModal,
|
||||||
|
question: question,
|
||||||
|
comment: comment,
|
||||||
|
file: file,
|
||||||
|
mandatory: mandatory,
|
||||||
|
optionAnswer: optionAnswer,
|
||||||
|
typeAnswer: currentTypeAnswer,
|
||||||
|
}
|
||||||
|
|
||||||
|
// const response = await updateBlockApi(cookies.token, stateModal, data);
|
||||||
|
|
||||||
|
// if (response.status === 200) {
|
||||||
|
// setListBlock(listBlock.map(item => {
|
||||||
|
// if (item.id === stateModal) {
|
||||||
|
// item = data
|
||||||
|
// }
|
||||||
|
// return item
|
||||||
|
// }))
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// console.log(response)
|
||||||
|
// }
|
||||||
|
|
||||||
|
setListBlock(listBlock.map(item => {
|
||||||
if (item.id === stateModal) {
|
if (item.id === stateModal) {
|
||||||
item.question = question;
|
item = data
|
||||||
item.comment = comment;
|
|
||||||
item.datetime = datetime;
|
|
||||||
item.file = file;
|
|
||||||
item.mandatory = mandatory;
|
|
||||||
item.optionAnswer = optionAnswer;
|
|
||||||
item.typeAnswer = currentTypeAnswer;
|
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
}))
|
}))
|
||||||
cleanStates()
|
|
||||||
|
cleanStates();
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveStates() {
|
async function addFormBlock() {
|
||||||
setNewForm([...newForm, {
|
const newBlock = {
|
||||||
id: nextID(newForm),
|
|
||||||
question: question,
|
question: question,
|
||||||
typeAnswer: currentTypeAnswer,
|
typeAnswer: currentTypeAnswer,
|
||||||
comment: comment,
|
comment: comment,
|
||||||
datetime: datetime,
|
|
||||||
mandatory: mandatory,
|
mandatory: mandatory,
|
||||||
optionAnswer: optionAnswer,
|
optionAnswer: optionAnswer,
|
||||||
file: file
|
file: file
|
||||||
}]);
|
}
|
||||||
|
|
||||||
|
const response = await addFormBlockApi(cookies.token, formId, newBlock)
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
setListBlock([...listBlock, newBlock]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
cleanStates();
|
cleanStates();
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateFormByForms() {
|
function updateFormByForms() {
|
||||||
updateFormByFormsApi(location.state.id, "Новая форма", newForm)
|
updateFormByFormsApi(location.state.id, "Новая форма", listBlock)
|
||||||
.then((resolve, _) => {
|
.then((resolve, _) => {
|
||||||
console.log(resolve);
|
console.log(resolve);
|
||||||
setForms(
|
setForms(
|
||||||
forms.map(item => {
|
forms.map(item => {
|
||||||
if (item.id === location.state.id) {
|
if (item.id === location.state.id) {
|
||||||
item.title = "Новая форма",
|
item.title = "Новая форма",
|
||||||
item.questions = newForm
|
item.questions = listBlock
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
})
|
})
|
||||||
@ -117,14 +162,14 @@ const NewForm = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function saveForm() {
|
function saveForm() {
|
||||||
saveFormApi("Новая форма", newForm)
|
saveFormApi("Новая форма", listBlock)
|
||||||
.then((resolve, reject) => {
|
.then((resolve, reject) => {
|
||||||
console.log(resolve);
|
console.log(resolve);
|
||||||
setForms(
|
setForms(
|
||||||
[...forms, {
|
[...forms, {
|
||||||
id: nextID(forms),
|
id: nextID(forms),
|
||||||
title: "Новая форма",
|
title: "Новая форма",
|
||||||
questions: newForm,
|
questions: listBlock,
|
||||||
answers: []
|
answers: []
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
@ -137,7 +182,13 @@ const NewForm = () => {
|
|||||||
return (
|
return (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
<div className={classes.header}>
|
<div className={classes.header}>
|
||||||
|
<div className={classes.header__date}>
|
||||||
|
<div className={classes.header__date__item}>
|
||||||
|
<span>Дедлайн выполнения</span>
|
||||||
|
<input type="datetime-local" value={datetime} onChange={event => setDatetime(event.target.value)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className={classes.header__listBtn}>
|
<div className={classes.header__listBtn}>
|
||||||
<MyButton text={'Предпросмотр'} backgroundColor={'rgb(225, 225, 225)'} toggle={"modal"} target={"#previewModal"}/>
|
<MyButton text={'Предпросмотр'} backgroundColor={'rgb(225, 225, 225)'} toggle={"modal"} target={"#previewModal"}/>
|
||||||
<MyButton text={'Опубликовать'} click={location.state ? updateFormByForms : saveForm}/>
|
<MyButton text={'Опубликовать'} click={location.state ? updateFormByForms : saveForm}/>
|
||||||
@ -154,7 +205,7 @@ const NewForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PreviewModal newForm={newForm} listTypeAnswer={listTypeAnswer}/>
|
<PreviewModal listBlock={listBlock} listTypeAnswer={listTypeAnswer}/>
|
||||||
|
|
||||||
<AnswerModal
|
<AnswerModal
|
||||||
stateModal={stateModal}
|
stateModal={stateModal}
|
||||||
@ -164,20 +215,18 @@ const NewForm = () => {
|
|||||||
mandatory={mandatory}
|
mandatory={mandatory}
|
||||||
optionAnswer={optionAnswer}
|
optionAnswer={optionAnswer}
|
||||||
setOptionAnswer={setOptionAnswer}
|
setOptionAnswer={setOptionAnswer}
|
||||||
datetime={datetime}
|
|
||||||
file={file}
|
file={file}
|
||||||
currentOptionAnswer={currentOptionAnswer}
|
currentOptionAnswer={currentOptionAnswer}
|
||||||
listTypeAnswer={listTypeAnswer}
|
listTypeAnswer={listTypeAnswer}
|
||||||
setQuestion={setQuestion}
|
setQuestion={setQuestion}
|
||||||
setComment={setComment}
|
setComment={setComment}
|
||||||
setDatetime={setDatetime}
|
|
||||||
setFile={setFile}
|
setFile={setFile}
|
||||||
setCurrentOptionAnswer={setCurrentOptionAnswer}
|
setCurrentOptionAnswer={setCurrentOptionAnswer}
|
||||||
setMandatory={setMandatory}
|
setMandatory={setMandatory}
|
||||||
cleanStates={cleanStates}
|
cleanStates={cleanStates}
|
||||||
saveStates={saveStates}
|
addFormBlock={addFormBlock}
|
||||||
addOptionAnswer={addOptionAnswer}
|
addOptionAnswer={addOptionAnswer}
|
||||||
updateAnswerByForm={updateAnswerByForm}
|
updateBlock={updateBlock}
|
||||||
setCurrentTypeAnswer={setCurrentTypeAnswer}/>
|
setCurrentTypeAnswer={setCurrentTypeAnswer}/>
|
||||||
|
|
||||||
<div className={classes.content__newForm}>
|
<div className={classes.content__newForm}>
|
||||||
@ -185,7 +234,7 @@ const NewForm = () => {
|
|||||||
<h3>Новая форма</h3>
|
<h3>Новая форма</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.content__newForm__list}>
|
<div className={classes.content__newForm__list}>
|
||||||
{newForm.map((item, i) =>
|
{listBlock.map((item, i) =>
|
||||||
<div
|
<div
|
||||||
className={classes.content__newForm__list__item}
|
className={classes.content__newForm__list__item}
|
||||||
key={i}
|
key={i}
|
||||||
@ -203,8 +252,8 @@ const NewForm = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onDrop={() => {
|
onDrop={() => {
|
||||||
const currentElem = newForm[dragElem]
|
const currentElem = listBlock[dragElem]
|
||||||
const tNewForm = [...newForm]
|
const tNewForm = [...listBlock]
|
||||||
if (dragElem > dropElem) {
|
if (dragElem > dropElem) {
|
||||||
tNewForm.splice(dropElem, 0, currentElem)
|
tNewForm.splice(dropElem, 0, currentElem)
|
||||||
tNewForm.splice(dragElem + 1, 1)
|
tNewForm.splice(dragElem + 1, 1)
|
||||||
@ -213,7 +262,7 @@ const NewForm = () => {
|
|||||||
tNewForm.splice(dropElem + 1, 0, currentElem)
|
tNewForm.splice(dropElem + 1, 0, currentElem)
|
||||||
tNewForm.splice(dragElem, 1)
|
tNewForm.splice(dragElem, 1)
|
||||||
}
|
}
|
||||||
setNewForm(tNewForm)
|
setListBlock(tNewForm)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={classes.content__newForm__list__item__answer}>
|
<div className={classes.content__newForm__list__item__answer}>
|
||||||
|
@ -1,30 +1,60 @@
|
|||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext, useEffect } from "react";
|
||||||
import classes from "../assets/styles/profile.module.scss";
|
import classes from "../assets/styles/profile.module.scss";
|
||||||
import MyButton from "../components/MyButton.jsx";
|
import MyButton from "../components/MyButton.jsx";
|
||||||
import { UserData } from "../context";
|
import { UserData } from "../context";
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
|
import { verifyUserApi } from "../hooks/api/enterAccountApi.js";
|
||||||
|
|
||||||
const Profile = () => {
|
const Profile = () => {
|
||||||
const [edit, setEdit] = useState(true);
|
const [edit, setEdit] = useState(true);
|
||||||
const {user, setUser} = useContext(UserData);
|
const {user, setUser} = useContext(UserData);
|
||||||
|
|
||||||
const [email, setEmail] = useState(user.email);
|
console.log(user)
|
||||||
const [phone, setPhone] = useState(user.phone);
|
|
||||||
const [name, setName] = useState(user.name);
|
const [email, setEmail] = useState("");
|
||||||
const [surname, setSurname] = useState(user.surname);
|
const [phone, setPhone] = useState("");
|
||||||
const [patronymic, setPatronymic] = useState(user.patronymic);
|
const [login, setLogin] = useState("");
|
||||||
|
const [first_name, setFirst_name] = useState("");
|
||||||
|
const [last_name, setLast_name] = useState("");
|
||||||
|
|
||||||
|
const [cookies, _, __] = useCookies(["user"]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(1)
|
||||||
|
async function verifyUser() {
|
||||||
|
const response = await verifyUserApi(cookies.token);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
if (response.status === 200) {
|
||||||
|
setUser(response.data);
|
||||||
|
setEmail(response.data.email);
|
||||||
|
setPhone(response.data.phone);
|
||||||
|
setLogin(response.data.login);
|
||||||
|
setFirst_name(response.data.first_name);
|
||||||
|
setLast_name(response.data.last_name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyUser()
|
||||||
|
}, [])
|
||||||
|
|
||||||
function choiceInput(key) {
|
function choiceInput(key) {
|
||||||
|
console.log(2)
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "email":
|
case "email":
|
||||||
return {get: email, set: setEmail}
|
return {get: email, set: setEmail}
|
||||||
case "phone":
|
case "phone":
|
||||||
return {get: phone, set: setPhone}
|
return {get: phone, set: setPhone}
|
||||||
case "name":
|
case "login":
|
||||||
return {get: name, set: setName}
|
return {get: login, set: setLogin}
|
||||||
case "surname":
|
case "last_name":
|
||||||
return {get: surname, set: setSurname}
|
return {get: last_name, set: setLast_name}
|
||||||
case "patronymic":
|
case "first_name":
|
||||||
return {get: patronymic, set: setPatronymic}
|
return {get: first_name, set: setFirst_name}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +64,11 @@ const Profile = () => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setUser({
|
setUser({
|
||||||
|
login: login,
|
||||||
|
first_name: first_name,
|
||||||
|
last_name: last_name,
|
||||||
email: email,
|
email: email,
|
||||||
phone: phone,
|
phone: phone,
|
||||||
name: name,
|
|
||||||
surname: surname,
|
|
||||||
patronymic: patronymic
|
|
||||||
})
|
})
|
||||||
setEdit(!edit)
|
setEdit(!edit)
|
||||||
}
|
}
|
||||||
@ -61,7 +91,7 @@ const Profile = () => {
|
|||||||
click={() => editUser()}/>
|
click={() => editUser()}/>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.profile__wrapper__body}>
|
<div className={classes.profile__wrapper__body}>
|
||||||
{Object.keys(user).map(key => key !== "password" ? <div className={classes.profile__wrapper__body__item}>
|
{Object.keys(user).map(key => key !== "is_admin" ? <div className={classes.profile__wrapper__body__item}>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
<span class="input-group-text">{key}</span>
|
<span class="input-group-text">{key}</span>
|
||||||
<input
|
<input
|
||||||
|
@ -1,26 +1,67 @@
|
|||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext, useEffect } from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { useCookies } from "react-cookie";
|
||||||
import classes from "../assets/styles/viewForm.module.scss";
|
import classes from "../assets/styles/viewForm.module.scss";
|
||||||
import { FormsData, TypeAnswerData } from "../context";
|
import { FormsData, TypeAnswerData } from "../context";
|
||||||
import GeneratingFormFields from "../components/GeneratingFormFields.jsx";
|
import GeneratingFormFields from "../components/GeneratingFormFields.jsx";
|
||||||
import MyButton from "../components/MyButton.jsx";
|
import MyButton from "../components/MyButton.jsx";
|
||||||
import { saveAnswersApi } from "../hooks/api/formApi.js";
|
import { listFormBlockApi } from "../hooks/api/formApi.js";
|
||||||
|
import { listFormsApi } from "../hooks/api/listFormsApi.js";
|
||||||
|
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
||||||
|
|
||||||
const ViewForm = () => {
|
const ViewForm = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { formId } = useParams();
|
const { formId } = useParams();
|
||||||
const {forms, setForms} = useContext(FormsData);
|
const {forms, setForms} = useContext(FormsData);
|
||||||
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
|
||||||
|
const [cookies, _, __] = useCookies(["user"]);
|
||||||
|
const [questions, setQuestions] = useState([]);
|
||||||
|
const [answers, setAnswers] = useState([]);
|
||||||
|
const [title, setTitle] = useState("");
|
||||||
|
|
||||||
|
|
||||||
function newForm() {
|
useEffect(() => {
|
||||||
return forms.find(item => item.id === Number(formId))
|
async function getForm() {
|
||||||
};
|
const responseForms = await listFormsApi(cookies.token);
|
||||||
|
const responseBlocks = await listFormBlockApi(cookies.token, formId);
|
||||||
|
|
||||||
const [answers, setAnswers] = useState(
|
if (responseBlocks.status === 200 && responseForms.status === 200 && responseBlocks.data) {
|
||||||
newForm() ? newForm().questions.map(item => (
|
// let responseToNewForm = {};
|
||||||
{id: item.id, answer: []}
|
// const result = {
|
||||||
)) : []
|
// title: responseForms.data.find(item => item.id === formId).title,
|
||||||
);
|
// questions: [],
|
||||||
|
// answers: []
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (let item of responseBlocks.data) {
|
||||||
|
// responseToNewForm["id"] = item.id;
|
||||||
|
|
||||||
|
// for (let block of item.data) {
|
||||||
|
// responseToNewForm[block.Key] = block.Value
|
||||||
|
// };
|
||||||
|
|
||||||
|
// result.questions.push(responseToNewForm);
|
||||||
|
// result.answers.push(
|
||||||
|
// {id: item.id, answer: []}
|
||||||
|
// )
|
||||||
|
// responseToNewForm = {};
|
||||||
|
// };
|
||||||
|
const listBlocks = responseDataToListBlock(responseBlocks.data);
|
||||||
|
|
||||||
|
setQuestions(listBlocks)
|
||||||
|
setAnswers(listBlocks.map(item => (
|
||||||
|
{id: item.id, answer: []}
|
||||||
|
)))
|
||||||
|
setTitle(responseForms.data.find(item => item.id === formId).title)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(responseForms)
|
||||||
|
console.log(responseBlocks)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getForm()
|
||||||
|
}, []);
|
||||||
|
|
||||||
function updateAnswersForm(value, id) {
|
function updateAnswersForm(value, id) {
|
||||||
setAnswers(
|
setAnswers(
|
||||||
@ -34,30 +75,32 @@ const ViewForm = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function saveAnswers() {
|
function saveAnswers() {
|
||||||
saveAnswersApi(formId, answers)
|
// saveAnswersApi(formId, answers)
|
||||||
.then((resolve, _) => {
|
// .then((resolve, _) => {
|
||||||
console.log(resolve)
|
// console.log(resolve)
|
||||||
setAnswers([]);
|
// setAnswers([]);
|
||||||
navigate("/");
|
// navigate("/");
|
||||||
})
|
// })
|
||||||
.catch((error) => console.log(error));
|
// .catch((error) => console.log(error));
|
||||||
|
setAnswers([]);
|
||||||
|
navigate("/forms");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
{newForm() ?
|
{questions ?
|
||||||
<div className={classes.wrapper}>
|
<div className={classes.wrapper}>
|
||||||
<div className={classes.form}>
|
<div className={classes.form}>
|
||||||
<div className={classes.form__header}>
|
<div className={classes.form__header}>
|
||||||
<div className={classes.form__header__title}>
|
<div className={classes.form__header__title}>
|
||||||
<span>{newForm().title}</span>
|
<span>{title}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.form__header__id}>
|
<div className={classes.form__header__id}>
|
||||||
<span>#{formId}</span>
|
<span>#{formId}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.form__content}>
|
<div className={classes.form__content}>
|
||||||
<GeneratingFormFields newForm={newForm().questions} listTypeAnswer={listTypeAnswer} answers={answers} updateAnswersForm={updateAnswersForm}/>
|
<GeneratingFormFields listBlock={questions} listTypeAnswer={listTypeAnswer} answers={answers} updateAnswersForm={updateAnswersForm}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.footer}>
|
<div className={classes.footer}>
|
||||||
|
@ -21,7 +21,7 @@ const router = createBrowserRouter([
|
|||||||
element: <Forms/>,
|
element: <Forms/>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/forms/edit",
|
path: "/forms/:formId/edit",
|
||||||
element: <NewForm/>
|
element: <NewForm/>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user