41 files changed
+779
-314
No files matched your search
+4
-2
@@ -25,8 +25,9 @@ import { PartnerSettings } from "./pages/PartnerSettings/PartnerSettings"
|
||||
import {PartnerRequests} from './pages/PartnerRequests/PartnerRequests'
|
||||
import {PartnerAddRequest} from './pages/PartnerAddRequest/PartnerAddRequest'
|
||||
import {PartnerBid} from './pages/PartnerBid/PartnerBid'
|
||||
import {PartnerPersonalInfo} from "./pages/PartnerPersonalInfo/PartnerPersonalInfo";
|
||||
import {PartnerCategories} from "./pages/PartnerСategories/PartnerСategories";
|
||||
import {PartnerTreaties} from "./pages/PartnerTreaties/PartnerTreaties";
|
||||
import {PartnerEmployees} from "./pages/PartnerEmployees/PartnerEmployees";
|
||||
|
||||
import './fonts/stylesheet.css'
|
||||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
@@ -71,8 +72,9 @@ const App = () => {
|
||||
<Route exact path='requests' element={<PartnerRequests/>}/>
|
||||
<Route exact path='add-request' element={<PartnerAddRequest/>}/>
|
||||
<Route exact path='bid' element={<PartnerBid/>}/>
|
||||
<Route exact path='employees' element={<PartnerPersonalInfo/>}/>
|
||||
<Route exact path='categories' element={<PartnerCategories/>}/>
|
||||
<Route exact path='treaties' element={<PartnerTreaties/>}/>
|
||||
<Route exact path='categories/employees' element={<PartnerEmployees/>}/>
|
||||
</Route>
|
||||
|
||||
<Route path="*" element={<Navigate to="/profile" replace/>}/>
|
||||
|
||||
@@ -3,24 +3,20 @@ import { Link, useNavigate } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { Loader } from "../Loader/Loader";
|
||||
import ErrorBoundary from "../../hoc/ErrorBoundary";
|
||||
|
||||
import { auth, selectAuth, setUserInfo } from "../../redux/outstaffingSlice";
|
||||
import { loading } from "../../redux/loaderSlice";
|
||||
import { setRole } from "../../redux/roleSlice";
|
||||
import { selectIsLoading } from "../../redux/loaderSlice";
|
||||
|
||||
import ModalErrorLogin from "../../components/UI/ModalErrorLogin/ModalErrorLogin";
|
||||
|
||||
import { apiRequest } from "../../api/request";
|
||||
|
||||
import ellipse from "../../images/ellipse.png";
|
||||
|
||||
import "./authBox.scss";
|
||||
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
|
||||
const SweetAlert = withReactContent(Swal);
|
||||
|
||||
export const AuthBox = ({ title }) => {
|
||||
const dispatch = useDispatch();
|
||||
const ref = useRef();
|
||||
@@ -30,15 +26,7 @@ export const AuthBox = ({ title }) => {
|
||||
const isLoading = useSelector(selectIsLoading);
|
||||
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const handleModalError = (error) => {
|
||||
SweetAlert.fire({
|
||||
title: "Ошибка",
|
||||
text: error,
|
||||
});
|
||||
|
||||
setError(null);
|
||||
};
|
||||
const [modalError, setModalError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!localStorage.getItem("auth_token")) {
|
||||
@@ -62,6 +50,7 @@ export const AuthBox = ({ title }) => {
|
||||
}).then((res) => {
|
||||
if (!res.access_token) {
|
||||
setError("Некорректные данные для входа");
|
||||
setModalError(true);
|
||||
dispatch(loading(false));
|
||||
} else {
|
||||
localStorage.setItem("auth_token", res.access_token);
|
||||
@@ -104,15 +93,11 @@ export const AuthBox = ({ title }) => {
|
||||
|
||||
{error && (
|
||||
<div className="auth-box__form-error">
|
||||
<ErrorBoundary>
|
||||
{handleModalError(error)}
|
||||
{/*<SweetAlert*/}
|
||||
{/* show={!!error}*/}
|
||||
{/* title='Ошибка'*/}
|
||||
{/* text={error}*/}
|
||||
{/* onConfirm={() => setError(null)}*/}
|
||||
{/*/>*/}
|
||||
</ErrorBoundary>
|
||||
<ModalErrorLogin
|
||||
active={modalError}
|
||||
setActive={setModalError}
|
||||
title={error}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -130,7 +115,9 @@ export const AuthBox = ({ title }) => {
|
||||
{/* TODO: при клике отправлять на форму/модалку/страницу регистрации */}
|
||||
<button
|
||||
className="auth-box__form-btn--role auth-box__auth-link"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
Регистрация
|
||||
</button>
|
||||
|
||||
@@ -150,11 +150,11 @@
|
||||
width: 268px;
|
||||
height: 75px;
|
||||
border-radius: 38px;
|
||||
background-color: #ffffff;
|
||||
background-color: #f5f5f5;
|
||||
border: 2px solid #6aaf5c;
|
||||
font-family: "Muller";
|
||||
font-size: 2em;
|
||||
font-weight: 300;
|
||||
font-weight: 400;
|
||||
letter-spacing: normal;
|
||||
line-height: 71.88px;
|
||||
text-align: center;
|
||||
|
||||
@@ -8,7 +8,9 @@ export const AuthHeader = ({}) => {
|
||||
return (
|
||||
<div className="auth-header">
|
||||
<div className="auth-header__logo">
|
||||
<h3>itguild.</h3>
|
||||
<h3>
|
||||
itguild.<span>аутстафинг ИТ специалистов</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="auth-header__navigation">
|
||||
<div className="container">
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
line-height: 32px;
|
||||
color: #000000;
|
||||
}
|
||||
span {
|
||||
color: #52b709;
|
||||
}
|
||||
}
|
||||
|
||||
&__navigation {
|
||||
|
||||
@@ -46,12 +46,16 @@ export const ProfileHeader = () => {
|
||||
},
|
||||
],
|
||||
partner: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Каталог'
|
||||
},
|
||||
{
|
||||
path: '/requests',
|
||||
name: 'Запросы'
|
||||
},
|
||||
{
|
||||
path: '/employees',
|
||||
path: '/categories',
|
||||
name: 'Персонал'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.auth-menu {
|
||||
z-index: 99;
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 141px;
|
||||
|
||||
@@ -46,14 +46,16 @@
|
||||
margin-left: 15px;
|
||||
|
||||
img {
|
||||
margin-right: 33px;
|
||||
margin-right: 20px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
color: black;
|
||||
width: 198px;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
&__resume {
|
||||
@@ -66,40 +68,54 @@
|
||||
line-height: 32px;
|
||||
color: white;
|
||||
border: none;
|
||||
transition: 0.5s;
|
||||
|
||||
&:hover {
|
||||
transition: 0.5s;
|
||||
background-color: #52b709a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slick-next {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #8dc63f;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 44px;
|
||||
|
||||
&:before {
|
||||
content: ">";
|
||||
color: white;
|
||||
font-size: 23px;
|
||||
content: url("../../images/arrowViewReport.svg");
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: #8dc63f;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
background-color: #8ec63f91;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-prev {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #8dc63f;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 44px;
|
||||
|
||||
&:before {
|
||||
content: "<";
|
||||
color: white;
|
||||
font-size: 23px;
|
||||
content: url("../../images/ArrovLeftSlider.png");
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: #8dc63f;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
background-color: #8ec63f91;
|
||||
}
|
||||
@@ -128,7 +144,6 @@
|
||||
|
||||
img {
|
||||
margin: 0;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -136,7 +151,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.worker-description {
|
||||
&-description {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import React, { useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { setProject } from "../../../redux/projectsTrackerSlice";
|
||||
|
||||
import "./ModalCreate.scss";
|
||||
|
||||
export const ModalCreate = ({ active, setActive, title }) => {
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const dispatch = useDispatch();
|
||||
|
||||
function createName() {
|
||||
let newItem = {
|
||||
name: inputValue,
|
||||
count: 0,
|
||||
};
|
||||
dispatch(setProject(newItem));
|
||||
setActive(false);
|
||||
setInputValue("")
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={active ? "modal-project active" : "modal-project"}
|
||||
onClick={() => setActive(false)}
|
||||
>
|
||||
<div
|
||||
className="modal-project__content"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="title-project">
|
||||
<h4>{title}</h4>
|
||||
<div className="input-container">
|
||||
<input
|
||||
className="name-project"
|
||||
value={inputValue}
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
</div>
|
||||
<button className="create-project" onClick={createName}>
|
||||
Создать
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalCreate;
|
||||
@@ -0,0 +1,71 @@
|
||||
.modal-project {
|
||||
z-index: 9;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.11);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: scale(0);
|
||||
|
||||
&__content {
|
||||
padding: 15px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dde2e4;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title-project {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.input-container {
|
||||
width: 220px;
|
||||
height: 25px;
|
||||
border-radius: 44px;
|
||||
border: 1px solid #d1d1d1;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #111112;
|
||||
margin-bottom: 10px;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.name-project {
|
||||
margin-left: 10px;
|
||||
border: none;
|
||||
outline: none;
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.create-project {
|
||||
margin: 15px 0 0 0;
|
||||
width: 188px;
|
||||
height: 40px;
|
||||
background: #52b709;
|
||||
border-radius: 44px;
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
line-height: 32px;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-project.active {
|
||||
transform: scale(1);
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import React from "react";
|
||||
|
||||
import "./modalErrorLogin.scss";
|
||||
|
||||
export const ModalErrorLogin = ({ active, setActive }) => {
|
||||
export const ModalErrorLogin = ({ active, setActive, title }) => {
|
||||
return (
|
||||
<div
|
||||
className={active ? "modal-error active" : "modal-error"}
|
||||
@@ -13,8 +13,14 @@ export const ModalErrorLogin = ({ active, setActive }) => {
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h2>Ошибка входа</h2>
|
||||
<p>Введены некоректные данные для входа</p>
|
||||
<button className="modal-error__content-button">
|
||||
<p>{title}</p>
|
||||
<button
|
||||
className="modal-error__content-button"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setActive(false);
|
||||
}}
|
||||
>
|
||||
Попробовать еще раз
|
||||
</button>
|
||||
<span onClick={() => setActive(false)}></span>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
import "./ModalProject.scss";
|
||||
|
||||
export const ModalProject = ({ active, setActive }) => {
|
||||
return (
|
||||
<div
|
||||
className={active ? "modal-project active" : "modal-project"}
|
||||
onClick={() => setActive(false)}
|
||||
>
|
||||
<div
|
||||
className="modal-project__content"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="title-project">
|
||||
<h4>Укажите название проекта: </h4>
|
||||
<div className="input-container">
|
||||
<input className="name-project"></input>
|
||||
</div>
|
||||
</div>
|
||||
<button className="create-project">Создать</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalProject;
|
||||
@@ -1,57 +0,0 @@
|
||||
.modal-project {
|
||||
z-index: 9;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.11);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
.modal-project.active {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.modal-project__content {
|
||||
padding: 15px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dde2e4;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.title-project {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.input-container {
|
||||
width: 220px;
|
||||
height: 25px;
|
||||
border-radius: 44px;
|
||||
border: 1px solid #d1d1d1;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.name-project {
|
||||
margin-left: 10px;
|
||||
border: none;
|
||||
outline: none;
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.create-project {
|
||||
margin: 15px 0 0 0;
|
||||
}
|
||||
}
|
||||
@@ -40,14 +40,6 @@ export const ModalTiket = ({ active, setActive }) => {
|
||||
className="modal-tiket__content"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="author">
|
||||
<a href="#">
|
||||
<img src={creatorMock}></img>
|
||||
</a>
|
||||
<a href="#">
|
||||
<img src={creatorMock}></img>
|
||||
</a>
|
||||
</div>
|
||||
<div className="content">
|
||||
<h3 className="title-project">
|
||||
<img src={category} className="title-project__category"></img>
|
||||
@@ -75,6 +67,7 @@ export const ModalTiket = ({ active, setActive }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="workers">
|
||||
<span className="exit" onClick={() => setActive(false)}></span>
|
||||
<span>{tiket.code}</span>
|
||||
<p className="workers__creator">Создатель : {tiket.creator}</p>
|
||||
<div>
|
||||
|
||||
@@ -23,20 +23,6 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.author {
|
||||
padding: 25px 0 0 0;
|
||||
border-radius: 8px 0 0 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 76px;
|
||||
background: #fbfbfb;
|
||||
|
||||
a {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -109,10 +95,34 @@
|
||||
}
|
||||
|
||||
.workers {
|
||||
position: relative;
|
||||
border-left: 1px solid #f1f1f1;
|
||||
width: 300px;
|
||||
padding: 40px;
|
||||
|
||||
.exit {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 31px;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
background: #263238;
|
||||
}
|
||||
|
||||
&:before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
&:after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-family: "Inter", sans-serif;
|
||||
font-weight: 500;
|
||||
@@ -149,6 +159,7 @@
|
||||
}
|
||||
|
||||
.start {
|
||||
font-size: 12px;
|
||||
margin-top: 25px;
|
||||
width: 151px;
|
||||
height: 40px;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 614 B |
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { AuthBox } from "../../components/AuthBox/AuthBox";
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.auth-developers {
|
||||
font-family: "LabGrotesque", sans-serif;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
@@ -200,7 +201,7 @@
|
||||
&__partnersForDev {
|
||||
background: #52b7098c;
|
||||
color: #2d6505;
|
||||
margin-left: -40px;
|
||||
margin-left: -35px;
|
||||
}
|
||||
|
||||
&__partnersForDev,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
.auth-partners {
|
||||
font-family: "LabGrotesque", sans-serif;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
@@ -302,7 +303,7 @@
|
||||
&__partnersForPart {
|
||||
background: #406128;
|
||||
color: white;
|
||||
margin-left: -40px;
|
||||
margin-left: -35px;
|
||||
}
|
||||
|
||||
&__partnersForPart,
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import {Link, Navigate} from "react-router-dom";
|
||||
import {useSelector} from "react-redux";
|
||||
import {getPartnerEmployees} from "../../redux/outstaffingSlice";
|
||||
|
||||
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
||||
import {Footer} from "../../components/Footer/Footer";
|
||||
|
||||
import imgInfo from "./emplInfo.png"
|
||||
import rightArrow from "../../images/arrowRight.png"
|
||||
|
||||
import "./partnerEmployees.scss"
|
||||
|
||||
export const PartnerEmployees = () => {
|
||||
const partnerEmployees = useSelector(getPartnerEmployees);
|
||||
if(localStorage.getItem('role_status') !== '18' || !partnerEmployees.length) {
|
||||
return <Navigate to="/profile/categories" replace/>
|
||||
}
|
||||
return(
|
||||
<div className="partnerEmployees">
|
||||
<ProfileHeader />
|
||||
<div className="container">
|
||||
<ProfileBreadcrumbs links={[
|
||||
{name: 'Главная', link: '/profile'},
|
||||
{name: 'Данные моего персонала', link: '/profile/categories'},
|
||||
{name: 'Backend разработчики', link: '/profile/categories/employees'},
|
||||
]}
|
||||
/>
|
||||
<h2 className="partnerEmployees__title">Backend разработчики</h2>
|
||||
<div className="partnerEmployees__items">
|
||||
{partnerEmployees.map((person) => {
|
||||
return <div className="partnerEmployees__item" key={person.id}>
|
||||
<div className="partnerEmployees__item__name">
|
||||
<img src={person.personAvatar} alt="avatar" />
|
||||
<h4>{person.name}</h4>
|
||||
</div>
|
||||
<div className="partnerEmployees__item__info">
|
||||
<div className="partnerEmployees__item__info__qualification">
|
||||
<h5>{person.qualification}</h5>
|
||||
<span>{person.level}</span>
|
||||
<div className="info_summary">
|
||||
<img src={imgInfo} alt="img" />
|
||||
<p>Данные и резюме</p>
|
||||
<div className="arrow">
|
||||
<img src={rightArrow} alt="arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="partnerEmployees__item__info__project">
|
||||
<span className="name">Проект:</span>
|
||||
<h5>{person.project}</h5>
|
||||
<div className="partnerEmployees__item__info__project__details">
|
||||
<div className="details__item">
|
||||
<p>Открытые задачи</p>
|
||||
<span className="count">{person.tasks_in_progress}</span>
|
||||
</div>
|
||||
<div className="details__item">
|
||||
<p>Отработанных часов в <span>марте</span></p>
|
||||
<span className="count">{person.month_hours}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 596 B |
@@ -0,0 +1,170 @@
|
||||
.partnerEmployees {
|
||||
background: #F1F1F1;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
font-family: 'LabGrotesque', sans-serif;
|
||||
|
||||
&__title {
|
||||
color: #000000;
|
||||
font-weight: 700;
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
&__items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 20px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
background: #E1FCCF;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
&__name {
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
padding: 25px 22px 25px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 274px;
|
||||
width: 100%;
|
||||
|
||||
img {
|
||||
width: 77px;
|
||||
height: 77px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-left: 13px;
|
||||
margin-bottom: 0;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
max-width: 96px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
padding: 15px 50px 14px 16px;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
|
||||
&__qualification {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
h5 {
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #6F6F6F;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info_summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #000000;
|
||||
margin: 0 18px 0 10px;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50px;
|
||||
width: 41px;
|
||||
height: 41px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__project {
|
||||
.name {
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #111112;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-bottom: 0;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #111112;
|
||||
}
|
||||
|
||||
&__details {
|
||||
display: flex;
|
||||
margin-top: 24px;
|
||||
column-gap: 25px;
|
||||
|
||||
.details__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
color: #6F6F6F;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
line-height: 24px;
|
||||
|
||||
span {
|
||||
color: #406128;
|
||||
font-weight: 700;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 8px;
|
||||
padding: 0 6px;
|
||||
background: #DDDDDD;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
color: #6F6F6F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.container {
|
||||
max-width: 1160px;
|
||||
margin-top: 23px;
|
||||
|
||||
@media (max-width: 570px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 70px;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export const PartnerSettings = () => {
|
||||
<ProfileBreadcrumbs
|
||||
links={[
|
||||
{ name: "Главная", link: "/profile" },
|
||||
{ name: "Данные моего персонала", link: "/profile/employees" },
|
||||
{ name: "Настройка профиля", link: "/profile/settings" },
|
||||
]}
|
||||
/>
|
||||
<div className="partner-settings">
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
min-height: 100vh;
|
||||
font-family: 'LabGrotesque', sans-serif;
|
||||
|
||||
.infoPersonal__title {
|
||||
color: #000000;
|
||||
font-weight: 700;
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&__page {
|
||||
max-width: 1160px !important;
|
||||
margin-top: 23px;
|
||||
|
||||
+58
-18
@@ -1,10 +1,14 @@
|
||||
import React, {useState} from 'react';
|
||||
import {Link} from "react-router-dom";
|
||||
import {Navigate} from "react-router-dom";
|
||||
import {useDispatch} from "react-redux";
|
||||
|
||||
import {ProfileHeader} from "../../components/ProfileHeader/ProfileHeader";
|
||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"
|
||||
import {Footer} from "../../components/Footer/Footer";
|
||||
|
||||
import {setPartnerEmployees} from "../../redux/outstaffingSlice";
|
||||
|
||||
import BackEndImg from "./images/personalBackEnd.png"
|
||||
import FrontendImg from "./images/PersonalFrontend.png"
|
||||
import ArchitectureImg from "./images/PersonalArchitecture.png"
|
||||
@@ -15,12 +19,12 @@ import ManageImg from "./images/PersonalMng.png"
|
||||
import CopyImg from "./images/PersonalCopy.png"
|
||||
import SmmImg from "./images/PersonalSMM.png"
|
||||
import rightArrow from "../../images/arrowRight.png"
|
||||
import avatarImg from "../PartnerEmployees/avatarMok.png";
|
||||
|
||||
import {Navigate} from "react-router-dom";
|
||||
import "./partnerСategories.scss"
|
||||
|
||||
import "./parthnerPersonalInfo.scss"
|
||||
|
||||
export const PartnerPersonalInfo = () => {
|
||||
export const PartnerCategories = () => {
|
||||
const dispatch = useDispatch();
|
||||
if(localStorage.getItem('role_status') !== '18') {
|
||||
return <Navigate to="/profile" replace/>
|
||||
}
|
||||
@@ -28,81 +32,117 @@ export const PartnerPersonalInfo = () => {
|
||||
const [personalInfoItems] = useState([
|
||||
{
|
||||
title: 'Backend разработчики',
|
||||
link: '/profile',
|
||||
link: '/profile/categories/employees',
|
||||
description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript',
|
||||
available: true,
|
||||
img: BackEndImg
|
||||
},
|
||||
{
|
||||
title: 'Frontend разработчики',
|
||||
link: '/profile',
|
||||
link: '/profile/categories/employees',
|
||||
description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript',
|
||||
available: true,
|
||||
img: FrontendImg
|
||||
},
|
||||
{
|
||||
title: 'Архитектура проектов',
|
||||
link: '/profile',
|
||||
link: '/profile/categories/employees',
|
||||
description: 'Потоки данных ER ERP CRM CQRS UML BPMN',
|
||||
available: true,
|
||||
img: ArchitectureImg
|
||||
},
|
||||
{
|
||||
title: 'Дизайн проектов',
|
||||
link: '/profile',
|
||||
link: '/profile/categories/employees',
|
||||
description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript',
|
||||
available: true,
|
||||
img: DesignImg
|
||||
},
|
||||
{
|
||||
title: 'Тестирование проектов',
|
||||
link: '/profile',
|
||||
link: '/profile/add-request',
|
||||
description: 'SQL Postman TestRail Kibana Ручное тестирование',
|
||||
available: false,
|
||||
img: TestImg
|
||||
},
|
||||
{
|
||||
title: 'Администрирование проектов',
|
||||
link: '/profile',
|
||||
link: '/profile/add-request',
|
||||
description: 'DevOps ELK Kubernetes Docker Bash Apache Oracle Git',
|
||||
available: false,
|
||||
img: AdminImg
|
||||
},
|
||||
{
|
||||
title: 'Управление проектом',
|
||||
link: '/profile',
|
||||
link: '/profile/add-request',
|
||||
description: 'Scrum Kanban Agile Miro CustDev',
|
||||
available: false,
|
||||
img: ManageImg
|
||||
},
|
||||
{
|
||||
title: 'Копирайтинг проектов',
|
||||
link: '/profile',
|
||||
link: '/profile/add-request',
|
||||
description: 'Теги Заголовок H1 Дескриптор Абзац Сценарий',
|
||||
available: false,
|
||||
img: CopyImg
|
||||
},
|
||||
{
|
||||
title: 'Реклама и SMM',
|
||||
link: '/profile',
|
||||
link: '/profile/add-request',
|
||||
description: 'Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript',
|
||||
available: false,
|
||||
img: SmmImg
|
||||
},
|
||||
])
|
||||
|
||||
const [mokPersons] = useState([
|
||||
{
|
||||
personAvatar: avatarImg,
|
||||
name: "Макаренко Дмитрий",
|
||||
qualification: "PHP Backend - разработчик",
|
||||
level: "Middle",
|
||||
project: "Админка НВД Консалтинг",
|
||||
tasks_in_progress: 5,
|
||||
month_hours: 140,
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
personAvatar: avatarImg,
|
||||
name: "Макаренко Дмитрий",
|
||||
qualification: "PHP Backend - разработчик",
|
||||
level: "Middle",
|
||||
project: "Админка НВД Консалтинг",
|
||||
tasks_in_progress: 5,
|
||||
month_hours: 140,
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
personAvatar: avatarImg,
|
||||
name: "Макаренко Дмитрий",
|
||||
qualification: "PHP Backend - разработчик",
|
||||
level: "Middle",
|
||||
project: "Админка НВД Консалтинг",
|
||||
tasks_in_progress: 5,
|
||||
month_hours: 140,
|
||||
id: 3
|
||||
},
|
||||
])
|
||||
return (
|
||||
<div className="personalInfo">
|
||||
<div className="partnerCategories">
|
||||
<ProfileHeader />
|
||||
<div className="container">
|
||||
<ProfileBreadcrumbs links={[
|
||||
{name: 'Главная', link: '/profile'},
|
||||
{name: 'Данные моего персонала', link: '/profile/employees'},
|
||||
{name: 'Данные моего персонала', link: '/profile/categories'},
|
||||
]}
|
||||
/>
|
||||
<h2 className="personalInfo__title">Данные персонала</h2>
|
||||
<div className="personalInfo__items">
|
||||
<h2 className="partnerCategories__title">Данные персонала</h2>
|
||||
<div className="partnerCategories__items">
|
||||
{personalInfoItems.map((item, index) => {
|
||||
return <Link to={item.link} key={index} className={item.available ? "personalInfo__item item" : "personalInfo__item item item__disable"}>
|
||||
return <Link to={item.link} key={index} className={item.available ? "partnerCategories__item item" : "partnerCategories__item item item__disable"}
|
||||
onClick={() => {
|
||||
dispatch(setPartnerEmployees(mokPersons))
|
||||
}}>
|
||||
<div className="item__title">
|
||||
<img src={item.img} alt={item.title} />
|
||||
<h4>{item.title}</h4>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+4
-4
@@ -1,4 +1,4 @@
|
||||
.personalInfo {
|
||||
.partnerCategories {
|
||||
background: #F1F1F1;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
&__title {
|
||||
color: #000000;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
line-height: 22px;
|
||||
font-weight: 700;
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&__items {
|
||||
@@ -65,7 +65,7 @@ export const Profile = () => {
|
||||
description: '<span>У вас 2 вакансии<br/></span>открытые от лица компании'
|
||||
},
|
||||
{
|
||||
path: '/employees',
|
||||
path: '/categories',
|
||||
img: summaryIcon,
|
||||
title: 'Данные персонала',
|
||||
description: 'Наши специалисты <br/><span>уже работающие у вас</span>'
|
||||
|
||||
+195
-121
@@ -1,10 +1,11 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader";
|
||||
import {ProfileBreadcrumbs} from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||
import { Footer } from "../../components/Footer/Footer";
|
||||
|
||||
import ModalTiket from "../../components/UI/ModalTiket/ModalTiket";
|
||||
import ModalProject from "../../components/UI/ModalProject/ModalProject";
|
||||
import ModalCreate from "../../components/UI/ModalCreate/ModalCreate";
|
||||
|
||||
import project from "../../images/trackerProject.svg";
|
||||
import tasks from "../../images/trackerTasks.svg";
|
||||
@@ -13,26 +14,28 @@ import avatarTest from "../../images/AvatarTest .png";
|
||||
import selectArrow from "../../images/select.svg";
|
||||
import commentsBoard from "../../images/commentsBoard.svg";
|
||||
import filesBoard from "../../images/filesBoard.svg";
|
||||
import search from "../../images/search.svg"
|
||||
import search from "../../images/search.svg";
|
||||
|
||||
import "./tracker.scss";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { getProjects } from "../../redux/projectsTrackerSlice";
|
||||
|
||||
export const Tracker = () => {
|
||||
const [toggleTab, setToggleTab] = useState(1);
|
||||
const [projects] = useState([
|
||||
{
|
||||
name: "Разработка трекера",
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
name: "Кинотеатр",
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
name: "Проект страхование",
|
||||
count: 4,
|
||||
},
|
||||
]);
|
||||
// const [projects] = useState([
|
||||
// {
|
||||
// name: "Разработка трекера",
|
||||
// count: 4,
|
||||
// },
|
||||
// {
|
||||
// name: "Кинотеатр",
|
||||
// count: 4,
|
||||
// },
|
||||
// {
|
||||
// name: "Проект страхование",
|
||||
// count: 4,
|
||||
// },
|
||||
// ]);
|
||||
const [tabTaskMok, setTabTaskMok] = useState([
|
||||
{
|
||||
name: "Открытые",
|
||||
@@ -45,7 +48,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 1
|
||||
id: 1,
|
||||
},
|
||||
{
|
||||
task: "PR - 2245",
|
||||
@@ -54,7 +57,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 2
|
||||
id: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -69,7 +72,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 3
|
||||
id: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -84,7 +87,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 4
|
||||
id: 4,
|
||||
},
|
||||
{
|
||||
task: "PR - 2245",
|
||||
@@ -93,7 +96,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 5
|
||||
id: 5,
|
||||
},
|
||||
{
|
||||
task: "PR - 2245",
|
||||
@@ -102,7 +105,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 6
|
||||
id: 6,
|
||||
},
|
||||
{
|
||||
task: "PR - 2245",
|
||||
@@ -111,7 +114,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 9
|
||||
id: 9,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -126,7 +129,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 7
|
||||
id: 7,
|
||||
},
|
||||
{
|
||||
task: "PR - 2245",
|
||||
@@ -135,7 +138,7 @@ export const Tracker = () => {
|
||||
files: 0,
|
||||
avatarCreated: avatarTest,
|
||||
avatarDo: avatarTest,
|
||||
id: 8
|
||||
id: 8,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -145,184 +148,217 @@ export const Tracker = () => {
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PR - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PK - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PE - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PA - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PB - 2245",
|
||||
description: "Верстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PC - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PD - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
{
|
||||
name: "PA - 2245",
|
||||
description: "Сверстать часть таблицы. Сверстать часть таблицы",
|
||||
dateComplete: '07/мар/23',
|
||||
dateComplete: "07/мар/23",
|
||||
avatarDo: avatarTest,
|
||||
},
|
||||
])
|
||||
]);
|
||||
|
||||
const [filterCompleteTasks, setFilterCompleteTasks] = useState(completeTasks)
|
||||
const [filterCompleteTasks, setFilterCompleteTasks] = useState(completeTasks);
|
||||
|
||||
const [modalActiveTicket, setModalActiveTicket] = useState(false);
|
||||
const [modalActiveProject, setModalActiveProject] = useState(false);
|
||||
const [startWrapperIndex, setStartWrapperIndex] = useState(null)
|
||||
const [wrapperHover, setWrapperHover] = useState([false, false, false, false])
|
||||
const [modalCreateProject, setModalCreateProject] = useState(false);
|
||||
const [modalCreateColl, setModalCreateColl] = useState(false);
|
||||
|
||||
const [startWrapperIndex, setStartWrapperIndex] = useState(null);
|
||||
const [wrapperHover, setWrapperHover] = useState([
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
]);
|
||||
|
||||
const projects = useSelector(getProjects);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const toggleTabs = (index) => {
|
||||
setToggleTab(index);
|
||||
};
|
||||
|
||||
function toggleMoreTasks (wrapperIndex) {
|
||||
setTabTaskMok(prevArray => prevArray.map((elem, index) => {
|
||||
if (wrapperIndex === index) {
|
||||
return {...elem, open: !elem.open}
|
||||
} else {
|
||||
return elem
|
||||
}
|
||||
}))
|
||||
function toggleMoreTasks(wrapperIndex) {
|
||||
setTabTaskMok((prevArray) =>
|
||||
prevArray.map((elem, index) => {
|
||||
if (wrapperIndex === index) {
|
||||
return { ...elem, open: !elem.open };
|
||||
} else {
|
||||
return elem;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function dragStartHandler(e, task, wrapperIndex) {
|
||||
setStartWrapperIndex({task: task, index: wrapperIndex})
|
||||
setStartWrapperIndex({ task: task, index: wrapperIndex });
|
||||
setTimeout(() => {
|
||||
e.target.classList.add('tasks__board__item__hide')
|
||||
},0)
|
||||
e.target.classList.add("tasks__board__item__hide");
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function dragEndHandler(e) {
|
||||
setWrapperHover(prevArray => prevArray.map((elem) => {
|
||||
return false
|
||||
}))
|
||||
e.target.classList.remove('tasks__board__item__hide')
|
||||
setWrapperHover((prevArray) =>
|
||||
prevArray.map((elem) => {
|
||||
return false;
|
||||
})
|
||||
);
|
||||
e.target.classList.remove("tasks__board__item__hide");
|
||||
}
|
||||
|
||||
function dragOverHandler(e) {
|
||||
e.preventDefault()
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function dragEnterHandler(wrapperIndex) {
|
||||
if (wrapperIndex === startWrapperIndex.index) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
setWrapperHover(prevArray => prevArray.map((elem, index) => {
|
||||
if (index === wrapperIndex) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}))
|
||||
setWrapperHover((prevArray) =>
|
||||
prevArray.map((elem, index) => {
|
||||
if (index === wrapperIndex) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function dragDropHandler(e, wrapperIndex) {
|
||||
e.preventDefault()
|
||||
e.preventDefault();
|
||||
if (startWrapperIndex.index === wrapperIndex) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
setWrapperHover(prevArray => prevArray.map((elem) => {
|
||||
return false
|
||||
}))
|
||||
setTabTaskMok(prevArray => prevArray.map((elem, index) => {
|
||||
if (index === wrapperIndex) {
|
||||
return {...elem, tasks: [...elem.tasks, startWrapperIndex.task]}
|
||||
} else if (index === startWrapperIndex.index) {
|
||||
return {...elem, tasks: elem.tasks.filter((item) => {
|
||||
return item.id !== startWrapperIndex.task.id
|
||||
}
|
||||
)}
|
||||
} else {
|
||||
return elem
|
||||
}
|
||||
}))
|
||||
setWrapperHover((prevArray) =>
|
||||
prevArray.map((elem) => {
|
||||
return false;
|
||||
})
|
||||
);
|
||||
setTabTaskMok((prevArray) =>
|
||||
prevArray.map((elem, index) => {
|
||||
if (index === wrapperIndex) {
|
||||
return { ...elem, tasks: [...elem.tasks, startWrapperIndex.task] };
|
||||
} else if (index === startWrapperIndex.index) {
|
||||
return {
|
||||
...elem,
|
||||
tasks: elem.tasks.filter((item) => {
|
||||
return item.id !== startWrapperIndex.task.id;
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
return elem;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function filterArchiveTasks(e) {
|
||||
setFilterCompleteTasks(completeTasks.filter((item) => {
|
||||
if (!e.target.value) {
|
||||
return item
|
||||
}
|
||||
if (item.name.toLowerCase().startsWith(e.target.value.toLowerCase()) || item.description.toLowerCase().startsWith(e.target.value.toLowerCase())) {
|
||||
return item
|
||||
}
|
||||
}))
|
||||
setFilterCompleteTasks(
|
||||
completeTasks.filter((item) => {
|
||||
if (!e.target.value) {
|
||||
return item;
|
||||
}
|
||||
if (
|
||||
item.name.toLowerCase().startsWith(e.target.value.toLowerCase()) ||
|
||||
item.description
|
||||
.toLowerCase()
|
||||
.startsWith(e.target.value.toLowerCase())
|
||||
) {
|
||||
return item;
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function createProject() {
|
||||
setModalCreateProject(true);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -330,6 +366,11 @@ export const Tracker = () => {
|
||||
<ProfileHeader />
|
||||
<div className="container">
|
||||
<div className="tracker__content">
|
||||
<ProfileBreadcrumbs links={[
|
||||
{name: 'Главная', link: '/profile'},
|
||||
{name: 'Трекер', link: '/profile/tracker'}
|
||||
]}
|
||||
/>
|
||||
<h2 className="tracker__title">Трекер</h2>
|
||||
<div className="tracker__tabs">
|
||||
<div className="tracker__tabs__head">
|
||||
@@ -375,11 +416,12 @@ export const Tracker = () => {
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<ModalProject
|
||||
active={modalActiveProject}
|
||||
setActive={setModalActiveProject}
|
||||
<ModalCreate
|
||||
active={modalCreateProject}
|
||||
setActive={setModalCreateProject}
|
||||
title={"Укажите название проекта:"}
|
||||
/>
|
||||
<button onClick={() => setModalActiveProject(true)}>
|
||||
<button onClick={createProject}>
|
||||
<span>+</span>Создать проект
|
||||
</button>
|
||||
</div>
|
||||
@@ -391,8 +433,18 @@ export const Tracker = () => {
|
||||
}
|
||||
>
|
||||
<div className="tasks__head">
|
||||
<ModalCreate
|
||||
active={modalCreateColl}
|
||||
setActive={setModalCreateColl}
|
||||
title={"Добавить колонку: "}
|
||||
/>
|
||||
<h4>Проект : Разработка трекера</h4>
|
||||
<span className="tasks__head__add">+</span>
|
||||
<span
|
||||
className="tasks__head__add"
|
||||
onClick={() => setModalCreateColl(true)}
|
||||
>
|
||||
+
|
||||
</span>
|
||||
<div className="tasks__head__persons">
|
||||
<img src={avatarTest} alt="avatar" />
|
||||
<img src={avatarTest} alt="avatar" />
|
||||
@@ -422,7 +474,13 @@ export const Tracker = () => {
|
||||
onDragOver={(e) => dragOverHandler(e)}
|
||||
onDragEnter={(e) => dragEnterHandler(wrapperIndex)}
|
||||
onDrop={(e) => dragDropHandler(e, wrapperIndex)}
|
||||
className={`tasks__board ${section.tasks.length >= 3 ? 'tasks__board__more' : ''} ${wrapperHover[wrapperIndex] ? 'tasks__board__hover' : ''}`}
|
||||
className={`tasks__board ${
|
||||
section.tasks.length >= 3 ? "tasks__board__more" : ""
|
||||
} ${
|
||||
wrapperHover[wrapperIndex]
|
||||
? "tasks__board__hover"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div className="board__head">
|
||||
<span className={wrapperIndex === 3 ? "done" : ""}>
|
||||
@@ -436,7 +494,7 @@ export const Tracker = () => {
|
||||
{section.tasks.map((task, index) => {
|
||||
if (index > 2) {
|
||||
if (!section.open) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
}
|
||||
return (
|
||||
@@ -444,7 +502,9 @@ export const Tracker = () => {
|
||||
key={index}
|
||||
className="tasks__board__item"
|
||||
draggable={true}
|
||||
onDragStart={(e) => dragStartHandler(e, task, wrapperIndex)}
|
||||
onDragStart={(e) =>
|
||||
dragStartHandler(e, task, wrapperIndex)
|
||||
}
|
||||
onDragEnd={(e) => dragEndHandler(e)}
|
||||
onClick={() => setModalActiveTicket(true)}
|
||||
>
|
||||
@@ -473,7 +533,16 @@ export const Tracker = () => {
|
||||
);
|
||||
})}
|
||||
{section.tasks.length > 3 && (
|
||||
<span className={section.open ? 'lessItems openItems' : 'moreItems openItems'} onClick={() => toggleMoreTasks(wrapperIndex)}>{section.open ? '-' : '+'}</span>
|
||||
<span
|
||||
className={
|
||||
section.open
|
||||
? "lessItems openItems"
|
||||
: "moreItems openItems"
|
||||
}
|
||||
onClick={() => toggleMoreTasks(wrapperIndex)}
|
||||
>
|
||||
{section.open ? "-" : "+"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@@ -483,30 +552,35 @@ export const Tracker = () => {
|
||||
<div
|
||||
className={
|
||||
toggleTab === 3
|
||||
? "tracker__tabs__content__archive tasks active__content"
|
||||
: "tracker__tabs__content__projects"
|
||||
? "tracker__tabs__content__archive tasks active__content"
|
||||
: "tracker__tabs__content__projects"
|
||||
}
|
||||
>
|
||||
<div className='archive__title'>
|
||||
<div className="archive__title">
|
||||
<h3>Архив:</h3>
|
||||
<p>{filterCompleteTasks.length} задач(а)</p>
|
||||
<div className='archive__search'>
|
||||
<input type='text' onChange={(event) => filterArchiveTasks(event)} />
|
||||
<img src={search} alt='search' />
|
||||
<div className="archive__search">
|
||||
<input
|
||||
type="text"
|
||||
onChange={(event) => filterArchiveTasks(event)}
|
||||
/>
|
||||
<img src={search} alt="search" />
|
||||
</div>
|
||||
</div>
|
||||
<div className='archive__tasksWrapper'>
|
||||
<div className="archive__tasksWrapper">
|
||||
{filterCompleteTasks.map((task, index) => {
|
||||
return <div className='archive__completeTask' key={index}>
|
||||
<div className='archive__completeTask__description'>
|
||||
<p>{task.description}</p>
|
||||
<p className='date'>{task.dateComplete}</p>
|
||||
</div>
|
||||
<div className='archive__completeTask__info'>
|
||||
<img src={task.avatarDo} alt='avatar' />
|
||||
<p>{task.name}</p>
|
||||
</div>
|
||||
</div>
|
||||
return (
|
||||
<div className="archive__completeTask" key={index}>
|
||||
<div className="archive__completeTask__description">
|
||||
<p>{task.description}</p>
|
||||
<p className="date">{task.dateComplete}</p>
|
||||
</div>
|
||||
<div className="archive__completeTask__info">
|
||||
<img src={task.avatarDo} alt="avatar" />
|
||||
<p>{task.name}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,8 @@ const initialState = {
|
||||
auth: false,
|
||||
positionId: null,
|
||||
profileInfo: {},
|
||||
reportsDates: ''
|
||||
reportsDates: '',
|
||||
partnerEmployees: []
|
||||
};
|
||||
|
||||
export const outstaffingSlice = createSlice({
|
||||
@@ -46,10 +47,13 @@ export const outstaffingSlice = createSlice({
|
||||
setReportsDates: (state, action) => {
|
||||
state.reportsDates = action.payload;
|
||||
},
|
||||
setPartnerEmployees: (state, action) => {
|
||||
state.partnerEmployees = action.payload
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const { tags, profiles, selectedItems, auth, currentCandidate, filteredCandidates, setPositionId, setUserInfo, setProfileInfo, setReportsDates } = outstaffingSlice.actions;
|
||||
export const { tags, profiles, selectedItems, auth, currentCandidate, filteredCandidates, setPositionId, setUserInfo, setProfileInfo, setReportsDates, setPartnerEmployees } = outstaffingSlice.actions;
|
||||
|
||||
export const selectProfiles = (state) => state.outstaffing.profiles;
|
||||
export const selectTags = (state) => state.outstaffing.tags;
|
||||
@@ -61,5 +65,6 @@ export const getPositionId = (state) => state.outstaffing.positionId;
|
||||
export const getProfileInfo = (state) => state.outstaffing.profileInfo;
|
||||
export const selectUserInfo = (state) => state.outstaffing.userInfo;
|
||||
export const getReportsDates = (state) => state.outstaffing.reportsDates;
|
||||
export const getPartnerEmployees = (state) => state.outstaffing.partnerEmployees;
|
||||
|
||||
export default outstaffingSlice.reducer;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
const initialState = {
|
||||
project: [
|
||||
{
|
||||
name: "Разработка трекера",
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
name: "Кинотеатр",
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
name: "Проект страхование",
|
||||
count: 4,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const projectsTrackerSlice = createSlice({
|
||||
name: "projectsTracker",
|
||||
initialState,
|
||||
reducers: {
|
||||
setProject: (state, action) => {
|
||||
state.project.push(action.payload);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setProject } = projectsTrackerSlice.actions;
|
||||
|
||||
export const getProjects = (state) => state.tracker.project;
|
||||
|
||||
export default projectsTrackerSlice.reducer;
|
||||
+12
-11
@@ -1,10 +1,10 @@
|
||||
import { configureStore } from '@reduxjs/toolkit';
|
||||
import outstaffingReducer from '../redux/outstaffingSlice';
|
||||
import loaderReducer from '../redux/loaderSlice';
|
||||
import roleReducer from '../redux/roleSlice';
|
||||
import reportReducer from '../redux/reportSlice';
|
||||
import quizSlice from '../redux/quizSlice';
|
||||
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import outstaffingReducer from "../redux/outstaffingSlice";
|
||||
import loaderReducer from "../redux/loaderSlice";
|
||||
import roleReducer from "../redux/roleSlice";
|
||||
import reportReducer from "../redux/reportSlice";
|
||||
import quizSlice from "../redux/quizSlice";
|
||||
import projectsTrackerSlice from "../redux/projectsTrackerSlice";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@@ -12,10 +12,11 @@ export const store = configureStore({
|
||||
loader: loaderReducer,
|
||||
role: roleReducer,
|
||||
report: reportReducer,
|
||||
tracker: projectsTrackerSlice,
|
||||
quiz: quizSlice,
|
||||
},
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware({
|
||||
serializableCheck: false,
|
||||
}),
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware({
|
||||
serializableCheck: false,
|
||||
}),
|
||||
});
|
||||
Reference in new issue
Block a user