This commit is contained in:
kuwsh1n 2024-04-13 21:53:36 +03:00
parent 15b981c170
commit cf8904d475
17 changed files with 511 additions and 116 deletions

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect, useLayoutEffect } from "react";
import { Outlet, useNavigate } from "react-router-dom";
import { FormsData, UserData, TypeAnswerData } from "./context";
import { FormsData, UserData, TypeAnswerData, answersData } from "./context";
import { useCookies } from "react-cookie";
import { globalRender } from "./router/protectedRouting.js";
import { verifyUserApi } from "./hooks/api/enterAccountApi.js"
@ -20,6 +20,7 @@ const App = () => {
const navigate = useNavigate();
const [forms, setForms] = useState([]);
const [user, setUser] = useState(false);
const [answersList, setAnswersList] = useState([]);
const [listTypeAnswer, setListTypeAnswer] = useState([
{id: 1, text: 'Краткий ответ', typeTag: InputText},
{id: 2, text: 'Расширенный ответ', typeTag: TextArea},
@ -48,11 +49,12 @@ const App = () => {
}
}
verifyUser()
verifyUser();
}, [])
return (
<UserData.Provider value={{ user, setUser }}>
<answersData.Provider value={{ answersList, setAnswersList }}>
<FormsData.Provider value={{ forms, setForms }}>
<TypeAnswerData.Provider value={{ listTypeAnswer, setListTypeAnswer }}>
<div className={classes.main}>
@ -67,6 +69,7 @@ const App = () => {
</div>
</TypeAnswerData.Provider>
</FormsData.Provider>
</answersData.Provider>
</UserData.Provider>
)
}

View File

@ -0,0 +1,107 @@
.main {
width: 100%;
height: 100%;
}
.wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.answers {
width: 70%;
height: 70%;
box-shadow: 0 0 5px 1px rgb(200, 200, 200);
padding: 1.5%;
position: relative;
&__linkAdmin {
position: absolute;
bottom: 103%;
left: 10px;
span {
font-size: 15px;
font-family: "Montserrat", sans-serif;
color: rgb(100, 100, 100);
cursor: pointer;
&:hover {
text-decoration: underline;
color: rgb(66, 68, 189);
}
}
}
&__wrapper {
&__header {
width: 100%;
height: 15%;
display: flex;
justify-content: start;
align-items: center;
margin-bottom: 10px;
h3 {
font-size: 25px;
font-family: "Montserrat", sans-serif;
color: rgb(100, 100, 100);
}
}
&__body {
width: 100%;
height: 85%;
&__item {
padding: 5px;
border-bottom: 1px solid rgb(200, 200, 200);
font-size: 15px;
font-family: "Montserrat", sans-serif;
cursor: pointer;
// &__question {
// &__text {
// font-size: 15px;
// font-family: "Montserrat", sans-serif;
// }
// &__comment {
// font-size: 11px;
// font-family: "Montserrat", sans-serif;
// font-style: italic;
// color: rgb(200, 200, 200);
// }
// }
// &__answer {
// &__text {
// font-size: 15px;
// font-family: "Montserrat", sans-serif;
// }
// }
}
}
}
}
.myModal {
&__item {
padding: 5px;
border-bottom: 1px solid rgb(200, 200, 200);
font-size: 15px;
font-family: "Montserrat", sans-serif;
cursor: pointer;
&__question {
&__text {
font-size: 15px;
font-family: "Montserrat", sans-serif;
}
&__comment {
font-size: 11px;
font-family: "Montserrat", sans-serif;
font-style: italic;
color: rgb(200, 200, 200);
}
}
&__answer {
&__text {
font-size: 15px;
font-family: "Montserrat", sans-serif;
}
}
}
}

View File

@ -87,6 +87,7 @@
justify-content: space-around;
flex-direction: column;
padding-bottom: 5px;
&__fio {
height: 15%;
display: flex;

View File

@ -40,6 +40,13 @@
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
&__btn {
height: 100%;
width: 35%;
display: flex;
justify-content: space-between;
align-items: center;
}
h3 {
font-size: 25px;
font-family: "Montserrat", sans-serif;

View File

@ -5,3 +5,5 @@ export const FormsData = createContext([]);
export const UserData = createContext(false);
export const TypeAnswerData = createContext();
export const answersData = createContext();

18
src/hooks/api/adminApi.js Normal file
View File

@ -0,0 +1,18 @@
import axios from "axios";
async function listUsersApi(token) {
try {
const response = await axios.get(`https://api.minerva.krbl.ru/auth/manage/users`,
{
headers: {
"Authorization": `Token ${token}`
}
})
return response
}
catch (e) {
return e
}
};
export {listUsersApi}

View File

@ -33,26 +33,11 @@ async function addFormBlockApi(token, formId, data) {
}
};
// 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(`https://api.minerva.krbl.ru/formBuilder/edit/${blockId}/set`,
{
data: data
"data": data
},
{
headers: {
@ -103,4 +88,49 @@ async function saveFormApi(token) {
}
};
export { addFormBlockApi, listFormBlockApi, saveFormApi, updateBlockApi, updateOrderBlockApi }
async function listFormBlockByTokenApi(token, formToken) {
try {
const response = await axios.get(`https://api.minerva.krbl.ru/form/${formToken}/get`,
{
headers: {
"Authorization": `Token ${token}`
}
})
return response
}
catch (e) {
return e
}
};
async function saveAnswersApi(token, formToken, data) {
try {
const response = await axios.post(`https://api.minerva.krbl.ru/form/${formToken}/submit`, {"data": data},
{
headers: {
"Authorization": `Token ${token}`
}
})
return response
}
catch (e) {
return e
}
};
async function getAnswersApi(token, formToken) {
try {
const response = await axios.get(`https://api.minerva.krbl.ru/formBuilder/edit/${formToken}/answers`,
{
headers: {
"Authorization": `Token ${token}`
}
})
return response
}
catch (e) {
return e
}
};
export { addFormBlockApi, listFormBlockApi, saveFormApi, updateBlockApi, updateOrderBlockApi, listFormBlockByTokenApi, saveAnswersApi, getAnswersApi }

View File

@ -35,7 +35,7 @@ async function createFormApi(token) {
async function removeFormApi(token, formId) {
try {
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/delete`, {
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/delete`, {}, {
headers: {
"Authorization": `Token ${token}`,
},
@ -67,7 +67,7 @@ async function updateTitleFormApi(token, formId, title) {
async function newFormTokenApi(token, formId) {
try {
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/access/new`,
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/access/new`, {},
{
headers: {
"Authorization": `Token ${token}`
@ -80,4 +80,19 @@ async function newFormTokenApi(token, formId) {
}
};
export { listFormsApi, createFormApi, removeFormApi, updateTitleFormApi, newFormTokenApi };
async function listFormsByTokenApi(token, formId) {
try {
const response = await axios.get(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/access/list`,
{
headers: {
"Authorization": `Token ${token}`
}
})
return response
}
catch (e) {
return e
}
};
export { listFormsApi, createFormApi, removeFormApi, updateTitleFormApi, newFormTokenApi, listFormsByTokenApi };

View File

@ -0,0 +1,31 @@
import axios from "axios";
async function editUserApi(token, data) {
try {
const response = await axios.post("https://api.minerva.krbl.ru/auth/manage/edit",
{
"email": data.email,
"first_name": data.first_name,
"id": "6617fec3f603c43e1719d3c8",
"is_admin": data.is_admin,
"last_name": data.last_name,
"login": data.login,
"phone": data.phone
},
{
headers: {
"Authorization": `Token ${token}`,
},
})
console.log(response)
return response
}
catch(e) {
console.log(e)
return e
}
// return false
}
export {editUserApi}

129
src/pages/AnswersForm.jsx Normal file
View File

@ -0,0 +1,129 @@
import React, { useState, useContext, useEffect } from "react";
import { useCookies } from "react-cookie";
import { useNavigate, useParams } from 'react-router-dom';
import { answersData } from "../context";
import classes from "../assets/styles/answersForm.module.scss";
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock";
import { listFormBlockApi, getAnswersApi } from "../hooks/api/formApi";
import { listUsersApi } from "../hooks/api/adminApi";
const AnswersForm = () => {
const { formId } = useParams();
const {answersList, setAnswersList} = useContext(answersData);
const [data, setData] = useState(false);
const [cookies, _, __] = useCookies(["user"]);
useEffect(() => {
async function getForm() {
const result = []
const responseBlocks = await listFormBlockApi(cookies.token, formId);
const responseAnswers = await getAnswersApi(cookies.token, formId);
const listUsers = await listUsersApi(cookies.token);
console.log("responseBlocks", responseBlocks)
console.log("responseAnswers", responseAnswers)
if (responseBlocks.status === 200 && responseBlocks.data) {
const listBlocks = responseDataToListBlock(responseBlocks.data);
if (responseAnswers.data) {
for (let item of responseAnswers.data) {
const blocks = {
user: listUsers.data.find(user => user.id === item.user_id).login,
block: []
}
if (item.data) {
for (let i = 0; i < item.data.length; i++) {
blocks.block.push({answers: {id: item.data[i][0].Value, answer: item.data[i][1].Value}, question: listBlocks[i]})
}
}
else {
for (let i = 0; i < listBlocks.length; i++) {
blocks.block.push({answers: [], question: listBlocks[i]})
}
}
result.push(blocks)
}
console.log("result", result)
}
setData(result)
}
else {
console.log(responseBlocks)
}
};
getForm()
}, []);
return (
<div className={classes.main}>
<div className={classes.wrapper}>
<div className={classes.answers}>
<div className={classes.answers__wrapper}>
<div className={classes.answers__wrapper__header}>
<h3>Ответы</h3>
</div>
<div className={classes.answers__wrapper__body}>
{data ?
data.map((item, i) =>
<div className={classes.answers__wrapper__body__item} key={i}>
<div className={classes.answers__wrapper__body__item__user} data-bs-toggle={"modal"} data-bs-target={`#answersModal${i}`}>
{item.user}
</div>
<div class="modal fade myModal" className={classes.myModal} id={`answersModal${i}`} tabIndex="-1" aria-labelledby="exampleModalLabel" data-bs-backdrop="static" aria-hidden="true">
<div class="modal-dialog myModal__dialog" className={classes.myModal__dialog}>
<div class="modal-content" className={classes.myModal__dialog__content}>
<div class="modal-body" className={classes.myModal__dialog__content__body}>
{item.block.map((block, i) =>
<div className={classes.myModal__item} key={i}>
<div className={classes.myModal__item__question}>
<p className={classes.myModal__item__question__text}>{block.question.question}</p>
<p className={classes.myModal__item__question__comment}>{block.question.comment}</p>
</div>
<div className={classes.myModal__item__answer}>
<p className={classes.myModal__item__question__text}>Ответ: {block.answers.answer}</p>
</div>
</div>)}
</div>
<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">Отмена</button>
</div>
</div>
</div>
</div>
</div>
)
: <div>Ответов нет</div>}
{/* <MyButton text={'Предпросмотр'} backgroundColor={'rgb(225, 225, 225)'} toggle={"modal"} target={"#previewModal"}/>
{data ? <div className={classes.answers__wrapper__body__item}></div> */}
{/* {data ?
data.map((item, i) =>
<div className={classes.answers__wrapper__body__item} key={i}>
<div className={classes.answers__wrapper__body__item__question}>
<p className={classes.answers__wrapper__body__item__question__text}>{i + 1}) {item.question.question}</p>
<p className={classes.item__question__comment}>{item.question.comment}</p>
</div>
<div className={classes.answers__wrapper__body__item__answer}>
<p className={classes.answers__wrapper__body__item__question__text}>Ответ: {item.answers.answer}</p>
</div>
</div>
)
: <div>Ответов нет</div>} */}
</div>
</div>
</div>
</div>
</div>
)
}
export default AnswersForm;

View File

@ -5,7 +5,7 @@ import classes from "../assets/styles/enterAccount.module.scss";
import MyInput from "../components/MyInput.jsx";
import MyButton from "../components/MyButton.jsx";
import { UserData } from "../context";
import { logIn, completeRegistration } from "../hooks/api/enterAccountApi.js";
import { logIn, completeRegistration, verifyUserApi } from "../hooks/api/enterAccountApi.js";
const EnterAccount = () => {
const [enter, setEnter] = useState("login");
@ -39,11 +39,7 @@ const EnterAccount = () => {
async function createUser() {
const response = await completeRegistration({
// email: email,
// phone: phone,
login: login,
// first_name: surname,
// last_name: patronymic,
password: password,
repiedPassword: repiedPassword
});
@ -73,9 +69,9 @@ const EnterAccount = () => {
if (response.status === 200) {
setCookie("token", response.data.token);
cleanState();
setUser({
login: login
})
// setUser({
// login: login
// })
window.location.reload();
// navigate("/")
// window.location.reload()
@ -121,6 +117,11 @@ const EnterAccount = () => {
<h3>Зарегестрировать учетную запись</h3>
</div>
<div className={classes.content__wrapper__register__body}>
<MyInput placeholder={"Логин"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={login} change={setLogin}/>
<MyInput type={"password"} placeholder={"Пароль"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={password} change={setPassword}/>
<MyInput type={'password'} placeholder={"Повторите пароль"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={repiedPassword} change={setRepiedPassword}/>
</div>
{/* <div className={classes.content__wrapper__register__body}>
<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}/>
<div className={classes.content__wrapper__register__body__fio}>
@ -130,7 +131,7 @@ const EnterAccount = () => {
</div>
<MyInput type={'password'} placeholder={"Пароль"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={password} change={setPassword}/>
<MyInput type={'password'} placeholder={"Повторите пароль"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={repiedPassword} change={setRepiedPassword}/>
</div>
</div> */}
<div className={classes.content__wrapper__register__footer}>
<MyButton text={"Создать"} otherStyle={{height: "100%", width: "20%"}} click={() => createUser()}/>
</div>

View File

@ -5,7 +5,7 @@ import classes from "../assets/styles/forms.module.scss"
import MyButton from "../components/MyButton.jsx";
import MyInput from "../components/MyInput.jsx";
import { FormsData, UserData } from "../context";
import { listFormsApi, createFormApi, removeFormApi, newFormTokenApi } from "../hooks/api/listFormsApi.js";
import { listFormsApi, createFormApi, removeFormApi, newFormTokenApi, listFormsByTokenApi } from "../hooks/api/listFormsApi.js";
const Forms = () => {
const navigate = useNavigate();
@ -20,10 +20,10 @@ const Forms = () => {
const response = await listFormsApi(cookies.token);
if (response.data) {
setForms(response.data)
setForms(response.data);
}
else if (response.status === 200 && response.data) {
setForms([])
setForms([]);
}
else {
console.log(response)
@ -41,7 +41,7 @@ const Forms = () => {
if (response.data) {
const token = await newFormTokenApi(cookies.token, response.data.id)
console.log("token", token)
navigate(`/forms/${response.data.id}/edit`)
}
else {
@ -54,22 +54,32 @@ const Forms = () => {
};
async function removeForm(id) {
setForms([...forms.filter(item => item.id !== id)]);
// const response = await removeFormApi(cookies.token, id)
const response = await removeFormApi(cookies.token, id)
// if (response.status === 200) {
// setForms([...forms.filter(item => item.id !== id)]);
// }
// else {
// console.log(response)
// }
if (response.status === 200) {
setForms([...forms.filter(item => item.id !== id)]);
}
else {
console.log(response)
}
};
async function openFormView(formId) {
const response = await listFormsByTokenApi(cookies.token, formId);
if (response.status === 200) {
navigate(`/forms/${response.data.tokens[0].id}/`);
}
else {
console.log(response)
}
}
return (
<div className={classes.main}>
<div className={classes.wrapper}>
<div className={classes.panel}>
<MyInput placeholder={'Поиск...'}/>
{/* <MyInput placeholder={'Поиск...'}/> */}
<MyButton click={createForm} otherStyle={{width: '200px'}} text={
stateLoading ? <div class="spinner-border text-light" role="status">
<span class="visually-hidden">Загрузка...</span>
@ -90,7 +100,8 @@ const Forms = () => {
<div className={classes.listForms__forms__item__update}>{item.update}</div> */}
<i class="fa-solid fa-ellipsis-vertical" id="action" data-bs-toggle="dropdown"></i>
<ul class="dropdown-menu" aria-labelledby="action">
<li><a class="dropdown-item" onClick={() => navigate(`/forms/${item.id}/`)}>Открыть</a></li>
<li><a class="dropdown-item" onClick={() => openFormView(item.id)}>Открыть</a></li>
<li><a class="dropdown-item" onClick={() => navigate(`/forms/${item.id}/answers`)}>Ответы</a></li>
<li><a class="dropdown-item" onClick={() => navigator.clipboard.writeText(`http://localhost:3000/forms/${item.id}/`)}>Скопировать ссылку</a></li>
<li><a class="dropdown-item" onClick={() => removeForm(item.id)}>Удалить</a></li>
</ul>

View File

@ -103,26 +103,28 @@ const NewForm = () => {
typeAnswer: currentTypeAnswer,
}
// const response = await updateBlockApi(cookies.token, stateModal, data);
console.log(stateModal)
// if (response.status === 200) {
// setListBlock(listBlock.map(item => {
// if (item.id === stateModal) {
// item = data
// }
// return item
// }))
// }
// else {
// console.log(response)
// }
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) {
// item = data
// }
// return item
// }))
cleanStates();
};

View File

@ -5,6 +5,7 @@ import MyButton from "../components/MyButton.jsx";
import { UserData } from "../context";
import { useCookies } from "react-cookie";
import { verifyUserApi } from "../hooks/api/enterAccountApi.js";
import { editUserApi } from "../hooks/api/profileApi.js";
const Profile = () => {
const [edit, setEdit] = useState(true);
@ -16,7 +17,7 @@ const Profile = () => {
const [first_name, setFirst_name] = useState("");
const [last_name, setLast_name] = useState("");
const [cookies, _, __] = useCookies(["user"]);
const [cookies, setCookies, removeCookies] = useCookies(["user"]);
const navigate = useNavigate();
useEffect(() => {
@ -42,7 +43,6 @@ const Profile = () => {
}, [])
function choiceInput(key) {
console.log(2)
switch (key) {
case "email":
return {get: email, set: setEmail}
@ -57,11 +57,22 @@ const Profile = () => {
}
}
function editUser() {
async function editUser() {
if (edit) {
setEdit(!edit)
}
else {
const response = await editUserApi(cookies.token, {
login: login,
first_name: first_name,
last_name: last_name,
email: email,
phone: phone,
is_admin: user.is_admin
})
if (response.status === 200) {
setUser({
login: login,
first_name: first_name,
@ -71,26 +82,43 @@ const Profile = () => {
})
setEdit(!edit)
}
}
};
function exitAccount() {
removeCookies("token");
setUser(false);
navigate("/");
}
return (
<div className={classes.main}>
<div className={classes.wrapper}>
<div className={classes.profile}>
<div className={classes.profile__linkAdmin}>
{/* {user.is_admin ? <div className={classes.profile__linkAdmin}>
<span onClick={() => navigate("/admin")}>Админ панель</span>
</div>
</div> : <div></div>} */}
<div className={classes.profile__wrapper}>
<div className={classes.profile__wrapper__header}>
<h3>Ваши данные</h3>
<MyButton
<div className={classes.profile__wrapper__header__btn}>
{user.is_admin ? <MyButton
text={
edit ?
<span>Редактировать <i class="fa-solid fa-pen"></i></span> :
<span>Сохранить <i class="fa-solid fa-floppy-disk"></i></span>
}
backgroundColor={edit ? "rgb(200, 200, 200)" : ""}
click={() => editUser()}/>
click={() => editUser()}/> : <div>Запросите изменение профиля у администратора</div>}
<MyButton
text={
<span>Выйти</span>
}
backgroundColor={edit ? "rgb(252, 151, 151)" : ""}
click={() => exitAccount()}/>
</div>
</div>
<div className={classes.profile__wrapper__body}>
{Object.keys(user).map(key => key !== "is_admin" ? <div className={classes.profile__wrapper__body__item}>

View File

@ -2,40 +2,41 @@ import React, { useState, useContext, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useCookies } from "react-cookie";
import classes from "../assets/styles/viewForm.module.scss";
import { FormsData, TypeAnswerData } from "../context";
import { FormsData, TypeAnswerData, answersData, UserData } from "../context";
import GeneratingFormFields from "../components/GeneratingFormFields.jsx";
import MyButton from "../components/MyButton.jsx";
import { listFormBlockApi } from "../hooks/api/formApi.js";
import { listFormBlockApi, listFormBlockByTokenApi, saveAnswersApi } from "../hooks/api/formApi.js";
import { listFormsApi } from "../hooks/api/listFormsApi.js";
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
const ViewForm = () => {
const navigate = useNavigate();
const { formId } = useParams();
const {user, setUser} = useContext(UserData);
const {forms, setForms} = useContext(FormsData);
const {answersList, setAnswersList} = useContext(answersData);
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
const [cookies, _, __] = useCookies(["user"]);
const [cookies, setCookies, __] = useCookies(["user"]);
const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState([]);
const [title, setTitle] = useState("");
// const [title, setTitle] = useState("");
useEffect(() => {
async function getForm() {
const responseForms = await listFormsApi(cookies.token);
const responseBlocks = await listFormBlockApi(cookies.token, formId);
// const responseForms = await listFormsApi(cookies.token);
const responseBlocks = await listFormBlockByTokenApi(cookies.token, formId);
if (responseBlocks.status === 200 && responseForms.status === 200 && responseBlocks.data) {
const listBlocks = responseDataToListBlock(responseBlocks.data);
if (responseBlocks.status === 200 && responseBlocks.data) {
const listBlocks = responseDataToListBlock(responseBlocks.data.blocks);
setQuestions(listBlocks)
setAnswers(listBlocks.map(item => (
{id: item.id, answer: []}
)))
setTitle(responseForms.data.find(item => item.id === formId).title)
// setTitle(responseForms.data.find(item => item.id === formId).title)
}
else {
console.log(responseForms)
// console.log(responseForms)
console.log(responseBlocks)
}
};
@ -54,17 +55,21 @@ const ViewForm = () => {
)
};
function saveAnswers() {
// saveAnswersApi(formId, answers)
// .then((resolve, _) => {
// console.log(resolve)
// setAnswers([]);
// navigate("/");
// })
// .catch((error) => console.log(error));
async function saveAnswers() {
const response = await saveAnswersApi(cookies.token, formId, answers);
console.log(response)
if (response.status === 200) {
setAnswersList([...answersList, {
id: formId,
user: user.login,
answers: answers
}])
setAnswers([]);
navigate("/forms");
}
}
return (
<div className={classes.main}>
@ -72,9 +77,6 @@ const ViewForm = () => {
<div className={classes.wrapper}>
<div className={classes.form}>
<div className={classes.form__header}>
<div className={classes.form__header__title}>
<span>{title}</span>
</div>
<div className={classes.form__header__id}>
<span>#{formId}</span>
</div>

View File

@ -4,6 +4,9 @@ const protectedUrl = {
"/forms/edit",
"/profile"
],
Authorized: [
"enter"
],
notRights: [
]

View File

@ -8,6 +8,7 @@ import App from "../App.jsx";
import Profile from "../pages/Profile.jsx";
import ViewForm from "../pages/ViewForm.jsx";
import AdminPanel from '../pages/AdminPanel.jsx';
import AnswersForm from '../pages/AnswersForm.jsx';
const router = createBrowserRouter([
{
@ -40,6 +41,10 @@ const router = createBrowserRouter([
{
path: "/admin",
element: <AdminPanel/>
},
{
path: "/forms/:formId/answers",
element: <AnswersForm/>
}
]
}