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 {
|
try {
|
||||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/set`,
|
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/set`,
|
||||||
{
|
{
|
||||||
|
order: order,
|
||||||
data: data
|
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) {
|
async function updateOrderBlockApi(token, formId, data) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`https://api.minerva.krbl.ru/formBuilder/edit/${formId}/moveTo`,
|
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">
|
<ul class="dropdown-menu" aria-labelledby="action">
|
||||||
<li><a class="dropdown-item" onClick={() => openFormView(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={() => 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" 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>
|
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#checkModal" onClick={() => setCurrentRemoveForm({id: item.id, title: item.title})}>Удалить</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -7,7 +7,7 @@ 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 { listFormsApi, updateTitleFormApi } from "../hooks/api/listFormsApi.js";
|
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 { responseDataToListBlock } from "../hooks/sundry/parseListBlock.js";
|
||||||
import MyInput from "../components/MyInput.jsx";
|
import MyInput from "../components/MyInput.jsx";
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ const NewForm = () => {
|
|||||||
setCurrentOptionAnswer("");
|
setCurrentOptionAnswer("");
|
||||||
};
|
};
|
||||||
|
|
||||||
function editAnswerByForm(id) {
|
function editAnswerByForm(id, order) {
|
||||||
const obj = listBlock.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);
|
||||||
@ -112,7 +112,12 @@ const NewForm = () => {
|
|||||||
typeAnswer: currentTypeAnswer,
|
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)
|
console.log(response)
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
@ -130,6 +135,17 @@ const NewForm = () => {
|
|||||||
cleanStates();
|
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() {
|
async function addFormBlock() {
|
||||||
const newBlock = {
|
const newBlock = {
|
||||||
question: question,
|
question: question,
|
||||||
@ -304,7 +320,7 @@ const NewForm = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className={classes.content__newForm__list__item__btn}>
|
<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-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>
|
||||||
</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 ViewForm from "../pages/ViewForm.jsx";
|
||||||
import AdminPanel from '../pages/AdminPanel.jsx';
|
import AdminPanel from '../pages/AdminPanel.jsx';
|
||||||
import AnswersForm from '../pages/AnswersForm.jsx';
|
import AnswersForm from '../pages/AnswersForm.jsx';
|
||||||
|
import TokensForm from '../pages/TokensForm.jsx';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@ -45,6 +46,10 @@ const router = createBrowserRouter([
|
|||||||
{
|
{
|
||||||
path: "/forms/:formId/answers",
|
path: "/forms/:formId/answers",
|
||||||
element: <AnswersForm/>
|
element: <AnswersForm/>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/tokens/:formId",
|
||||||
|
element: <TokensForm/>
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user