fix tickets 4, 6, 15, 12
All checks were successful
publish-main / release-image (push) Successful in 6m44s
All checks were successful
publish-main / release-image (push) Successful in 6m44s
This commit is contained in:
parent
e3455e3e6d
commit
cdd43807f8
172
src/assets/styles/tokensForm.module.scss
Normal file
172
src/assets/styles/tokensForm.module.scss
Normal file
@ -0,0 +1,172 @@
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading__wrapper {
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&__body {
|
||||
// margin-top: 100px;
|
||||
span {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.answers {
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
box-shadow: 0 0 5px 1px rgb(200, 200, 200);
|
||||
padding: 1.5%;
|
||||
&__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 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&__header {
|
||||
width: 100%;
|
||||
height: 15%;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
h3 {
|
||||
font-size: 25px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
color: rgb(100, 100, 100);
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
&__body {
|
||||
width: 100%;
|
||||
height: 85%;
|
||||
overflow-y: auto;
|
||||
border-bottom: 1px solid rgb(200, 200, 200);
|
||||
&::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: rgb(200, 200, 200);
|
||||
}
|
||||
&__column {
|
||||
font-size: 15px;
|
||||
width: 100%;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
padding: 5px 30px 5px 5px;
|
||||
border-bottom: 1px solid rgb(200, 200, 200);
|
||||
&__wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
&__item {
|
||||
padding: 0 30px 0 5px;
|
||||
// border-bottom: 1px solid rgb(200, 200, 200);
|
||||
font-size: 15px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
background-color: rgba(230, 230, 230, 0.6);
|
||||
}
|
||||
&__wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
&__title {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&__token {
|
||||
|
||||
}
|
||||
}
|
||||
&__btn {
|
||||
width: 10%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: 0 5px;
|
||||
font-size: 13px;
|
||||
i {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
i:first-child:hover {
|
||||
color: rgb(42, 64, 187);
|
||||
}
|
||||
i:last-child:hover {
|
||||
color: rgb(199, 73, 73);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -33,10 +33,11 @@ async function addFormBlockApi(token, formId, data) {
|
||||
}
|
||||
};
|
||||
|
||||
async function updateBlockApi(token, formId, data) {
|
||||
async function updateBlockApi(token, formId, data, order) {
|
||||
try {
|
||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/set`,
|
||||
{
|
||||
order: order,
|
||||
data: data
|
||||
},
|
||||
{
|
||||
@ -51,6 +52,25 @@ async function updateBlockApi(token, formId, data) {
|
||||
}
|
||||
};
|
||||
|
||||
async function removeBlockApi(token, formId, order) {
|
||||
try {
|
||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/set`,
|
||||
{
|
||||
order: order,
|
||||
delete_flag: true
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"Authorization": `Token ${token}`,
|
||||
}
|
||||
})
|
||||
return response
|
||||
}
|
||||
catch (e) {
|
||||
return e
|
||||
}
|
||||
};
|
||||
|
||||
async function updateOrderBlockApi(token, formId, data) {
|
||||
try {
|
||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/moveTo`,
|
||||
@ -133,4 +153,4 @@ async function getAnswersApi(token, formToken) {
|
||||
}
|
||||
};
|
||||
|
||||
export { addFormBlockApi, listFormBlockApi, saveFormApi, updateBlockApi, updateOrderBlockApi, listFormBlockByTokenApi, saveAnswersApi, getAnswersApi }
|
||||
export { addFormBlockApi, listFormBlockApi, saveFormApi, updateBlockApi, updateOrderBlockApi, listFormBlockByTokenApi, saveAnswersApi, getAnswersApi, removeBlockApi }
|
@ -95,4 +95,22 @@ async function listFormsByTokenApi(token, formId) {
|
||||
}
|
||||
};
|
||||
|
||||
export { listFormsApi, createFormApi, removeFormApi, updateTitleFormApi, newFormTokenApi, listFormsByTokenApi };
|
||||
async function removeTokenFormApi(token, formId, formToken) {
|
||||
try {
|
||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/access/revoke`,
|
||||
{
|
||||
"token_id": formToken
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"Authorization": `Token ${token}`
|
||||
}
|
||||
})
|
||||
return response
|
||||
}
|
||||
catch (e) {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
export { listFormsApi, createFormApi, removeFormApi, updateTitleFormApi, newFormTokenApi, listFormsByTokenApi, removeTokenFormApi };
|
@ -119,6 +119,7 @@ const Forms = () => {
|
||||
<ul class="dropdown-menu" aria-labelledby="action">
|
||||
<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={() => navigate(`/tokens/${item.id}`)}>Список токенов</a></li>
|
||||
<li><a class="dropdown-item" onClick={() => copyLinkToFormView(item.id)}>Скопировать ссылку</a></li>
|
||||
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#checkModal" onClick={() => setCurrentRemoveForm({id: item.id, title: item.title})}>Удалить</a></li>
|
||||
</ul>
|
||||
|
@ -7,7 +7,7 @@ import AnswerModal from "../components/AnswerModal.jsx";
|
||||
import PreviewModal from "../components/PreviewModal.jsx"
|
||||
import { FormsData, TypeAnswerData } from "../context";
|
||||
import { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
|
||||
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi, updateOrderBlockApi } from "../hooks/api/formApi.js";
|
||||
import { saveFormApi, addFormBlockApi, listFormBlockApi, updateBlockApi, updateOrderBlockApi, removeBlockApi } from "../hooks/api/formApi.js";
|
||||
import { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
||||
import MyInput from "../components/MyInput.jsx";
|
||||
|
||||
@ -89,7 +89,7 @@ const NewForm = () => {
|
||||
setCurrentOptionAnswer("");
|
||||
};
|
||||
|
||||
function editAnswerByForm(id) {
|
||||
function editAnswerByForm(id, order) {
|
||||
const obj = listBlock.find(item => item.id === id);
|
||||
setQuestion(obj.question);
|
||||
setComment(obj.comment);
|
||||
@ -112,7 +112,12 @@ const NewForm = () => {
|
||||
typeAnswer: currentTypeAnswer,
|
||||
}
|
||||
|
||||
const response = await updateBlockApi(cookies.token, formId, data);
|
||||
const response = await updateBlockApi(
|
||||
cookies.token,
|
||||
formId,
|
||||
data,
|
||||
listBlock.find(item => item.id === stateModal).order
|
||||
);
|
||||
console.log(response)
|
||||
|
||||
if (response.status === 200) {
|
||||
@ -130,6 +135,17 @@ const NewForm = () => {
|
||||
cleanStates();
|
||||
};
|
||||
|
||||
async function removeBlock(order) {
|
||||
const response = await removeBlockApi(cookies.token, formId, order)
|
||||
|
||||
if (response.status === 200) {
|
||||
setListBlock([...listBlock.filter(item => item.order !== order)]);
|
||||
}
|
||||
else {
|
||||
console.log(response)
|
||||
}
|
||||
}
|
||||
|
||||
async function addFormBlock() {
|
||||
const newBlock = {
|
||||
question: question,
|
||||
@ -304,7 +320,7 @@ const NewForm = () => {
|
||||
</div>
|
||||
<div className={classes.content__newForm__list__item__btn}>
|
||||
<i class="fa-solid fa-pen" data-bs-toggle="modal" data-bs-target="#answerModal" onClick={() => {editAnswerByForm(item.id)}}></i>
|
||||
<i class="fa-solid fa-trash" onClick={() => removeAnswerByForm(item.id)}></i>
|
||||
<i class="fa-solid fa-trash" onClick={() => removeBlock(item.order)}></i>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
124
src/pages/TokensForm.jsx
Normal file
124
src/pages/TokensForm.jsx
Normal file
@ -0,0 +1,124 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useCookies } from "react-cookie";
|
||||
import classes from "../assets/styles/tokensForm.module.scss";
|
||||
import { listFormsByTokenApi, newFormTokenApi, removeTokenFormApi } from "../hooks/api/listFormsApi";
|
||||
import MyButton from "../components/MyButton.jsx";
|
||||
import MyInput from "../components/MyInput.jsx";
|
||||
import CheckModal from "../components/CheckModal.jsx";
|
||||
|
||||
const TokensForm = () => {
|
||||
const { formId } = useParams();
|
||||
const [tokens, setTokens] = useState([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [titleToken, setTitleToken] = useState('')
|
||||
|
||||
const [cookies, _, __] = useCookies(["user"]);
|
||||
|
||||
useEffect(() => {
|
||||
async function listFormsByToken() {
|
||||
const response = await listFormsByTokenApi(cookies.token, formId)
|
||||
|
||||
if (response.data.tokens) {
|
||||
setTokens(response.data.tokens.filter(item => item.is_active === true))
|
||||
setLoading(false)
|
||||
}
|
||||
else {
|
||||
console.log(response)
|
||||
}
|
||||
}
|
||||
|
||||
listFormsByToken()
|
||||
}, [])
|
||||
|
||||
async function newFormToken() {
|
||||
const response = await newFormTokenApi(cookies.token, formId)
|
||||
|
||||
if (response.status === 200) {
|
||||
setTokens([...tokens, response.data.token])
|
||||
}
|
||||
else {
|
||||
console.log(response)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeTokenForm(tokenForm) {
|
||||
const response = await removeTokenFormApi(cookies.token, formId, tokenForm)
|
||||
|
||||
if (response.status === 200) {
|
||||
setTokens(tokens.filter(item => item.id !== tokenForm))
|
||||
}
|
||||
else {
|
||||
console.log(response)
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
<MyButton text={"Создать"} class={"main__green"} click={newFormToken}/>
|
||||
</div>
|
||||
<div className={classes.answers__wrapper__body}>
|
||||
<div className={classes.answers__wrapper__body__column}>
|
||||
<div className={classes.answers__wrapper__body__column__wrapper}>
|
||||
<div>Название</div>
|
||||
<div>Токен</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{tokens ?
|
||||
tokens.map((item, i) =>
|
||||
<div className={classes.answers__wrapper__body__item} key={i}>
|
||||
<div className={classes.answers__wrapper__body__item__wrapper}>
|
||||
<div className={classes.answers__wrapper__body__item__wrapper__title}>
|
||||
По умолчанию
|
||||
</div>
|
||||
<div className={classes.answers__wrapper__body__item__wrapper__token}>
|
||||
{item.form_id}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.answers__wrapper__body__item__btn}>
|
||||
<i
|
||||
class="fa-solid fa-pen"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target={`#tokensModal${i}`}
|
||||
onClick={() => setTitleToken("По умолчанию")}>
|
||||
</i>
|
||||
<i class="fa-solid fa-trash" onClick={() => removeTokenForm(item.id)}></i>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade myModal" className={classes.myModal} id={`tokensModal${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}>
|
||||
<MyInput type={"text"} value={titleToken} change={setTitleToken}/>
|
||||
</div>
|
||||
<div class="modal-footer myModal__dialog__content__footer" className={classes.myModal__dialog__content__footer}>
|
||||
<MyButton text={"Сохранить"} class={"main__green"} dismiss={"modal"}/>
|
||||
<MyButton text={"Отмена"} class={"main__white"} dismiss={"modal"}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
:
|
||||
<div className={classes.loading__wrapper}>
|
||||
<div class="spinner-border text-dark" className={classes.loading__wrapper__body} role="status">
|
||||
<span class="visually-hidden">Загрузка...</span>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TokensForm;
|
@ -9,6 +9,7 @@ import Profile from "../pages/Profile.jsx";
|
||||
import ViewForm from "../pages/ViewForm.jsx";
|
||||
import AdminPanel from '../pages/AdminPanel.jsx';
|
||||
import AnswersForm from '../pages/AnswersForm.jsx';
|
||||
import TokensForm from '../pages/TokensForm.jsx';
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
@ -45,6 +46,10 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: "/forms/:formId/answers",
|
||||
element: <AnswersForm/>
|
||||
},
|
||||
{
|
||||
path: "/tokens/:formId",
|
||||
element: <TokensForm/>
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user