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 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, answersData } from "./context";
import { useCookies } from "react-cookie"; 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 { verifyUserApi } from "./hooks/api/enterAccountApi.js"
@ -20,6 +20,7 @@ const App = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const [forms, setForms] = useState([]); const [forms, setForms] = useState([]);
const [user, setUser] = useState(false); const [user, setUser] = useState(false);
const [answersList, setAnswersList] = useState([]);
const [listTypeAnswer, setListTypeAnswer] = useState([ const [listTypeAnswer, setListTypeAnswer] = useState([
{id: 1, text: 'Краткий ответ', typeTag: InputText}, {id: 1, text: 'Краткий ответ', typeTag: InputText},
{id: 2, text: 'Расширенный ответ', typeTag: TextArea}, {id: 2, text: 'Расширенный ответ', typeTag: TextArea},
@ -48,11 +49,12 @@ const App = () => {
} }
} }
verifyUser() verifyUser();
}, []) }, [])
return ( return (
<UserData.Provider value={{ user, setUser }}> <UserData.Provider value={{ user, setUser }}>
<answersData.Provider value={{ answersList, setAnswersList }}>
<FormsData.Provider value={{ forms, setForms }}> <FormsData.Provider value={{ forms, setForms }}>
<TypeAnswerData.Provider value={{ listTypeAnswer, setListTypeAnswer }}> <TypeAnswerData.Provider value={{ listTypeAnswer, setListTypeAnswer }}>
<div className={classes.main}> <div className={classes.main}>
@ -67,6 +69,7 @@ const App = () => {
</div> </div>
</TypeAnswerData.Provider> </TypeAnswerData.Provider>
</FormsData.Provider> </FormsData.Provider>
</answersData.Provider>
</UserData.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; justify-content: space-around;
flex-direction: column; flex-direction: column;
padding-bottom: 5px; padding-bottom: 5px;
&__fio { &__fio {
height: 15%; height: 15%;
display: flex; display: flex;

View File

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

View File

@ -5,3 +5,5 @@ export const FormsData = createContext([]);
export const UserData = createContext(false); export const UserData = createContext(false);
export const TypeAnswerData = createContext(); 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) { async function updateBlockApi(token, blockId, data) {
try { try {
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${blockId}/set`, const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${blockId}/set`,
{ {
data: data "data": data
}, },
{ {
headers: { 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) { async function removeFormApi(token, formId) {
try { 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: { headers: {
"Authorization": `Token ${token}`, "Authorization": `Token ${token}`,
}, },
@ -67,7 +67,7 @@ async function updateTitleFormApi(token, formId, title) {
async function newFormTokenApi(token, formId) { async function newFormTokenApi(token, formId) {
try { 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: { headers: {
"Authorization": `Token ${token}` "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 MyInput from "../components/MyInput.jsx";
import MyButton from "../components/MyButton.jsx"; import MyButton from "../components/MyButton.jsx";
import { UserData } from "../context"; import { UserData } from "../context";
import { logIn, completeRegistration } from "../hooks/api/enterAccountApi.js"; import { logIn, completeRegistration, verifyUserApi } from "../hooks/api/enterAccountApi.js";
const EnterAccount = () => { const EnterAccount = () => {
const [enter, setEnter] = useState("login"); const [enter, setEnter] = useState("login");
@ -39,11 +39,7 @@ const EnterAccount = () => {
async function createUser() { async function createUser() {
const response = await completeRegistration({ const response = await completeRegistration({
// email: email,
// phone: phone,
login: login, login: login,
// first_name: surname,
// last_name: patronymic,
password: password, password: password,
repiedPassword: repiedPassword repiedPassword: repiedPassword
}); });
@ -73,9 +69,9 @@ const EnterAccount = () => {
if (response.status === 200) { if (response.status === 200) {
setCookie("token", response.data.token); setCookie("token", response.data.token);
cleanState(); cleanState();
setUser({ // setUser({
login: login // login: login
}) // })
window.location.reload(); window.location.reload();
// navigate("/") // navigate("/")
// window.location.reload() // window.location.reload()
@ -121,6 +117,11 @@ const EnterAccount = () => {
<h3>Зарегестрировать учетную запись</h3> <h3>Зарегестрировать учетную запись</h3>
</div> </div>
<div className={classes.content__wrapper__register__body}> <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={"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}>
@ -130,7 +131,7 @@ const EnterAccount = () => {
</div> </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={password} change={setPassword}/>
<MyInput type={'password'} placeholder={"Повторите пароль"} otherMainStyle={{width: "100%", height: "15%"}} otherInputStyle={{width: "100%"}} value={repiedPassword} change={setRepiedPassword}/> <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}> <div className={classes.content__wrapper__register__footer}>
<MyButton text={"Создать"} otherStyle={{height: "100%", width: "20%"}} click={() => createUser()}/> <MyButton text={"Создать"} otherStyle={{height: "100%", width: "20%"}} click={() => createUser()}/>
</div> </div>

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import MyButton from "../components/MyButton.jsx";
import { UserData } from "../context"; import { UserData } from "../context";
import { useCookies } from "react-cookie"; import { useCookies } from "react-cookie";
import { verifyUserApi } from "../hooks/api/enterAccountApi.js"; import { verifyUserApi } from "../hooks/api/enterAccountApi.js";
import { editUserApi } from "../hooks/api/profileApi.js";
const Profile = () => { const Profile = () => {
const [edit, setEdit] = useState(true); const [edit, setEdit] = useState(true);
@ -16,7 +17,7 @@ const Profile = () => {
const [first_name, setFirst_name] = useState(""); const [first_name, setFirst_name] = useState("");
const [last_name, setLast_name] = useState(""); const [last_name, setLast_name] = useState("");
const [cookies, _, __] = useCookies(["user"]); const [cookies, setCookies, removeCookies] = useCookies(["user"]);
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => { useEffect(() => {
@ -42,7 +43,6 @@ const Profile = () => {
}, []) }, [])
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}
@ -57,11 +57,22 @@ const Profile = () => {
} }
} }
function editUser() { async function editUser() {
if (edit) { if (edit) {
setEdit(!edit) setEdit(!edit)
} }
else { 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({ setUser({
login: login, login: login,
first_name: first_name, first_name: first_name,
@ -71,26 +82,43 @@ const Profile = () => {
}) })
setEdit(!edit) setEdit(!edit)
} }
}
};
function exitAccount() {
removeCookies("token");
setUser(false);
navigate("/");
} }
return ( return (
<div className={classes.main}> <div className={classes.main}>
<div className={classes.wrapper}> <div className={classes.wrapper}>
<div className={classes.profile}> <div className={classes.profile}>
<div className={classes.profile__linkAdmin}> {/* {user.is_admin ? <div className={classes.profile__linkAdmin}>
<span onClick={() => navigate("/admin")}>Админ панель</span> <span onClick={() => navigate("/admin")}>Админ панель</span>
</div> </div> : <div></div>} */}
<div className={classes.profile__wrapper}> <div className={classes.profile__wrapper}>
<div className={classes.profile__wrapper__header}> <div className={classes.profile__wrapper__header}>
<h3>Ваши данные</h3> <h3>Ваши данные</h3>
<MyButton <div className={classes.profile__wrapper__header__btn}>
{user.is_admin ? <MyButton
text={ text={
edit ? edit ?
<span>Редактировать <i class="fa-solid fa-pen"></i></span> : <span>Редактировать <i class="fa-solid fa-pen"></i></span> :
<span>Сохранить <i class="fa-solid fa-floppy-disk"></i></span> <span>Сохранить <i class="fa-solid fa-floppy-disk"></i></span>
} }
backgroundColor={edit ? "rgb(200, 200, 200)" : ""} 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>
<div className={classes.profile__wrapper__body}> <div className={classes.profile__wrapper__body}>
{Object.keys(user).map(key => key !== "is_admin" ? <div className={classes.profile__wrapper__body__item}> {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 { useNavigate, useParams } from "react-router-dom";
import { useCookies } from "react-cookie"; 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, answersData, UserData } 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 { listFormBlockApi } from "../hooks/api/formApi.js"; import { listFormBlockApi, listFormBlockByTokenApi, saveAnswersApi } from "../hooks/api/formApi.js";
import { listFormsApi } from "../hooks/api/listFormsApi.js"; import { listFormsApi } from "../hooks/api/listFormsApi.js";
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.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 {user, setUser} = useContext(UserData);
const {forms, setForms} = useContext(FormsData); const {forms, setForms} = useContext(FormsData);
const {answersList, setAnswersList} = useContext(answersData);
const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData); const {listTypeAnswer, setListTypeAnswer} = useContext(TypeAnswerData);
const [cookies, _, __] = useCookies(["user"]); const [cookies, setCookies, __] = useCookies(["user"]);
const [questions, setQuestions] = useState([]); const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState([]); const [answers, setAnswers] = useState([]);
const [title, setTitle] = useState(""); // const [title, setTitle] = useState("");
useEffect(() => { useEffect(() => {
async function getForm() { async function getForm() {
const responseForms = await listFormsApi(cookies.token); // const responseForms = await listFormsApi(cookies.token);
const responseBlocks = await listFormBlockApi(cookies.token, formId); const responseBlocks = await listFormBlockByTokenApi(cookies.token, formId);
if (responseBlocks.status === 200 && responseForms.status === 200 && responseBlocks.data) { if (responseBlocks.status === 200 && responseBlocks.data) {
const listBlocks = responseDataToListBlock(responseBlocks.data); const listBlocks = responseDataToListBlock(responseBlocks.data.blocks);
setQuestions(listBlocks) setQuestions(listBlocks)
setAnswers(listBlocks.map(item => ( setAnswers(listBlocks.map(item => (
{id: item.id, answer: []} {id: item.id, answer: []}
))) )))
setTitle(responseForms.data.find(item => item.id === formId).title) // setTitle(responseForms.data.find(item => item.id === formId).title)
} }
else { else {
console.log(responseForms) // console.log(responseForms)
console.log(responseBlocks) console.log(responseBlocks)
} }
}; };
@ -54,17 +55,21 @@ const ViewForm = () => {
) )
}; };
function saveAnswers() { async function saveAnswers() {
// saveAnswersApi(formId, answers) const response = await saveAnswersApi(cookies.token, formId, answers);
// .then((resolve, _) => { console.log(response)
// console.log(resolve)
// setAnswers([]); if (response.status === 200) {
// navigate("/"); setAnswersList([...answersList, {
// }) id: formId,
// .catch((error) => console.log(error)); user: user.login,
answers: answers
}])
setAnswers([]); setAnswers([]);
navigate("/forms"); navigate("/forms");
} }
}
return ( return (
<div className={classes.main}> <div className={classes.main}>
@ -72,9 +77,6 @@ const ViewForm = () => {
<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}>
<span>{title}</span>
</div>
<div className={classes.form__header__id}> <div className={classes.form__header__id}>
<span>#{formId}</span> <span>#{formId}</span>
</div> </div>

View File

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

View File

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