ticket 16
All checks were successful
publish-main / release-image (push) Successful in 6m40s

This commit is contained in:
kuwsh1n 2024-06-23 21:05:43 +03:00
parent 86854956eb
commit 133ed782aa
10 changed files with 175 additions and 101 deletions

View File

@ -33,6 +33,8 @@
} }
} }
&__wrapper { &__wrapper {
width: 100%;
height: 100%;
&__header { &__header {
width: 100%; width: 100%;
height: 15%; height: 15%;
@ -53,9 +55,13 @@
width: 100%; width: 100%;
height: 20%; height: 20%;
border-bottom: 1px solid rgb(200, 200, 200); border-bottom: 1px solid rgb(200, 200, 200);
&__wrapper {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 95%;
height: 100%;
}
&__item { &__item {
font-size: 15px; font-size: 15px;
font-family: "Montserrat", sans-serif; font-family: "Montserrat", sans-serif;
@ -67,19 +73,30 @@
&__users { &__users {
width: 100%; width: 100%;
height: 80%; height: 80%;
margin-top: 10px; overflow-y: auto;
&::-webkit-scrollbar {
width: 7px;
}
&::-webkit-scrollbar-thumb {
background-color: rgb(200, 200, 200);
}
&__item { &__item {
width: 100%; width: 100%;
height: 20%; height: 20%;
border-bottom: 1px solid rgb(200, 200, 200);
position: relative;
&__wrapper {
width: 95%;
height: 100%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
border-bottom: 1px solid rgb(200, 200, 200); }
&__link { &__link {
font-size: 15px; font-size: 15px;
font-family: "Montserrat", sans-serif; font-family: "Montserrat", sans-serif;
color: rgb(70, 70, 70); color: rgb(70, 70, 70);
width: 33.3%; width: 20%;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
@ -91,9 +108,19 @@
font-size: 15px; font-size: 15px;
font-family: "Montserrat", sans-serif; font-family: "Montserrat", sans-serif;
color: rgb(100, 100, 100); color: rgb(100, 100, 100);
width: 33.3%; width: 20%;
text-align: center; text-align: center;
} }
&__remove {
position: absolute;
right: 2%;
cursor: pointer;
i {
&:hover {
color: rgb(199, 73, 73);
}
}
}
} }
} }
&__item { &__item {

View File

@ -10,9 +10,14 @@ const NavBar = ({navigate, auth, setAuth}) => {
<div className={classes.menu}> <div className={classes.menu}>
<div className={classes.menu__authorized}> <div className={classes.menu__authorized}>
<span onClick={() => navigate("/")}>Главная</span> <span onClick={() => navigate("/")}>Главная</span>
{auth ? {
auth.is_admin ? <span onClick={() => navigate("/forms")}>Мои формы</span> : <span></span> : auth ?
<span></span>} auth.is_admin ?
<><span onClick={() => navigate("/forms")}>Мои формы</span>
<span onClick={() => navigate("/admin")}>Админ панель</span></> :
<span></span> :
<span></span>
}
</div> </div>
</div> </div>
<div className={classes.profile}> <div className={classes.profile}>

View File

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

View File

@ -131,6 +131,7 @@ async function saveAnswersApi(token, formToken, data) {
"Authorization": `Token ${token}` "Authorization": `Token ${token}`
} }
}) })
console.log("saveAnswersApi", response)
return response return response
} }
catch (e) { catch (e) {

View File

@ -26,6 +26,7 @@ async function createFormApi(token) {
"Authorization": `Token ${token}`, "Authorization": `Token ${token}`,
} }
}) })
console.log("createFormApi", response)
return response return response
} }
catch (e) { catch (e) {
@ -67,7 +68,10 @@ 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`,
{
"name": "test"
},
{ {
headers: { headers: {
"Authorization": `Token ${token}` "Authorization": `Token ${token}`

View File

@ -18,8 +18,6 @@ async function editUserApi(token, data) {
"Authorization": `Token ${token}`, "Authorization": `Token ${token}`,
}, },
}) })
console.log(response)
return response return response
} }
catch(e) { catch(e) {
@ -29,22 +27,6 @@ async function editUserApi(token, data) {
}; };
// async function getListUserApi(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
// }
// };
async function getListUserApi(token) { async function getListUserApi(token) {
try { try {
const response = await axios.get(`https://api.minerva.krbl.ru/auth/manage/users`, const response = await axios.get(`https://api.minerva.krbl.ru/auth/manage/users`,
@ -83,10 +65,31 @@ async function addUserApi(token, data) {
catch (e) { catch (e) {
return e return e
} }
};
async function removeUserApi(token, login) {
try {
const response = await axios.post("https://api.minerva.krbl.ru/auth/manage/delete",
{
"login": login
},
{
headers: {
"Authorization": `Token ${token}`,
},
})
return response
}
catch(e) {
console.log(e)
return e
}
} }
export { export {
editUserApi, editUserApi,
getListUserApi, getListUserApi,
addUserApi addUserApi,
removeUserApi
} }

View File

@ -3,11 +3,12 @@ import { useCookies } from "react-cookie";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import classes from "../assets/styles/adminPanel.module.scss"; import classes from "../assets/styles/adminPanel.module.scss";
import { UserData } from "../context"; import { UserData } from "../context";
import { getListUserApi, editUserApi, addUserApi } from "../hooks/api/profileApi.js"; import { getListUserApi, editUserApi, addUserApi, removeUserApi } from "../hooks/api/profileApi.js";
import { verifyUser } from "../hooks/services/profile.js"; import { verifyUser } from "../hooks/services/profile.js";
import DefaultModal from "../components/DefaultModal.jsx"; import DefaultModal from "../components/DefaultModal.jsx";
import EditUserAdminPanel from "../components/bodyModal/EditUserAdminPanel.jsx"; import EditUserAdminPanel from "../components/bodyModal/EditUserAdminPanel.jsx";
import MyButton from "../components/MyButton.jsx"; import MyButton from "../components/MyButton.jsx";
import CheckModal from "../components/CheckModal.jsx";
const AdminPanel = () => { const AdminPanel = () => {
@ -106,13 +107,21 @@ const AdminPanel = () => {
setPhone(user.phone) setPhone(user.phone)
} }
async function removeUser(login) {
const response = await removeUserApi(cookies.token, login)
if (response.status === 200) {
setListUser(listUser.filter(item => item.login !== login))
}
}
return ( return (
<div className={classes.main}> <div className={classes.main}>
<div className={classes.wrapper}> <div className={classes.wrapper}>
<div className={classes.admin}> <div className={classes.admin}>
<div className={classes.admin__linkProfile}> {/* <div className={classes.admin__linkProfile}>
<span onClick={() => navigate("/profile")}>Профиль</span> <span onClick={() => navigate("/profile")}>Профиль</span>
</div> </div> */}
<div className={classes.admin__wrapper}> <div className={classes.admin__wrapper}>
<div className={classes.admin__wrapper__header}> <div className={classes.admin__wrapper__header}>
<h3>Пользователи</h3> <h3>Пользователи</h3>
@ -125,15 +134,18 @@ const AdminPanel = () => {
</div> </div>
<div className={classes.admin__wrapper__body}> <div className={classes.admin__wrapper__body}>
<div className={classes.admin__wrapper__body__columns}> <div className={classes.admin__wrapper__body__columns}>
<div className={classes.admin__wrapper__body__columns__wrapper}>
<div className={classes.admin__wrapper__body__columns__item}>Логин</div> <div className={classes.admin__wrapper__body__columns__item}>Логин</div>
<div className={classes.admin__wrapper__body__columns__item}>Фамилия</div> <div className={classes.admin__wrapper__body__columns__item}>Фамилия</div>
<div className={classes.admin__wrapper__body__columns__item}>Email</div> <div className={classes.admin__wrapper__body__columns__item}>Email</div>
<div className={classes.admin__wrapper__body__columns__item}>Учитель</div> <div className={classes.admin__wrapper__body__columns__item}>Учитель</div>
<div className={classes.admin__wrapper__body__columns__item}>Администратор</div> <div className={classes.admin__wrapper__body__columns__item}>Администратор</div>
</div> </div>
</div>
<div className={classes.admin__wrapper__body__users}> <div className={classes.admin__wrapper__body__users}>
{listUser.map(item => {listUser.map(item =>
<div className={classes.admin__wrapper__body__users__item} key={item.id}> <div className={classes.admin__wrapper__body__users__item} key={item.id}>
<div className={classes.admin__wrapper__body__users__item__wrapper}>
<div <div
className={classes.admin__wrapper__body__users__item__link} className={classes.admin__wrapper__body__users__item__link}
data-bs-toggle="modal" data-bs-target={`#adminModal`} data-bs-toggle="modal" data-bs-target={`#adminModal`}
@ -148,10 +160,29 @@ const AdminPanel = () => {
{item.email ? item.email : '-'} {item.email ? item.email : '-'}
</div> </div>
<div className={classes.admin__wrapper__body__users__item__info}> <div className={classes.admin__wrapper__body__users__item__info}>
{item.is_teacher ? 'Да' : 'Нет'} {
item.is_teacher ?
<i class="fa-solid fa-circle-check" style={{color: "rgb(150, 209, 158)"}}></i> :
<i class="fa-solid fa-circle-xmark" style={{color: "rgb(235, 130, 130)"}}></i>
}
</div> </div>
<div className={classes.admin__wrapper__body__users__item__info}> <div className={classes.admin__wrapper__body__users__item__info}>
{item.admin ? 'Да' : 'Нет'} {
item.admin ?
<i class="fa-solid fa-circle-check" style={{color: "rgb(150, 209, 158)"}}></i> :
<i class="fa-solid fa-circle-xmark" style={{color: "rgb(235, 130, 130)"}}></i>}
</div>
<div className={classes.admin__wrapper__body__users__item__remove}>
<i class="fa-solid fa-trash" data-bs-toggle="modal" data-bs-target={`#checkModal${item.id}`}></i>
</div>
<CheckModal
postfix={item.id}
message={`Вы хотетите удалить пользователя <${item.login}>?`}
action={{
execute: () => removeUser(item.login),
cancel: () => {}
}}
/>
</div> </div>
</div> </div>
)} )}

View File

@ -97,9 +97,9 @@ const Profile = () => {
<div className={classes.main}> <div className={classes.main}>
<div className={classes.wrapper}> <div className={classes.wrapper}>
<div className={classes.profile}> <div className={classes.profile}>
{user.is_admin ? <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></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>

View File

@ -18,6 +18,7 @@ const TokensForm = () => {
useEffect(() => { useEffect(() => {
async function listFormsByToken() { async function listFormsByToken() {
const response = await listFormsByTokenApi(cookies.token, formId) const response = await listFormsByTokenApi(cookies.token, formId)
console.log(response)
if (response.data.tokens) { if (response.data.tokens) {
setTokens(response.data.tokens.filter(item => item.is_active === true)) setTokens(response.data.tokens.filter(item => item.is_active === true))
@ -78,7 +79,7 @@ const TokensForm = () => {
По умолчанию По умолчанию
</div> </div>
<div className={classes.answers__wrapper__body__item__wrapper__token}> <div className={classes.answers__wrapper__body__item__wrapper__token}>
{item.form_id} {item.id}
</div> </div>
</div> </div>
<div className={classes.answers__wrapper__body__item__btn}> <div className={classes.answers__wrapper__body__item__btn}>

View File

@ -5,6 +5,7 @@ const protectedUrl = {
new RegExp("/profile"), new RegExp("/profile"),
new RegExp("/forms/\\w+/answers"), new RegExp("/forms/\\w+/answers"),
new RegExp("/tokens/\\w+"), new RegExp("/tokens/\\w+"),
new RegExp("/admin"),
], ],
Authorized: [ Authorized: [
"/enter" "/enter"
@ -14,6 +15,7 @@ const protectedUrl = {
new RegExp("/forms/\\w+/edit"), new RegExp("/forms/\\w+/edit"),
new RegExp("/forms/\\w+/answers"), new RegExp("/forms/\\w+/answers"),
new RegExp("/tokens/\\w+"), new RegExp("/tokens/\\w+"),
new RegExp("/admin"),
] ]
} }