add ModalTicketToReport and add OpenRequest, fix
LandingTracker, fix url ModalTicket
This commit is contained in:
parent
b396201cdf
commit
a367f8b09c
@ -5,7 +5,7 @@ import React, { useEffect, useState } from "react";
|
||||
import DatePicker, { registerLocale } from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
|
||||
import { getProfileInfo } from "@redux/outstaffingSlice";
|
||||
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
|
||||
@ -44,6 +44,7 @@ import watch from "assets/icons/watch.svg";
|
||||
import avatarMok from "assets/images/avatarMok.webp";
|
||||
|
||||
import { getCorrectDate } from "../../../../utils/calendarHelper";
|
||||
import ModalTicketToReport from "../ModalTicketToReport/ModalTicketToReport";
|
||||
import "./modalTicket.scss";
|
||||
|
||||
registerLocale("ru", ru);
|
||||
@ -59,6 +60,8 @@ export const ModalTiсket = ({
|
||||
projectMarks
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const location = useLocation();
|
||||
|
||||
const [addSubtask, setAddSubtask] = useState(false);
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [inputsValue, setInputsValue] = useState({
|
||||
@ -87,6 +90,12 @@ export const ModalTiсket = ({
|
||||
minute: 0,
|
||||
seconds: 0
|
||||
});
|
||||
const additionalData = {
|
||||
id: task.id,
|
||||
title: inputsValue.title,
|
||||
link: null,
|
||||
nameProject: projectName
|
||||
};
|
||||
const [timerId, setTimerId] = useState(null);
|
||||
const [taskFiles, setTaskFiles] = useState([]);
|
||||
const [correctProjectUsers, setCorrectProjectUsers] = useState(projectUsers);
|
||||
@ -98,9 +107,21 @@ export const ModalTiсket = ({
|
||||
const [selectPriorityOpen, setSelectPriorityOpen] = useState(false);
|
||||
const { showNotification } = useNotification();
|
||||
const [commentSendDisable, setCommentSendDisable] = useState(false);
|
||||
const [showModalToReport, setShowModalToReport] = useState(false);
|
||||
|
||||
const openModalToReport = () => {
|
||||
setShowModalToReport(!showModalToReport);
|
||||
};
|
||||
|
||||
const closeModalToReport = () => {
|
||||
setShowModalToReport(!showModalToReport);
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
setActive(false);
|
||||
const currentUrl = window.location.pathname;
|
||||
const newUrl = currentUrl.replace(/\/task\/\d+$/, "");
|
||||
window.history.replaceState({}, "", newUrl);
|
||||
// Восстанавливаем скролл при закрытии модального окна
|
||||
document.body.style.overflow = "auto";
|
||||
};
|
||||
@ -1072,7 +1093,7 @@ export const ModalTiсket = ({
|
||||
</div>
|
||||
<div className="workers_box-bottom">
|
||||
<div
|
||||
className={editOpen ? "edit" : ""}
|
||||
className={`bottom-button ${editOpen ? "edit" : ""}`}
|
||||
onClick={() => {
|
||||
if (editOpen) {
|
||||
editTask();
|
||||
@ -1084,30 +1105,39 @@ export const ModalTiсket = ({
|
||||
<img src={edit}></img>
|
||||
<p>{editOpen ? "сохранить" : "редактировать"}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="bottom-button">
|
||||
<img src={link}></img>
|
||||
<p onClick={copyTicketLink}>ссылка на задачу</p>
|
||||
</div>
|
||||
<div className="bottom-button">
|
||||
<img src={link}></img>
|
||||
<p onClick={openModalToReport}>выгрузка в отчет</p>
|
||||
<ModalTicketToReport
|
||||
show={showModalToReport}
|
||||
onClose={closeModalToReport}
|
||||
additionalData={additionalData}
|
||||
></ModalTicketToReport>
|
||||
</div>
|
||||
<div
|
||||
onClick={archiveTask}
|
||||
className={
|
||||
className={`bottom-button ${
|
||||
profileInfo.id_user === projectOwnerId ||
|
||||
profileInfo.id_user === task.user_id
|
||||
? ""
|
||||
: "disable"
|
||||
}
|
||||
}`}
|
||||
>
|
||||
<img src={archive}></img>
|
||||
<p>в архив</p>
|
||||
</div>
|
||||
<div
|
||||
onClick={deleteTask}
|
||||
className={
|
||||
className={`bottom-button ${
|
||||
profileInfo.id_user === projectOwnerId ||
|
||||
profileInfo.id_user === task.user_id
|
||||
? ""
|
||||
: "disable"
|
||||
}
|
||||
}`}
|
||||
>
|
||||
<img src={del}></img>
|
||||
<p>удалить</p>
|
||||
|
@ -1178,33 +1178,35 @@
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
.bottom {
|
||||
&-button {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
|
||||
img {
|
||||
width: 11px;
|
||||
img {
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
|
||||
&.edit {
|
||||
background: #52b709;
|
||||
border-radius: 50px;
|
||||
width: fit-content;
|
||||
p {
|
||||
font-weight: 700;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
p:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
background: #52b709;
|
||||
border-radius: 50px;
|
||||
width: fit-content;
|
||||
p {
|
||||
font-weight: 700;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
p:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
import axios from "axios";
|
||||
import React, { useState } from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
|
||||
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
||||
|
||||
import "./modalTicketToReport.scss";
|
||||
|
||||
const ModalTicketToReport = ({ show, onClose, additionalData }) => {
|
||||
const [date, setDate] = useState(new Date());
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const data = {
|
||||
date,
|
||||
...additionalData
|
||||
};
|
||||
|
||||
try {
|
||||
await axios.post(
|
||||
"https://itguild.info/profile/calendar/reports/create",
|
||||
data
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`modal-report-backdrop ${show ? "show" : ""}`}
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
className="modal-report-content"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="modal-report-close" onClick={onClose}></div>
|
||||
<h2>Выгрузка в отчет</h2>
|
||||
<div className="modal-report-date-picker">
|
||||
<DatePicker
|
||||
className="datePicker"
|
||||
locale="ru"
|
||||
selected={date}
|
||||
onChange={(date) => setDate(date)}
|
||||
dateFormat="dd/MM/yyyy"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="modal-report__buttons">
|
||||
<BaseButton
|
||||
styles={"button-add add-person-btn "}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Выгрузить в отчет
|
||||
</BaseButton>
|
||||
<BaseButton
|
||||
styles={`button-add add-person-btn ${show ? "" : "disable"}`}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Выгрузить и перейти в отчет
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalTicketToReport;
|
@ -0,0 +1,167 @@
|
||||
.modal-report {
|
||||
&-backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
|
||||
&.show {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
cursor: auto;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
max-width: 500px;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&-close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
background: #263238;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
background: #263238;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
&-date-picker {
|
||||
// .datePicker {
|
||||
// visibility: hidden;
|
||||
// height: 0;
|
||||
// padding: 0;
|
||||
// width: 0;
|
||||
// position: absolute;
|
||||
// }
|
||||
|
||||
.react-datepicker-wrapper {
|
||||
// position: absolute;
|
||||
}
|
||||
|
||||
.react-datepicker {
|
||||
border: 1px solid #e8ede4;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.react-datepicker-popper {
|
||||
top: -150px !important;
|
||||
left: 180px !important;
|
||||
z-index: 10;
|
||||
|
||||
@media (max-width: 880px) {
|
||||
left: 0 !important;
|
||||
top: -15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.react-datepicker__current-month {
|
||||
font-size: 18px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.react-datepicker__navigation-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50px;
|
||||
border: 2px solid #cbd1d2;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.react-datepicker__navigation-icon--next::before {
|
||||
border-width: 2px 2px 0 0;
|
||||
top: auto;
|
||||
left: 4px;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.react-datepicker__navigation-icon--previous::before {
|
||||
border-width: 2px 2px 0 0;
|
||||
top: auto;
|
||||
left: 6px;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.react-datepicker__header {
|
||||
padding: 5px 0 10px;
|
||||
border-bottom: 1px solid #baacc0;
|
||||
}
|
||||
|
||||
.react-datepicker__day {
|
||||
font-size: 16px;
|
||||
width: 35px;
|
||||
border-radius: 50px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.react-datepicker__day-name {
|
||||
font-size: 18px;
|
||||
width: 35px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.react-datepicker__triangle {
|
||||
display: none;
|
||||
// left: 85px !important;
|
||||
|
||||
// &:before {
|
||||
// border: 1px solid #e8ede4;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
&__buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 100px;
|
||||
margin: 30px 0;
|
||||
|
||||
.button {
|
||||
height: 47px;
|
||||
font-size: 15px;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -106,14 +106,7 @@ const TrackerCardTask = ({
|
||||
onDrop={(e) => dragDropTaskHandler(e, task, column)}
|
||||
onClick={(e) => openTicket(e, task)}
|
||||
>
|
||||
<div
|
||||
className="tasks__board__item__title"
|
||||
onClick={() => {
|
||||
if (window.innerWidth < 985) {
|
||||
window.location.replace(`/tracker/task/${task.id}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="tasks__board__item__title">
|
||||
<p className="task__board__item__title">{task.title}</p>
|
||||
</div>
|
||||
<p
|
||||
|
@ -84,7 +84,9 @@ export const LandingTracker = () => {
|
||||
<h3>
|
||||
ITGu <br /> ild
|
||||
</h3>
|
||||
<img className="intro-logo__cup" src={trackerCup} alt="" />
|
||||
<div className="intro-logo__cup">
|
||||
<img src={trackerCup} alt="" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="intro-content">
|
||||
<div className="intro-content__sublogo">
|
||||
|
@ -57,6 +57,32 @@
|
||||
position: absolute;
|
||||
bottom: -85px;
|
||||
right: -150px;
|
||||
|
||||
&::before {
|
||||
content: "Не нужно заваривать мышь";
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
top: 100px;
|
||||
left: -80px;
|
||||
width: 182px;
|
||||
height: 106px;
|
||||
border-radius: 8px;
|
||||
border: 0.5px solid #ffffff;
|
||||
background: linear-gradient(
|
||||
110.06deg,
|
||||
rgba(255, 255, 255, 0.34) 0%,
|
||||
rgba(199, 206, 198, 0.34) 99.25%
|
||||
);
|
||||
backdrop-filter: blur(8.6999998093px);
|
||||
box-shadow: 10px 9px 14px 0 rgba(0, 0, 0, 0.06);
|
||||
padding: 0 15px;
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
line-height: 19.72px;
|
||||
letter-spacing: 0.01em;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
32
src/pages/OpenRequests/OpenRequest.jsx
Normal file
32
src/pages/OpenRequests/OpenRequest.jsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from "react";
|
||||
|
||||
import { Footer } from "@components/Common/Footer/Footer";
|
||||
import { Navigation } from "@components/Navigation/Navigation";
|
||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||
|
||||
import "./OpenRequest.scss";
|
||||
|
||||
export const OpenRequest = () => {
|
||||
return (
|
||||
<div className="open-request">
|
||||
<ProfileHeader />
|
||||
<Navigation />
|
||||
<div className="container">
|
||||
<div className="open-request-content">
|
||||
<ProfileBreadcrumbs
|
||||
links={[
|
||||
{ name: "Главная", link: "/profile" },
|
||||
{
|
||||
name: "Работа в IT открытые запросы",
|
||||
link: "/profile/open-request"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
<h2 className="summary__title">Работа в IT открытые запросы</h2>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
};
|
0
src/pages/OpenRequests/OpenRequest.scss
Normal file
0
src/pages/OpenRequests/OpenRequest.scss
Normal file
@ -29,7 +29,7 @@ export const Profile = () => {
|
||||
const [profileItemsInfo] = useState({
|
||||
developer: [
|
||||
{
|
||||
path: "profile",
|
||||
path: "profile/open-requests",
|
||||
img: paymentIcon,
|
||||
title: "Работа в IT <br/>открытые запросы",
|
||||
description: "Перейдите чтобы посмотреть <br/>открытые позиции"
|
||||
|
@ -1,7 +1,7 @@
|
||||
import moment from "moment";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import {
|
||||
activeLoader,
|
||||
@ -51,6 +51,8 @@ import avatarMok from "assets/images/avatarMok.webp";
|
||||
export const ProjectTracker = () => {
|
||||
const dispatch = useDispatch();
|
||||
const projectId = useParams();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [openColumnSelect, setOpenColumnSelect] = useState({});
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
@ -97,6 +99,24 @@ export const ProjectTracker = () => {
|
||||
} else {
|
||||
setFilteredNoTasks(false);
|
||||
}
|
||||
|
||||
const path = location.pathname;
|
||||
const match = path.match(/\/task\/(\d+)/);
|
||||
console.log(match);
|
||||
if (match) {
|
||||
const extractedTaskId = match[1];
|
||||
|
||||
console.log(extractedTaskId);
|
||||
// Убираем /task/id из URL
|
||||
const newUrl = path.replace(/\/task\/\d+/, "");
|
||||
navigate(newUrl, { replace: true });
|
||||
|
||||
// Открываем тикет
|
||||
console.log("asd", projectBoard);
|
||||
const Dtask = tasks.find((task) => task.id === extractedTaskId);
|
||||
console.log("asd", Dtask);
|
||||
// openTicket(extractedTaskId);
|
||||
}
|
||||
}, [projectBoard]);
|
||||
|
||||
function dragOverHandler(e) {
|
||||
@ -148,9 +168,16 @@ export const ProjectTracker = () => {
|
||||
function openTicket(e, task) {
|
||||
setSelectedTicket(task);
|
||||
setModalActiveTicket(true);
|
||||
const currentUrl = window.location.pathname;
|
||||
const newUrl = `${currentUrl}/task/${task.id}`;
|
||||
window.history.pushState({}, "", newUrl);
|
||||
document.body.style.overflow = "hidden";
|
||||
}
|
||||
|
||||
// useEffect(() => {
|
||||
|
||||
// }, [location]);
|
||||
|
||||
function deleteColumn(column) {
|
||||
const priorityColumns = [];
|
||||
apiRequest("/project-column/update-column", {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
import { Navigate, Route, Routes } from "react-router-dom";
|
||||
import { Route, Routes } from "react-router-dom";
|
||||
|
||||
import { OpenRequest } from "@pages/OpenRequests/openRequest";
|
||||
import { PartnerSettings } from "@pages/PartnerSettings/PartnerSettings";
|
||||
import { PartnerTreaties } from "@pages/PartnerTreaties/PartnerTreaties";
|
||||
import { Payouts } from "@pages/Payouts/Payouts";
|
||||
@ -14,7 +15,6 @@ import { Summary } from "@pages/Summary/Summary";
|
||||
import { Tracker } from "@pages/Tracker/Tracker";
|
||||
import { ViewReport } from "@pages/ViewReport/ViewReport";
|
||||
|
||||
import { TicketFullScreen } from "@components/Modal/Tracker/TicketFullScreen/TicketFullScreen";
|
||||
import { ProfileCalendar } from "@components/ProfileCalendar/ProfileCalendar";
|
||||
import { ReportForm } from "@components/ReportForm/ReportForm";
|
||||
|
||||
@ -23,9 +23,10 @@ export const DeveloperPage = () => {
|
||||
<Routes>
|
||||
<Route
|
||||
exact
|
||||
path="/tracker/task/:id"
|
||||
element={<TicketFullScreen />}
|
||||
></Route>
|
||||
path="/tracker/project/:id/task/:taskId"
|
||||
element={<ProjectTracker />}
|
||||
/>
|
||||
|
||||
<Route exact path="/tracker/project/:id" element={<ProjectTracker />} />
|
||||
|
||||
<Route exact path="profile">
|
||||
@ -33,6 +34,7 @@ export const DeveloperPage = () => {
|
||||
<Route exact path="calendar" element={<ProfileCalendar />} />
|
||||
<Route exact path="calendar/report" element={<ReportForm />} />
|
||||
<Route exact path="calendar/view/:date/:id" element={<ViewReport />} />
|
||||
<Route exact path="open-requests" element={<OpenRequest />} />
|
||||
<Route exact path="summary" element={<Summary />} />
|
||||
<Route exact path="tracker" element={<Tracker />} />
|
||||
<Route exact path="statistics/:id" element={<Statistics />} />
|
||||
@ -45,7 +47,7 @@ export const DeveloperPage = () => {
|
||||
<Route exact path="report/:uuid" element={<QuizReportPage />} />
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="*" element={<Navigate to="/profile" replace />} />
|
||||
{/* <Route path="*" element={<Navigate to="/profile" replace />} /> */}
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
@ -19,7 +19,6 @@ import { ViewReport } from "@pages/ViewReport/ViewReport";
|
||||
|
||||
import { Calendar } from "@components/Calendar/Calendar";
|
||||
import { Candidate } from "@components/Candidate/Candidate";
|
||||
import { TicketFullScreen } from "@components/Modal/Tracker/TicketFullScreen/TicketFullScreen";
|
||||
|
||||
export const PartnerPage = () => {
|
||||
return (
|
||||
@ -28,11 +27,6 @@ export const PartnerPage = () => {
|
||||
<Route exact path="/candidate/:id/form" element={<FormPage />} />
|
||||
<Route path="/:userId/calendar" element={<Calendar />} />
|
||||
|
||||
<Route
|
||||
exact
|
||||
path="/tracker/task/:id"
|
||||
element={<TicketFullScreen />}
|
||||
></Route>
|
||||
<Route exact path="/tracker/project/:id" element={<ProjectTracker />} />
|
||||
|
||||
<Route exact path="profile">
|
||||
|
Loading…
Reference in New Issue
Block a user