Compare commits

...

14 Commits

Author SHA1 Message Date
Mikola
cf1bbf136e catalogSpecialists 2024-02-01 23:14:42 +03:00
Mikola
f07589217a catalogSpecialists 2024-02-01 23:14:29 +03:00
Mikola
0acbef4195 catalogSpecialists 2024-02-01 22:33:22 +03:00
Mikola
6dbb4eb609 catalogSpecialists 2024-02-01 22:32:55 +03:00
Victor Batischev
66e6b4c7d7 fix style names 2024-01-31 16:57:22 +03:00
Victor Batischev
78249348eb fix style names 2024-01-31 16:46:16 +03:00
Victor Batischev
73c9101be2 style fix 2024-01-31 16:25:06 +03:00
Victor Batischev
8462d38862 fix list employees 2024-01-30 20:26:58 +03:00
Victor Batischev
43cd44f0a9 full screen ticket fix 2024-01-30 20:16:21 +03:00
Victor Batischev
a32533fdea tracker add task fix 2024-01-30 20:02:28 +03:00
Victor Batischev
7a5d6fc9ec fix tracker card 2024-01-30 18:28:57 +03:00
Victor Batischev
c59d2100d2 small fix 2024-01-30 17:40:40 +03:00
6caed581e9 Merge pull request 'trackerTask' (#11) from trackerTask into main
Reviewed-on: #11
2024-01-29 21:21:23 +03:00
9114be123f Merge pull request 'trackerTask' (#10) from trackerTask into main
Reviewed-on: #10
2024-01-26 18:08:29 +03:00
43 changed files with 615 additions and 588 deletions

View File

@ -25,8 +25,8 @@ import { RegistrationSetting } from "@pages/RegistrationSetting/RegistrationSett
import Article from "./pages/Article/Article";
import FormPage from "./pages/FormPage/FormPage";
import SingleReportPage from "./pages/SingleReportPage/SingleReportPage";
import { QuizPage } from "./pages/quiz/QuizPage";
import { QuizReportPage } from "./pages/quiz/QuizReportPage";
import { QuizPage } from "./pages/Quiz/QuizPage";
import { QuizReportPage } from "./pages/Quiz/QuizReportPage";
import { Profile } from "./pages/Profile/Profile.js";
import { Summary } from "./pages/Summary/Summary";
import { ViewReport } from "./pages/ViewReport/ViewReport";
@ -42,7 +42,7 @@ import { PartnerEmployees } from "./pages/PartnerEmployees/PartnerEmployees";
import { AuthForCandidate } from "./pages/AuthForCandidate/AuthForCandidate";
import { RegistrationForCandidate } from "./pages/RegistrationForCandidate/RegistrationForCandidate";
import { ProfileCandidate } from "./pages/ProfileCandidate/ProfileCandidate";
import { PassingTests } from "./pages/quiz/PassingTests";
import { PassingTests } from "./pages/Quiz/PassingTests";
import Blog from "./pages/Blog/Blog";
import Statistics from "@pages/Statistics/Statistics";
import { ProjectTracker } from "./pages/ProjectTracker/ProjectTracker";

View File

@ -51,10 +51,10 @@ export const apiRequest = (
};
const RequestError = (code, msg, data) => {
const description = msg ? `- ${msg}` : "";
const descriptionMessage = msg ? `- ${msg}` : "";
this.name = "RequestError";
this.message = `API returned: ${code}${description}.`;
this.message = `API returned: ${code}${descriptionMessage}.`;
this.code = code;
this.description = msg;
this.data = data;

View File

@ -101,6 +101,21 @@
line-height: 32px;
color: white;
height: 45px;
@media (max-width: 900px) {
max-width: 185px;
}
@media (max-width: 450px) {
width: 100%;
max-width: none;
margin-right: 0;
}
}
@media (max-width: 450px) {
flex-direction: column;
row-gap: 10px;
}
}
@ -139,12 +154,17 @@
transform: scale(1.03);
color: white;
}
@media (max-width: 450px) {
width: 100%;
max-width: none;
}
}
&__img {
position: absolute;
right: 48px;
top: -90px;
top: -20px;
@media (max-width: 900px) {
order: 1;

View File

@ -75,7 +75,7 @@ const Calendar = () => {
}}
/>
<p className="calendar__hours">
{month} : <span> 60 часов </span>
{month}: <span> 60 часов </span>
</p>
</div>
</div>

View File

@ -127,7 +127,7 @@ const Candidate = () => {
<img src={rightArrow} alt="" />
</div>
<div className="candidate__arrow-sp">
<span>Вернуться к списку</span>
<span>К списку кандидатов</span>
</div>
</div>
</div>

View File

@ -29,8 +29,13 @@
display: flex;
padding: 0 0 14px 16px;
p {
font-size: 13px;
}
img {
margin-right: 9px;
width: 15px;
margin-right: 5px;
}
}
}

View File

@ -21,7 +21,7 @@
align-items: center;
justify-content: center;
.selectPerson {
.select-person {
align-items: start;
&__info {
@ -45,7 +45,7 @@
font-weight: 300;
}
.addPersonBlock {
.add-person-block {
display: flex;
flex-direction: column;
justify-content: space-between;
@ -55,7 +55,7 @@
}
}
.invitePersonBlock {
.invite-person-block {
display: flex;
flex-direction: column;
row-gap: 20px;
@ -89,14 +89,14 @@
margin: 5px 0;
}
.invitePersonBlock {
.invite-person-block {
row-gap: 5px;
&__btn {
margin: 5px auto;
}
}
.addPersonBtn {
.add-person-btn {
margin: 10px auto 0;
}
}
@ -114,7 +114,7 @@
}
}
.createTiketProject {
.create-ticket-project {
padding: 0;
background: white;
}
@ -128,11 +128,11 @@
transform: scale(1);
}
.createProject,
.createColumn,
.editProject,
.addWorker,
.editColumn {
.create-project,
.create-column,
.edit-project,
.add-worker,
.edit-column {
background: linear-gradient(180deg, #fff 0%, #ebebeb 37.29%);
.title-project {
margin-top: 20px;

View File

@ -3,14 +3,15 @@
.frequently-asked-questions-item {
&__head {
display: flex;
align-items: center;
gap: 19px;
margin: 0 0 -5px 29px;
margin: 0 0 0px 29px;
}
&__title {
font-weight: 700;
@include adaptiv-value("font-size", 28, 22, 1);
line-height: 79%;
line-height: 100%;
color: #1458dd;
}

View File

@ -1,4 +1,5 @@
import React from "react";
import { Link } from "react-router-dom";
import close from "assets/icons/closeProjectPersons.svg";
@ -16,12 +17,13 @@ export const ModalTrackerRegistration = ({ setModalReset, email }) => {
для активации вашего аккаунта на почту
<br /> <span>{email}</span>
</p>
<button
<Link
to={"/registration-setting"}
onClick={() => setModalReset(false)}
className="modalConfirmTracker__btn"
>
Понятно
</button>
</Link>
<img
onClick={() => setModalReset(false)}
src={close}

View File

@ -51,8 +51,8 @@ const ListEmployees = ({
{caseOfNum(projectBoard.projectUsers?.length, "persons")}
</div>
<div className="persons__list__info">
<span>В проекте - </span>
<p>{projectBoard.name}</p>
<span>В проекте </span>
<p>{projectBoard.name}</p>
</div>
<div className="persons__list__items">
{projectBoard.projectUsers?.map((person) => {
@ -81,12 +81,12 @@ const ListEmployees = ({
<div
className="persons__list__add"
onClick={() => {
dispatch(modalToggle("addWorker"));
dispatch(modalToggle("add-worker"));
setModalAdd(true);
setActiveListEmpl(false);
}}
>
<span className="addPerson">+</span>
<span className="add-person">+</span>
<p>Добавить участников</p>
</div>
</div>

View File

@ -70,7 +70,7 @@
left: -20px;
}
.addPerson {
.add-person {
background: #00c5a8;
color: white;
font-size: 14px;
@ -100,15 +100,15 @@
flex-direction: column;
background: linear-gradient(180deg, #ffffff 0%, #ebebeb 100%);
border-radius: 20px;
padding: 30px;
padding: 20px;
cursor: default;
width: 800px;
width: 700px;
&__close {
cursor: pointer;
position: absolute;
right: 25px;
top: 25px;
right: 20px;
top: 20px;
margin-left: auto;
width: 35px;
height: 35px;
@ -122,7 +122,7 @@
span {
font-size: 44px;
font-weight: 700;
line-height: 40px;
line-height: 30px;
width: auto;
height: auto;
margin-right: 5px;
@ -131,7 +131,7 @@
&__info {
display: flex;
margin: 11px 0 35px;
margin: 10px 0;
align-items: center;
span {
@ -161,14 +161,13 @@
&__items {
display: flex;
flex-wrap: wrap;
row-gap: 32px;
column-gap: 85px;
margin-bottom: 38px;
row-gap: 10px;
column-gap: 30px;
margin-bottom: 10px;
}
&__item {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 300px;
width: 100%;
@ -181,13 +180,13 @@
span {
display: block;
font-weight: 400;
font-weight: 500;
font-size: 15px;
line-height: initial;
color: #807777;
width: auto;
height: auto;
max-width: 215px;
max-width: 280px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

View File

@ -592,16 +592,16 @@ export const ModalTiсket = ({
return (
<div
className={active ? "modal-tiket active" : "modal-tiket"}
className={active ? "modal-ticket active" : "modal-ticket"}
onClick={(e) => {
if (e.target.className.includes("modal-tiket")) setActive(false);
if (e.target.className.includes("modal-ticket")) setActive(false);
}}
>
<div className="modal-tiket__content">
<div className="modal-ticket__content">
<div className="content">
<h3 className="title-project">
<img src={category} className="title-project__category"></img>
Проект: {projectName}
{projectName}
<Link
to={`/tracker/task/${task.id}`}
className="title-project__full"
@ -758,14 +758,18 @@ export const ModalTiсket = ({
<div className="workers">
<div className="workers_box task__info">
<span className="exit" onClick={() => setActive(false)}></span>
<p className="workers__creator">Создатель : {task.user?.fio}</p>
<p className="workers__creator">Создатель: {task.user?.fio}</p>
{executor ? (
<>
<h5>Исполнитель: </h5>
<div className="executor">
<p>Исполнитель: {executor.fio}</p>
<p>{executor.fio}</p>
<img
src={
executor?.avatar ? urlForLocal(executor.avatar) : avatarMok
executor?.avatar
? urlForLocal(executor.avatar)
: avatarMok
}
alt="avatar"
/>
@ -775,6 +779,7 @@ export const ModalTiсket = ({
onClick={() => deleteTaskExecutor()}
/>
</div>
</>
) : (
<div className="add-worker moreItems ">
<button
@ -817,7 +822,7 @@ export const ModalTiсket = ({
{Boolean(members.length) && (
<div className="members">
<p>Участники:</p>
<h5>Участники:</h5>
<div className="members__list">
{members.map((member) => {
return (
@ -912,7 +917,7 @@ export const ModalTiсket = ({
</div>
<div className="time">
<img src={watch}></img>
<span>Длительность : </span>
<span>Длительность: </span>
<p>
{correctTimerTime(currentTimerCount.hours)}:
{correctTimerTime(currentTimerCount.minute)}:

View File

@ -1,4 +1,4 @@
.modal-tiket {
.modal-ticket {
z-index: 9;
height: 100%;
width: 100%;
@ -11,11 +11,11 @@
justify-content: center;
}
.modal-tiket.active {
.modal-ticket.active {
display: flex;
}
.modal-tiket__content {
.modal-ticket__content {
background: #ffffff;
border-radius: 8px;
display: flex;
@ -63,9 +63,10 @@
color: #1458dd;
font-weight: 700;
font-size: 22px;
margin-left: 15px;
&__category {
margin-right: 17px;
margin-right: 5px;
}
h2,
@ -613,7 +614,7 @@
cursor: pointer;
position: absolute;
top: 25px;
right: 30px;
right: 20px;
width: 13px;
height: 13px;
display: flex;
@ -654,8 +655,7 @@
display: flex;
align-items: center;
position: relative;
margin-bottom: 5px;
margin-top: 12px;
margin-top: 10px;
span {
color: #000000;
@ -688,7 +688,7 @@
.start {
font-size: 12px;
margin-top: 25px;
margin-top: 15px;
width: 151px;
height: 40px;
border: none;
@ -964,11 +964,11 @@
}
&_box {
padding: 25px 85px 25px 40px;
padding: 25px 0px 10px 40px;
border-bottom: 1px solid #f1f1f1;
&-middle {
padding: 0px 40px 25px 40px;
padding: 0px 0px 10px 35px;
border-bottom: 1px solid #f1f1f1;
}
@ -978,8 +978,8 @@
flex-direction: column;
position: relative;
row-gap: 15px;
padding: 22px 40px 0 40px;
row-gap: 10px;
padding: 10px 40px 0px 40px;
border-radius: 10px;
margin-bottom: 10px;
@ -1170,10 +1170,10 @@
}
&-bottom {
padding: 10px 110px 15px 56px;
padding: 0px 110px 10px 35px;
font-weight: 400;
font-size: 14px;
line-height: 38px;
line-height: 32px;
div {
display: flex;

View File

@ -7,13 +7,7 @@ import { useDispatch, useSelector } from "react-redux";
import { Link, useNavigate, useParams } from "react-router-dom";
import { getProfileInfo } from "@redux/outstaffingSlice";
import {
deletePersonOnProject,
getBoarderLoader,
modalToggle,
setProjectBoardFetch,
setToggleTab
} from "@redux/projectsTrackerSlice";
import { getBoarderLoader, setToggleTab } from "@redux/projectsTrackerSlice";
import {
backendImg,
@ -32,7 +26,6 @@ import { Footer } from "@components/Common/Footer/Footer";
import { Loader } from "@components/Common/Loader/Loader";
import FileTracker from "@components/FileTracker/FileTracker";
import AcceptModal from "@components/Modal/AcceptModal/AcceptModal";
import TrackerModal from "@components/Modal/Tracker/TrackerModal/TrackerModal";
import { Navigation } from "@components/Navigation/Navigation";
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
@ -60,7 +53,6 @@ import "./ticketFullScreen.scss";
registerLocale("ru", ru);
export const TicketFullScreen = () => {
const [modalAddWorker, setModalAddWorker] = useState(false);
const ticketId = useParams();
const dispatch = useDispatch();
const navigate = useNavigate();
@ -71,7 +63,6 @@ export const TicketFullScreen = () => {
const [inputsValue, setInputsValue] = useState({});
const [loader, setLoader] = useState(true);
const [comments, setComments] = useState([]);
const [personListOpen, setPersonListOpen] = useState(false);
const [timerStart, setTimerStart] = useState(false);
const [timerInfo, setTimerInfo] = useState({});
const [currentTimerCount, setCurrentTimerCount] = useState({
@ -292,18 +283,6 @@ export const TicketFullScreen = () => {
});
}
function deletePerson(userId) {
apiRequest("/project/del-user", {
method: "DELETE",
data: {
project_id: projectInfo.id,
user_id: userId
}
}).then(() => {
dispatch(deletePersonOnProject(userId));
});
}
function commentDelete(comment) {
setComments((prevValue) =>
prevValue.filter((item) => item.id !== comment.id)
@ -616,18 +595,6 @@ export const TicketFullScreen = () => {
) {
setSelectTagsOpen(false);
}
if (
event &&
!path.find(
(div) =>
div.classList &&
(div.classList.contains("addPerson") ||
div.classList.contains("persons__list"))
)
) {
setPersonListOpen(false);
}
};
return (
@ -679,112 +646,20 @@ export const TicketFullScreen = () => {
<div className="tracker__tabs__content content-tabs">
<div className="tasks__head">
<div className="tasks__head__wrapper tasks__head__wrapper__fullScreen">
<h5>Проект : {projectInfo.name}</h5>
<TrackerModal
active={modalAddWorker}
setActive={setModalAddWorker}
></TrackerModal>
<div className="tasks__head__persons">
<div className="projectPersons">
{projectInfo.projectUsers?.length &&
projectInfo.projectUsers.slice(0, 3).map((person) => {
return (
<img
key={person.user_id}
src={
person.user?.avatar
? urlForLocal(person.user.avatar)
: avatarMok
}
alt="avatar"
/>
);
})}
</div>
{projectInfo.projectUsers?.length > 3 && (
<span className="countPersons">+1</span>
)}
<span
className="addPerson"
onClick={() => {
setPersonListOpen(true);
}}
>
+
</span>
<p>добавить участника</p>
{personListOpen && (
<div className="persons__list">
<img
className="persons__list__close"
src={close}
alt="close"
onClick={() => setPersonListOpen(false)}
/>
<div className="persons__list__count">
<span>{projectInfo.projectUsers?.length}</span>
участник
</div>
<div className="persons__list__info">
<span>В проекте - </span>
<p>{projectInfo.name}</p>
</div>
<div className="persons__list__items">
{projectInfo.projectUsers?.map((person) => {
return (
<div
className="persons__list__item"
key={person.user_id}
>
<img
className="avatar"
src={
person.user?.avatar
? urlForLocal(person.user.avatar)
: avatarMok
}
alt="avatar"
/>
<span>{person.user.fio}</span>
<img
className="delete"
src={close}
alt="delete"
onClick={() => deletePerson(person.user_id)}
/>
</div>
);
})}
</div>
<div
className="persons__list__add"
onClick={() => {
dispatch(modalToggle("addWorker"));
setModalAddWorker(true);
setPersonListOpen(false);
}}
>
<span className="addPerson">+</span>
<p>Добавить участников</p>
</div>
</div>
)}
</div>
<h5>{projectInfo.name}</h5>
<Link
to={`/tracker/project/${taskInfo.project_id}`}
className="link"
>
<div className="tasks__head__back">
<p>Вернуться на проект</p>
<p>К списку задач</p>
<img src={arrow} alt="arrow" />
</div>
</Link>
</div>
</div>
</div>
<div className="modal-tiket__content ticket">
<div className="modal-ticket__content ticket">
<div className="content ticket-whith">
<div className="content__task">
{editOpen ? (
@ -800,7 +675,6 @@ export const TicketFullScreen = () => {
/>
) : (
<h5 className="fullName nameFullScreen">
<span>Название задачи:</span>
{inputsValue.title}
</h5>
)}
@ -833,12 +707,7 @@ export const TicketFullScreen = () => {
/>
) : (
<div className="ticket__description">
<span>
Описание
<br />
задачи:{" "}
</span>
<p
<div
className="fullDescription fullScreenDescription"
dangerouslySetInnerHTML={{
__html: inputsValue.description
@ -884,18 +753,6 @@ export const TicketFullScreen = () => {
</div>
)}
<div className="content__communication">
{/*<p className="tasks">*/}
{/* <BaseButton*/}
{/* onClick={() => {*/}
{/* dispatch(modalToggle("addSubtask"));*/}
{/* setModalAddWorker(true);*/}
{/* }}*/}
{/* styles={"button-green-add"}*/}
{/* >*/}
{/* <img src={plus}></img>*/}
{/* Добавить под задачу*/}
{/* </BaseButton>*/}
{/*</p>*/}
<div className="file">
<div className="input__wrapper">
<input
@ -954,13 +811,15 @@ export const TicketFullScreen = () => {
</div>
<div className="workers fullScreenWorkers">
<div className="workers_box task__info">
<p className="workers__creator">
Создатель :<p>&nbsp;{taskInfo.user?.fio}</p>
</p>
<div className="workers__creator">
Создатель: <p>&nbsp;{taskInfo.user?.fio}</p>
</div>
{taskInfo.executor ? (
<>
<h5>Исполнитель: </h5>
<div className="executor">
<p>Исполнитель: {taskInfo.executor.fio}</p>
<p>{taskInfo.executor.fio}</p>
<img
src={
taskInfo.executor?.avatar
@ -975,6 +834,7 @@ export const TicketFullScreen = () => {
onClick={() => deleteTaskExecutor()}
/>
</div>
</>
) : (
<div className="add-worker moreItems ">
<button

View File

@ -65,7 +65,7 @@ export const TrackerModal = ({
const [projectName, setProjectName] = useState(defautlInput);
const [valueColumn, setValueColumn] = useState("");
const [nameProject, setNameProject] = useState("");
const [valueTiket, setValueTiket] = useState("");
const [valueTicket, setValueTicket] = useState("");
const [descriptionTicket, setDescriptionTicket] = useState("");
const [workers, setWorkers] = useState([]);
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
@ -127,8 +127,8 @@ export const TrackerModal = ({
setActive(false);
}
function createTiket() {
if (!valueTiket || !descriptionTicket) {
function createTicket() {
if (!valueTicket || !descriptionTicket) {
showNotification({
show: true,
text: "Введите название и описание",
@ -141,7 +141,7 @@ export const TrackerModal = ({
method: "POST",
data: {
project_id: projectBoard.id,
title: valueTiket,
title: valueTicket,
description: descriptionTicket,
status: 1,
user_id: localStorage.getItem("id"),
@ -180,14 +180,14 @@ export const TrackerModal = ({
}).then(() => {
dispatch(setProjectBoardFetch(projectBoard.id));
setActive(false);
setValueTiket("");
setValueTicket("");
setDescriptionTicket("");
setSelectedExecutorTask("Выберите исполнителя задачи");
setSelectedPriority(null);
});
} else {
setActive(false);
setValueTiket("");
setValueTicket("");
setDescriptionTicket("");
dispatch(setProjectBoardFetch(projectBoard.id));
}
@ -265,9 +265,7 @@ export const TrackerModal = ({
}
function createProject() {
if (nameProject === "") {
return;
} else {
if (nameProject !== "") {
apiRequest("/project/create", {
method: "POST",
data: {
@ -308,7 +306,7 @@ export const TrackerModal = ({
}
useEffect(() => {
modalType === "addWorker"
modalType === "add-worker"
? apiRequest("/project/my-employee").then((el) => {
let persons = el.managerEmployees;
let ids = projectBoard.projectUsers.map((user) => user.user_id);
@ -396,10 +394,10 @@ export const TrackerModal = ({
// setSelectWorkersOpen(false);
// }}
>
{modalType === "addWorker" && (
{modalType === "add-worker" && (
<>
<div className="select__person">
<div className="title-project selectPerson">
<div className="title-project select-person">
<h4>Добавьте участника</h4>
{/*<div className="input-container">*/}
{/* <input*/}
@ -408,11 +406,11 @@ export const TrackerModal = ({
{/* onChange={(e) => setEmailWorker(e.target.value)}*/}
{/* />*/}
{/*</div>*/}
<p className="selectPerson__info">
<p className="select-person__info">
Выберите пользователя в проекте или добавьте по e-mail
</p>
<div className="invite__blocks">
<div className="addPersonBlock">
<div className="add-person-block">
<div
className={
selectWorkersOpen
@ -457,22 +455,22 @@ export const TrackerModal = ({
)}
</div>
<BaseButton
styles={"button-add addPersonBtn"}
styles={"button-add add-person-btn"}
onClick={addUserToProject}
>
Добавить
</BaseButton>
</div>
<span>или</span>
<div className="invitePersonBlock">
<div className="input-container invitePersonBlock__input">
<div className="invite-person-block">
<div className="input-container invite-person-block__input">
<input
className="name-project"
placeholder="e-mail"
type="email"
/>
</div>
<BaseButton styles={"button-add invitePersonBlock__btn"}>
<BaseButton styles={"button-add invite-person-block__btn"}>
Отправить приглашение
</BaseButton>
</div>
@ -481,12 +479,12 @@ export const TrackerModal = ({
</div>
</>
)}
{modalType === "createTiketProject" && (
{modalType === "create-ticket-project" && (
<>
<div className="title-project">
<div className="createTaskHead">
<div className="createTaskBody__right__owner">
<p>Создатель : {profileInfo?.fio}</p>
<p>Создатель: {profileInfo?.fio}</p>
<img
src={
profileInfo.photo
@ -509,8 +507,8 @@ export const TrackerModal = ({
<input
maxLength="100"
className="name-project"
value={valueTiket}
onChange={(e) => setValueTiket(e.target.value)}
value={valueTicket}
onChange={(e) => setValueTicket(e.target.value)}
placeholder="Название задачи"
/>
</div>
@ -713,15 +711,15 @@ export const TrackerModal = ({
}}
/>
</div>
<BaseButton styles={"button-add"} onClick={createTiket}>
</div>
</div>
<BaseButton styles={"button-add"} onClick={createTicket}>
Создать
</BaseButton>
</div>
</div>
</div>
</>
)}
{modalType === "editProject" && (
{modalType === "edit-project" && (
<div>
<div className="title-project">
<h4>Введите новое название</h4>
@ -739,7 +737,7 @@ export const TrackerModal = ({
</BaseButton>
</div>
)}
{modalType === "createProject" && (
{modalType === "create-project" && (
<div>
<div className="title-project">
<h4>{titleProject}</h4>
@ -774,7 +772,7 @@ export const TrackerModal = ({
</BaseButton>
</div>
)}
{modalType === "createColumn" && (
{modalType === "create-column" && (
<div>
<div className="title-project">
<h4>Введите название колонки</h4>
@ -788,11 +786,11 @@ export const TrackerModal = ({
</div>
</div>
<BaseButton styles={"button-add"} onClick={createTab}>
Создать
Добавить
</BaseButton>
</div>
)}
{modalType === "editColumn" && (
{modalType === "edit-column" && (
<div>
<div className="title-project">
<h4>Введите новое название</h4>

View File

@ -31,7 +31,7 @@
align-items: center;
flex-direction: column;
row-gap: 8px;
margin-bottom: 10px;
padding-bottom: 10px;
.select-priority {
background-color: white;
@ -296,7 +296,7 @@
.createTaskHead {
width: 100%;
padding: 30px 42px 18px;
padding: 5px 10px;
display: flex;
column-gap: 9.5px;
align-items: center;
@ -325,9 +325,9 @@
}
.createTaskBody {
padding: 13px 43px 46px 42px;
padding: 10px;
display: flex;
column-gap: 55px;
column-gap: 20px;
&__left {
display: flex;
@ -336,7 +336,8 @@
color: #263238 !important;
font-size: 16px;
line-height: 19.2px;
margin-bottom: 25px;
margin-bottom: 15px;
margin-left: 5px;
}
.input-container {
@ -360,8 +361,8 @@
}
.ck-editor__editable.ck-rounded-corners {
min-height: 110px;
max-height: 110px;
min-height: 130px;
max-height: 130px;
}
}
@ -399,7 +400,7 @@
font-weight: 300;
line-height: 18px;
font-size: 15px;
margin-bottom: 17.5px;
margin-bottom: 10px;
border-radius: 8px;
display: flex;
flex-direction: column;
@ -579,7 +580,6 @@
font-weight: 300;
line-height: 18px;
font-size: 15px;
margin-bottom: 27px;
z-index: 100;
}
@ -600,7 +600,7 @@
line-height: 18px;
font-size: 15px;
position: relative;
margin-bottom: 22px;
margin: 8px 0 30px;
span {
color: #6f6f6f;
@ -730,7 +730,7 @@
margin: 0 auto;
}
.addPersonBtn {
.add-person-btn {
margin: 0 auto 0 0;
margin-top: 20px;
}

View File

@ -0,0 +1,29 @@
import React from "react";
import { Link } from "react-router-dom";
import { urlForLocal } from "@utils/helper";
import rightArrow from "assets/icons/arrows/arrowRight.svg";
import "./partnerPersonCard.scss";
export const PartnerPersonCard = ({ name, img, userId }) => {
return (
<div className="partnerPersonCard">
<div className="partnerPersonCard__img">
<img src={urlForLocal(img)} alt="avatar" />
</div>
<div className="partnerPersonCard__info">
<h2 className="partnerPersonCard__name">{name}</h2>
<Link className="partnerPersonCard__report" to={`calendar/${userId}`}>
Подробный отчет
<div className="partnerPersonCard__more">
<img src={rightArrow} alt="arrow" />
</div>
</Link>
</div>
</div>
);
};
export default PartnerPersonCard;

View File

@ -0,0 +1,45 @@
.partnerPersonCard {
display: flex;
position: relative;
&__img {
background: white;
border-radius: 12px;
padding: 25px;
z-index: 2;
img {
width: 77px;
height: 77px;
}
}
&__info {
position: relative;
background: #E1FCCF;
z-index: 1;
padding: 15px 15px 15px 30px;
left: -15px;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
&__report {
display: flex;
column-gap: 10px;
color: black;
font-size: 16px;
align-items: center;
}
&__more {
width: 41px;
height: 41px;
background: white;
border-radius: 50px;
display: flex;
justify-content: center;
align-items: center;
}
}

View File

@ -51,9 +51,7 @@ export const ProfileCalendar = () => {
return;
}
apiRequest(
`/reports/reports-by-date?${requestDates}&user_card_id=${localStorage.getItem(
"cardId"
)}`
`/reports/index?${requestDates}&user_id =${localStorage.getItem("id")}`
).then((reports) => {
let spendTime = 0;

View File

@ -114,9 +114,7 @@ export const ProfileCalendarComponent = React.memo(
startDate._d
)}`;
apiRequest(
`/reports/reports-by-date?${requestDates}&user_card_id=${localStorage.getItem(
"cardId"
)}`
`/reports/index?${requestDates}&user_id =${localStorage.getItem("id")}`
).then((reports) => {
let spendTime = 0;
reports.map((report) => {

View File

@ -20,9 +20,9 @@ import edit from "assets/icons/edit.svg";
import link from "assets/icons/link.svg";
import avatarProject from "assets/images/avatarMok.png";
import "./projectTiket.scss";
import "./projectTicket.scss";
export const ProjectTiket = ({ project, index }) => {
export const ProjectTicket = ({ project, index }) => {
const [modalSelect, setModalSelect] = useState(false);
const [modalAdd, setModalAdd] = useState(false);
const [modalDelete, setModalDelete] = useState(false);
@ -64,7 +64,7 @@ export const ProjectTiket = ({ project, index }) => {
dispatch(deleteProject(project));
showNotification({
show: true,
text: "Проект успешно была перемещена в архив",
text: "Проект успешно был перемещен в архив",
type: "archive"
});
});
@ -81,7 +81,7 @@ export const ProjectTiket = ({ project, index }) => {
<div className={`project project-${project.id}`} key={index}>
<Link
to={`/tracker/project/${project.id}`}
className="project__open-traker"
className="project__open-tracker"
>
<div className="project__link">{project.name}</div>
@ -125,7 +125,7 @@ export const ProjectTiket = ({ project, index }) => {
<div className="project__settings-menu">
<div
onClick={() => {
dispatch(modalToggle("editProject"));
dispatch(modalToggle("edit-project"));
setModalAdd(true);
setModalSelect(false);
}}
@ -177,4 +177,4 @@ export const ProjectTiket = ({ project, index }) => {
);
};
export default ProjectTiket;
export default ProjectTicket;

View File

@ -96,7 +96,7 @@
margin-left: 56px;
}
&__open-traker {
&__open-tracker {
padding: 17px 26px 16px;
}

View File

@ -97,6 +97,7 @@ const ReportForm = () => {
apiRequest("/reports/create", {
method: "POST",
data: {
user_id: localStorage.getItem("id"),
tasks: inputs,
difficulties: troublesInputValue,
tomorrow: scheduledInputValue,

View File

@ -39,9 +39,7 @@ export const ShortReport = () => {
setTomorrowTask([]);
setTotalHours(0);
apiRequest(
`reports/find-by-date?user_card_id=${localStorage.getItem(
"cardId"
)}&date=${day}`
`reports/find-by-date?user_id=${localStorage.getItem("id")}&date=${day}`
).then((res) => {
let spendTime = 0;
for (const item of res) {

View File

@ -3,7 +3,7 @@
position: fixed;
top: 0;
left: 0;
width: 141px;
width: 100px;
height: 100%;
background: #e1fccf;
@ -108,7 +108,7 @@
}
.auth-body {
padding: 40px;
padding: 40px 10px;
visibility: hidden;
transition: 0.2s ease-in-out;
opacity: 0;
@ -184,8 +184,8 @@
transition: 0.1s ease-in-out;
opacity: 1;
display: flex;
width: 424px;
left: 140px;
width: 280px;
left: 100px;
@media (max-width: 1440px) {
left: 79px;

View File

@ -504,13 +504,13 @@ $maxWidthContainer: 1123;
}
}
&__finished {
background: rgba(255, 255, 255, 0.76);
background: white;
mix-blend-mode: normal;
border: 3px solid #52b709;
border-radius: 12px;
padding: 13px 16px;
position: absolute;
bottom: 0;
bottom: 4px;
left: 0;
display: flex;
align-items: center;

View File

@ -41,7 +41,7 @@ export const Article = () => {
<AuthHeader />
<SideBar />
<div className="container">
<div className="article-blog__breadCrumbs">
<div className="article-blog__breadcrumbs">
<ProfileBreadcrumbs
links={[
{ name: "Главная", link: "/auth" },

View File

@ -1,7 +1,7 @@
.article-blog {
background: #f1f1f1;
&__breadCrumbs {
&__breadcrumbs {
margin-top: 30px;
@media (max-width: 1375px) {
@ -38,7 +38,7 @@
span {
font-weight: 400;
font-size: 12px;
font-size: 18px;
line-height: 20px;
color: #6f6f6f;
margin-left: 19px;
@ -117,7 +117,8 @@
}
img {
margin: 0 16px 0 0;
width: 15px;
margin-right: 5px;
}
}

View File

@ -56,7 +56,7 @@ export const Blog = () => {
<SideBar />
<div className="container">
<div className="blog__breadCrumbs">
<div className="blog__breadcrumbs">
<ProfileBreadcrumbs
links={[
{ name: "Главная", link: "/auth" },

View File

@ -1,7 +1,7 @@
.blog {
background: #f1f1f1;
&__breadCrumbs {
&__breadcrumbs {
margin-top: 30px;
@media (max-width: 1375px) {

View File

@ -1,16 +0,0 @@
import React from "react";
import { BookkeepingContent } from "@components/features/bookkeeping/BookkeepingContent/BookkeepingContent";
import { BookkeepingTemplete } from "@components/features/bookkeeping/BookkeepingTemplete/BookkeepingTemplete";
const Bookkeeping = () => {
return (
<div>
<BookkeepingTemplete>
<BookkeepingContent></BookkeepingContent>
</BookkeepingTemplete>
</div>
);
};
export default Bookkeeping;

View File

@ -10,12 +10,12 @@
}
&__container {
flex: 1 1 auto;
margin-top: 30px;
margin: 30px 0;
}
&__about {
display: flex;
align-items: center;
margin: 0 0 70px 0;
margin-bottom: 30px;
@media (max-width: 600px) {
flex-wrap: wrap;
row-gap: 25px;

View File

@ -1,137 +1,146 @@
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import React, { useEffect, useState } from "react";
// import { useDispatch } from "react-redux";
// import { Link } from "react-router-dom";
import { Navigate } from "react-router-dom";
import { setPartnerEmployees } from "@redux/outstaffingSlice";
import { apiRequest } from "@api/request";
// import { setPartnerEmployees } from "@redux/outstaffingSlice";
import { Footer } from "@components/Common/Footer/Footer";
import { Navigation } from "@components/Navigation/Navigation";
import PartnerPersonCard from "@components/PartnerPersonCard/PartnerPersonCard";
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
import rightArrow from "assets/icons/arrows/arrowRight.svg";
import avatarImg from "assets/images/avatarMok.png";
import AdminImg from "assets/images/partnerProfile/PersonalAdmin.svg";
import ArchitectureImg from "assets/images/partnerProfile/PersonalArchitecture.svg";
import CopyImg from "assets/images/partnerProfile/PersonalCopy.svg";
import DesignImg from "assets/images/partnerProfile/PersonalDesign.svg";
import FrontendImg from "assets/images/partnerProfile/PersonalFrontend.svg";
import ManageImg from "assets/images/partnerProfile/PersonalMng.svg";
import SmmImg from "assets/images/partnerProfile/PersonalSMM.svg";
import TestImg from "assets/images/partnerProfile/PersonalTesters.svg";
import BackEndImg from "assets/images/partnerProfile/personalBackEnd.svg";
import { Navigation } from "../../components/Navigation/Navigation";
// import rightArrow from "assets/icons/arrows/arrowRight.svg";
// import avatarImg from "assets/images/avatarMok.png";
// import AdminImg from "assets/images/partnerProfile/PersonalAdmin.svg";
// import ArchitectureImg from "assets/images/partnerProfile/PersonalArchitecture.svg";
// import CopyImg from "assets/images/partnerProfile/PersonalCopy.svg";
// import DesignImg from "assets/images/partnerProfile/PersonalDesign.svg";
// import FrontendImg from "assets/images/partnerProfile/PersonalFrontend.svg";
// import ManageImg from "assets/images/partnerProfile/PersonalMng.svg";
// import SmmImg from "assets/images/partnerProfile/PersonalSMM.svg";
// import TestImg from "assets/images/partnerProfile/PersonalTesters.svg";
// import BackEndImg from "assets/images/partnerProfile/personalBackEnd.svg";
import "./partnerСategories.scss";
export const PartnerCategories = () => {
const dispatch = useDispatch();
// const dispatch = useDispatch();
if (localStorage.getItem("role_status") !== "18") {
return <Navigate to="/profile" replace />;
}
const [personalInfoItems] = useState([
{
title: "Backend разработчики",
link: "/profile/categories/employees",
description:
"Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
available: true,
img: BackEndImg
},
{
title: "Frontend разработчики",
link: "/profile/categories/employees",
description:
"Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
available: true,
img: FrontendImg
},
{
title: "Архитектура проектов",
link: "/profile/categories/employees",
description: "Потоки данных ER ERP CRM CQRS UML BPMN",
available: true,
img: ArchitectureImg
},
{
title: "Дизайн проектов",
link: "/profile/categories/employees",
description:
"Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
available: true,
img: DesignImg
},
{
title: "Тестирование проектов",
link: "/profile/add-request",
description: "SQL Postman TestRail Kibana Ручное тестирование",
available: false,
img: TestImg
},
{
title: "Администрирование проектов",
link: "/profile/add-request",
description: "DevOps ELK Kubernetes Docker Bash Apache Oracle Git",
available: false,
img: AdminImg
},
{
title: "Управление проектом",
link: "/profile/add-request",
description: "Scrum Kanban Agile Miro CustDev",
available: false,
img: ManageImg
},
{
title: "Копирайтинг проектов",
link: "/profile/add-request",
description: "Теги Заголовок H1 Дескриптор Абзац Сценарий",
available: false,
img: CopyImg
},
{
title: "Реклама и SMM",
link: "/profile/add-request",
description:
"Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
available: false,
img: SmmImg
}
]);
const [staff, setStaff] = useState([]);
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
}
]);
useEffect(() => {
apiRequest("/project/my-employee").then((el) => {
setStaff(el.managerEmployees);
});
}, []);
// const [personalInfoItems] = useState([
// {
// title: "Backend разработчики",
// link: "/profile/categories/employees",
// description:
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
// available: true,
// img: BackEndImg
// },
// {
// title: "Frontend разработчики",
// link: "/profile/categories/employees",
// description:
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
// available: true,
// img: FrontendImg
// },
// {
// title: "Архитектура проектов",
// link: "/profile/categories/employees",
// description: "Потоки данных ER ERP CRM CQRS UML BPMN",
// available: true,
// img: ArchitectureImg
// },
// {
// title: "Дизайн проектов",
// link: "/profile/categories/employees",
// description:
// "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
// available: true,
// img: DesignImg
// },
// {
// title: "Тестирование проектов",
// link: "/profile/add-request",
// description: "SQL Postman TestRail Kibana Ручное тестирование",
// available: false,
// img: TestImg
// },
// {
// title: "Администрирование проектов",
// link: "/profile/add-request",
// description: "DevOps ELK Kubernetes Docker Bash Apache Oracle Git",
// available: false,
// img: AdminImg
// },
// {
// title: "Управление проектом",
// link: "/profile/add-request",
// description: "Scrum Kanban Agile Miro CustDev",
// available: false,
// img: ManageImg
// },
// {
// title: "Копирайтинг проектов",
// link: "/profile/add-request",
// description: "Теги Заголовок H1 Дескриптор Абзац Сценарий",
// available: false,
// img: CopyImg
// },
// {
// title: "Реклама и SMM",
// 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="partnerCategories">
<ProfileHeader />
@ -145,39 +154,49 @@ export const PartnerCategories = () => {
/>
<h2 className="partnerCategories__title">Данные персонала</h2>
<div className="partnerCategories__items">
{personalInfoItems.map((item, index) => {
{staff.map((card) => {
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>
</div>
<div className="item__info">
<p>{item.description}</p>
<div className="more">
<img src={rightArrow} alt="arrow" />
</div>
</div>
{!item.available && (
<div className="item__disableHover">
<p>У вас нет персонала из категории</p>
<button>Подобрать</button>
</div>
)}
</Link>
<PartnerPersonCard
key={card.id}
name={card.employee.fio}
img={card.employee.avatar}
userId={card.user_id}
/>
);
})}
{/*{personalInfoItems.map((item, index) => {*/}
{/* 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>*/}
{/* </div>*/}
{/* <div className="item__info">*/}
{/* <p>{item.description}</p>*/}
{/* <div className="more">*/}
{/* <img src={rightArrow} alt="arrow" />*/}
{/* </div>*/}
{/* </div>*/}
{/* {!item.available && (*/}
{/* <div className="item__disableHover">*/}
{/* <p>У вас нет персонала из категории</p>*/}
{/* <button>Подобрать</button>*/}
{/* </div>*/}
{/* )}*/}
{/* </Link>*/}
{/* );*/}
{/*})}*/}
</div>
</div>
<Footer />

View File

@ -13,10 +13,12 @@
&__items {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 25px;
row-gap: 24px;
column-gap: 21px;
//flex-wrap: wrap;
//margin-top: 25px;
//row-gap: 24px;
//column-gap: 21px;
}

View File

@ -214,7 +214,7 @@ export const ProjectTracker = () => {
function selectedTabTask(columnId, length) {
setSelectedTab(columnId);
dispatch(modalToggle("createTiketProject"));
dispatch(modalToggle("create-ticket-project"));
setModalAdd(true);
setPriorityTask(length);
}
@ -369,7 +369,7 @@ export const ProjectTracker = () => {
!path.find(
(div) =>
div.classList &&
(div.classList.contains("addPerson") ||
(div.classList.contains("add-person") ||
div.classList.contains("persons__list"))
)
) {
@ -489,12 +489,12 @@ export const ProjectTracker = () => {
<div className="tracker__tabs__content__tasks tasks active__content">
<div className="tasks__head">
<div className="tasks__head__wrapper">
<h5>Проект : {projectBoard.name}</h5>
<h5>{projectBoard.name}</h5>
<div className="tasks__head__add">
<BaseButton
onClick={() => {
dispatch(modalToggle("createColumn"));
dispatch(modalToggle("create-column"));
setModalAdd(true);
}}
styles={"button-add-column"}
@ -508,7 +508,7 @@ export const ProjectTracker = () => {
className={
projectBoard.projectUsers?.length
? "tasks__head__persons"
: "tasks__head__persons noProjectUsers"
: "tasks__head__persons no-project-users"
}
>
{Boolean(projectBoard.projectUsers?.length) && (
@ -538,7 +538,7 @@ export const ProjectTracker = () => {
<span className="countPersons">+1</span>
)}
<span
className="addPerson"
className="add-person"
onClick={() => {
setPersonListOpen(true);
}}
@ -765,7 +765,7 @@ export const ProjectTracker = () => {
)}
</div>
<Link to="/profile/tracker" className="tasks__head__back">
<p>Вернуться на проекты</p>
<p>К списку проектов</p>
<img src={arrow} alt="arrow" />
</Link>
</div>
@ -837,7 +837,7 @@ export const ProjectTracker = () => {
...prevState,
[column.id]: false
}));
dispatch(modalToggle("editColumn"));
dispatch(modalToggle("edit-column"));
dispatch(setColumnName(column.title));
dispatch(setColumnId(column.id));
dispatch(setColumnPriority(column.priority));
@ -964,17 +964,17 @@ export const ProjectTracker = () => {
/>
<span>
{task.comment_count}{" "}
{caseOfNum(
{/* {caseOfNum(
task.comment_count,
"comments"
)}
)} */}
</span>
</div>
<div className="tasks__board__item__info__more">
<img src={filesBoard} alt="filesImg" />
<span>
{task.files ? task.files : 0}{" "}
{caseOfNum(0, "files")}
{/* {caseOfNum(0, "files")} */}
</span>
</div>
</div>

View File

@ -114,7 +114,7 @@ const Statistics = () => {
<img src={arrow} alt="#" />
<Link to={`/profile/tracker`} className="return-text">
вернуться на все проекты
К списку проектов
</Link>
</div>
</div>

View File

@ -22,7 +22,7 @@ import TrackerModal from "@components/Modal/Tracker/TrackerModal/TrackerModal";
import { Navigation } from "@components/Navigation/Navigation";
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
import ProjectTiket from "@components/ProjectTiket/ProjectTiket";
import ProjectTicket from "@components/ProjectTicket/ProjectTicket";
import addProjectImg from "assets/icons/addProjectImg.svg";
import archiveTrackerProjects from "assets/icons/archiveTrackerProjects.svg";
@ -189,7 +189,7 @@ export const Tracker = () => {
!loader &&
projects?.map((project, index) => {
return project.status !== 10 ? (
<ProjectTiket key={index} project={project} />
<ProjectTicket key={index} project={project} />
) : (
""
);
@ -208,14 +208,14 @@ export const Tracker = () => {
</div>
<BaseButton
styles={"createProjectBtn"}
styles={"create-project-btn"}
onClick={() => {
dispatch(modalToggle("createProject"));
dispatch(modalToggle("create-project"));
setModalCreateProject(true);
}}
>
<img src={addProjectImg} alt="#"></img>
<p className="createProjectBtn__text">
<p className="create-project-btn__text">
Ставьте задачи, следите за прогрессом, ведите учёт
рабочего времени
</p>
@ -226,17 +226,14 @@ export const Tracker = () => {
{projects && Boolean(projects.length) && !loader && (
<>
<BaseButton
styles="createProjectBtn"
styles="create-project-btn"
onClick={() => {
dispatch(modalToggle("createProject"));
dispatch(modalToggle("create-project"));
setModalCreateProject(true);
}}
>
<img src={addProjectImg} alt="#"></img>
<p className="createProjectBtn__text">
Ставьте задачи, следите за прогрессом, ведите учёт рабочего
времени
</p>
<p className="create-project-btn__text">Добавить проект</p>
</BaseButton>
</>
)}
@ -321,11 +318,11 @@ export const Tracker = () => {
<div className="taskList__end">
<BaseButton styles={"close-day"}>
Закрыть сегоднящний день
Закрыть сегодняшний день
</BaseButton>
<p>
Нажимая кнопку - Закрыть сегодняшний день - вы отправляете
потрачеенное время на сверку
Нажимая кнопку Закрыть сегодняшний день, вы отправляете
потраченное время на сверку
</p>
</div>
</div>

View File

@ -130,7 +130,7 @@
&__content {
width: 100%;
background: #ffffff;
padding: 27px 0 29px;
padding: 15px 0;
margin-bottom: 50px;
&__wrapper {
@ -176,7 +176,7 @@
}
}
.createProjectBtn {
.create-project-btn {
max-width: 322px;
width: 322px;
height: 166px;
@ -276,7 +276,7 @@
&__add {
display: flex;
margin: 0 15px 0 10px;
margin: 0 10px 0 15px;
.button-add-column {
width: 33px;
@ -288,7 +288,7 @@
}
p {
margin-left: 14px;
margin-left: 5px;
font-weight: 300;
font-size: 14px;
line-height: 17px;
@ -306,11 +306,11 @@
}
}
.noProjectUsers {
.no-project-users {
@media (max-width: 900px) {
position: inherit;
.addPerson {
.add-person {
position: inherit;
}
@ -521,7 +521,7 @@
margin: 0 10px;
column-gap: 5px;
cursor: pointer;
padding: 5px 20px;
padding: 5px;
border-radius: 8px;
border: 1px solid #e3e2e2;
max-height: 30px;
@ -542,7 +542,7 @@
align-items: center;
justify-content: center;
display: flex;
background: #cbd9f9;
background: #99b4f3;
color: white;
font-size: 14px;
transition: all 0.15s ease;
@ -705,9 +705,9 @@
}
&__container {
padding: 30px 25px 30px;
padding: 10px;
display: flex;
column-gap: 25px;
column-gap: 15px;
margin: 0 auto;
overflow: auto;
max-width: 100%;
@ -730,9 +730,9 @@
}
@media (max-width: 900px) {
padding: 15px;
padding: 5px;
flex-direction: column;
row-gap: 25px;
row-gap: 15px;
transform: none;
}
}
@ -744,8 +744,7 @@
0px 1px 1px rgba(0, 0, 0, 0.06);
border-radius: 8px;
padding: 12px 10px 12px 8px;
min-width: 365px;
max-width: 380px;
width: 360px;
display: flex;
flex-direction: column;
row-gap: 10px;
@ -765,10 +764,10 @@
.tasksContainer {
display: flex;
flex-direction: column;
row-gap: 16px;
row-gap: 8px;
max-height: 750px;
overflow: auto;
padding: 8px;
padding: 5px;
&::-webkit-scrollbar {
width: 3px;
@ -798,7 +797,7 @@
&__item {
width: 328px;
padding: 16px;
padding: 6px 10px;
position: relative;
box-shadow: 0px 3px 2px -2px rgba(0, 0, 0, 0.06),
0px 5px 3px -2px rgba(0, 0, 0, 0.02);
@ -854,7 +853,7 @@
align-items: center;
justify-content: center;
font-size: 20px;
padding-bottom: 13px;
padding-bottom: 10px;
width: 24px;
height: 24px;
border: 1px solid #dddddd;
@ -862,11 +861,11 @@
}
&__description {
margin: 8px 0 4px;
margin: 4px 0;
color: #5c6165;
font-weight: 400;
font-size: 14px;
line-height: 140%;
line-height: 120%;
max-height: 100px;
overflow: hidden;
text-overflow: ellipsis;
@ -877,7 +876,7 @@
&__info {
display: flex;
justify-content: space-between;
column-gap: 10px;
align-items: center;
pointer-events: none;
@ -908,8 +907,8 @@
&__priority {
display: flex;
justify-content: space-between;
align-items: center;
column-gap: 5px;
margin-bottom: 8px;
p {
@ -938,8 +937,8 @@
&__deadLine {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
column-gap: 5px;
margin-bottom: 8px;
p {
font-weight: 500;
@ -955,12 +954,11 @@
&__executor {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0 15px;
padding-right: 10px;
margin-top: 2px;
font-size: 14px;
font-weight: 500;
column-gap: 5px;
span {
max-width: 210px;
@ -980,7 +978,7 @@
flex-wrap: wrap;
column-gap: 6px;
row-gap: 3px;
margin: 5px 0 10px;
margin: 5px 0 8px;
.tagItem {
padding: 3px 10px;
@ -1071,7 +1069,7 @@
img {
width: 27px;
height: 27px;
margin-right: 17px;
margin-right: 5px;
}
p {

View File

@ -15,12 +15,12 @@ import "./trackerAuth.scss";
export const TrackerAuth = () => {
const [modalResetOpen, setModalReset] = useState(false);
return (
<div className="trackerAuth">
<div className="tracker-auth">
<AuthHeader />
<SideBar />
<div className="trackerAuth__content">
<div className="tracker-auth__content">
<div className="container">
<h1 className="trackerAuth__title">
<h1 className="tracker-auth__title">
Войдите в свое{" "}
<span>
рабочее пространство

View File

@ -1,4 +1,4 @@
.trackerAuth {
.tracker-auth {
&__content {
font-family: "LabGrotesque", sans-serif;
background-color: #f1f1f1;

View File

@ -1,4 +1,8 @@
import React, { useState } from "react";
import { Navigate } from "react-router-dom";
import { useFormValidation } from "@hooks/useFormValidation";
import { useNotification } from "@hooks/useNotification";
import AuthHeader from "@components/Common/AuthHeader/AuthHeader";
import { Footer } from "@components/Common/Footer/Footer";
@ -14,54 +18,115 @@ import "./trackerRegistration.scss";
export const TrackerRegistration = () => {
const [modalConfirmOpen, setModalConfirm] = useState(false);
const [inputs, setInputs] = useState({
email: ""
const fields = {
username: "",
email: "",
password: "",
secondPassword: ""
};
const apiEndpoint = "/register/sign-up";
const { showNotification } = useNotification();
const showNotificationError = () => {
showNotification({
show: true,
text: "Аккаунт с таким логином или email уже существует",
type: "error"
});
};
const showNotificationTrue = () => {
showNotification({
show: true,
text: "Аккаунт успешно создан",
type: "success"
});
};
const { formData, validationErrors, handleChange, handleSubmit } =
useFormValidation(
apiEndpoint,
fields,
showNotificationError,
showNotificationTrue
);
return (
<div className="trackerRegistration">
<div className="tracker-registration">
<AuthHeader />
<SideBar />
<div className="trackerAuth__content">
<div className="tracker-auth__content">
<div className="container">
<h1 className="trackerAuth__title">
<h1 className="tracker-auth__title">
Создайте свое{" "}
<span>
рабочее пространство
<img src={arrowInfo} alt="arrow" />
</span>
</h1>
<div className="trackerRegistration__form">
<div className="trackerRegistration__form__inputs">
<div className="trackerRegistration__inputContainer">
<span>Ваше имя</span>
<input placeholder="Имя" />
</div>
<div className="trackerRegistration__inputContainer">
<span>Ваш e-mail</span>
<div className="tracker-registration__form">
<div className="tracker-registration__form__inputs">
<div className="tracker-registration__inputContainer">
<h5>Ваше имя</h5>
<input
placeholder="E-mail"
onChange={(e) =>
setInputs((prevState) => ({
...prevState,
email: e.target.value
}))
}
type="email"
placeholder="Имя"
className={validationErrors.username ? "error" : ""}
onChange={handleChange}
value={formData.username}
id="username"
/>
<span>{validationErrors.username}</span>
</div>
<div className="trackerRegistration__inputContainer">
<span>Придумайте пароль</span>
<input placeholder="Пароль" />
<div className="tracker-registration__inputContainer">
<h5>Ваш e-mail</h5>
<input
onChange={handleChange}
className={validationErrors.email ? "error" : ""}
placeholder="E-mail"
type="email"
id="email"
value={formData.email}
/>
<span>{validationErrors.email}</span>
</div>
<div className="trackerRegistration__inputContainer">
<span>Повторите пароль</span>
<input placeholder="Повторите пароль" />
<div className="tracker-registration__inputContainer">
<h5>Придумайте пароль</h5>
<input
placeholder="Пароль"
className={validationErrors.password ? "error" : ""}
onChange={handleChange}
value={formData.password}
type="password"
id="password"
/>
<span>{validationErrors.password}</span>
</div>
<div className="tracker-registration__inputContainer">
<h5>Повторите пароль</h5>
<input
placeholder="Повторите пароль"
className={validationErrors.secondPassword ? "error" : ""}
value={formData.secondPassword}
type="password"
onChange={handleChange}
id="secondPassword"
/>
<span>{validationErrors.secondPassword}</span>
</div>
</div>
<div className="trackerRegistration__form__submit">
<button onClick={() => setModalConfirm(true)}>Отправить</button>
<div className="trackerRegistration__form__info">
<div className="tracker-registration__form__submit">
<button
onClick={async (e) => {
e.preventDefault();
const result = await handleSubmit(e);
if (result === true) {
setModalConfirm(true);
}
}}
>
Отправить
</button>
<div className="tracker-registration__form__info">
<img src={authImg} alt="img" />
<p>
Создавайте и редактируйте задачи и проекты вместе с другими
@ -70,7 +135,7 @@ export const TrackerRegistration = () => {
</div>
</div>
<img
className="trackerRegistration__form__img"
className="tracker-registration__form__img"
src={registrationImg}
alt="img"
/>
@ -80,7 +145,7 @@ export const TrackerRegistration = () => {
<ModalLayout active={modalConfirmOpen} setActive={setModalConfirm}>
<ModalTrackerRegistration
setModalReset={setModalConfirm}
email={inputs.email}
email={formData.email}
/>
</ModalLayout>
)}

View File

@ -1,4 +1,4 @@
.trackerRegistration {
.tracker-registration {
&__content {
font-family: "LabGrotesque", sans-serif;
background-color: #f1f1f1;
@ -19,7 +19,7 @@
position: relative;
border-radius: 12px;
background: #FFF;
padding: 59px 115px 70px 102px;
padding: 20px;
@media (max-width: 1000px) {
display: flex;
@ -31,21 +31,17 @@
display: flex;
flex-wrap: wrap;
max-width: 650px;
row-gap: 25px;
column-gap: 44px;
@media (max-width: 1000px) {
order: 2;
}
@media (max-width: 6755px) {
margin-bottom: 35px;
}
}
&__submit {
display: flex;
align-items: center;
margin-top: 5px;
button {
border-radius: 44px;
@ -111,15 +107,18 @@
&__inputContainer {
display: flex;
flex-direction: column;
row-gap: 15px;
max-width: 300px;
width: 100%;
margin-bottom: 44px;
h5 {
font-size: 15px;
}
span {
font-weight: 400;
font-size: 15px;
color: #000;
font-size: 12px;
color: red;
}
input {
@ -127,6 +126,7 @@
padding: 8px 12px 9px;
background-color: #EFF2F7;
border-radius: 8px;
margin: 10px 0;
border: none;
font-weight: 400;
font-size: 15px;
@ -137,5 +137,9 @@
margin-bottom: 0;
max-width: none;
}
.error {
border: 1px solid red;
}
}
}

View File

@ -41,9 +41,7 @@ export const ViewReport = () => {
setDifficulties([]);
setTomorrowTask([]);
apiRequest(
`reports/find-by-date?user_card_id=${localStorage.getItem(
"cardId"
)}&date=${day}`
`reports/find-by-date?user_id=${localStorage.getItem("id")}&date=${day}`
).then((res) => {
let spendTime = 0;
for (const item of res) {