diff --git a/src/components/Common/ModalLayout/ModalLayout.jsx b/src/components/Common/ModalLayout/ModalLayout.jsx index 44c2bbf8..2b7c12f6 100644 --- a/src/components/Common/ModalLayout/ModalLayout.jsx +++ b/src/components/Common/ModalLayout/ModalLayout.jsx @@ -5,19 +5,25 @@ import "./modalLayout.scss"; export const ModalLayout = ({ active, setActive, + onClose, children, styles, type, ...props }) => { + const handleClose = (event) => { + if (event.target.className === "modal-layout active") { + setActive(false); + if (onClose) { + onClose(); // Вызов колбэк-функции при закрытии модального окна + } + } + }; + return (
{ - if (event.target.className === "modal-layout active") { - setActive(false); - } - }} + onClick={handleClose} {...props} >
{ + setActive(false); + // Восстанавливаем скролл при закрытии модального окна + document.body.style.overflow = "auto"; + }; + + const [isExpanded, setIsExpanded] = useState(false); + + const toggleModalSize = () => { + setIsExpanded((prevState) => !prevState); + }; + function deleteTask() { apiRequest("/task/update-task", { method: "PUT", @@ -107,7 +119,7 @@ export const ModalTiсket = ({ status: 0 } }).then(() => { - setActive(false); + closeModal(); dispatch(setProjectBoardFetch(projectId)); showNotification({ show: true, @@ -594,20 +606,20 @@ export const ModalTiсket = ({
{ - if (e.target.className.includes("modal-ticket")) setActive(false); + if (e.target.className.includes("modal-ticket")) closeModal(); }} > -
+

{projectName} - - - + />

{editOpen ? ( @@ -757,7 +769,7 @@ export const ModalTiсket = ({
- setActive(false)}> + closeModal()}>
Создатель:

{task.user?.fio}

{executor ? ( diff --git a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss index c097afd0..8482406d 100644 --- a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss +++ b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss @@ -15,13 +15,20 @@ display: flex; } +.modal-ticket__content.expanded { + width: 100vw; + height: 100vh; + max-height: none; + max-width: none; +} + .modal-ticket__content { background: #ffffff; border-radius: 8px; display: flex; flex-direction: row; max-height: 700px; - // overflow-y: auto; + max-width: 915px; @media (max-width: 990px) { width: 96%; @@ -52,7 +59,7 @@ position: relative; display: flex; flex-direction: column; - width: 630px; + width: 68%; margin: 26px 0 0 21px; .title-project { @@ -160,7 +167,6 @@ .comments__list { display: flex; - overflow-y: auto; height: 190px; flex-direction: column; @@ -364,7 +370,6 @@ column-gap: 25px; row-gap: 20px; margin-top: 33px; - overflow-y: auto; .task-file { cursor: pointer; @@ -607,6 +612,7 @@ .workers { position: relative; border-left: 1px solid #f1f1f1; + width: 32%; .exit { cursor: pointer; diff --git a/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx b/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx index 0704694b..db73ff4a 100644 --- a/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx +++ b/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx @@ -72,6 +72,7 @@ export const TrackerModal = ({ const [selectWorkersOpen, setSelectWorkersOpen] = useState(false); const [selectedWorker, setSelectedWorker] = useState(null); const [emailWorker, setEmailWorker] = useState(""); + const [emailError, setEmailError] = useState(""); const [selectColumnPriority, setSelectColumnPriority] = useState( "Выберите приоритет колонки" ); @@ -114,6 +115,19 @@ export const TrackerModal = ({ return; } + const existingColumn = projectBoard.columns.find( + (column) => column.title === valueColumn + ); + + if (existingColumn) { + showNotification({ + show: true, + text: "Колонка с таким названием уже существует", + type: "error" + }); + return; + } + apiRequest("/project-column/create-column", { method: "POST", data: { @@ -325,19 +339,6 @@ export const TrackerModal = ({ setActive(false); setSelectedWorker(""); setSelectWorkersOpen(false); - }); - } - - function inviteUserByEmail() { - apiRequest("/project/add-user-by-email", { - method: "POST", - data: { - email: emailWorker, - project_id: projectBoard.id - } - }).then((el) => { - setActive(false); - setEmailWorker(""); showNotification({ show: true, text: "Приглашение отправлено", @@ -346,6 +347,35 @@ export const TrackerModal = ({ }); } + const validateEmail = (email) => { + // Простая валидация адреса электронной почты + const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + return emailPattern.test(email); + }; + + const inviteUserByEmail = () => { + if (validateEmail(emailWorker)) { + setEmailError(""); + apiRequest("/project/add-user-by-email", { + method: "POST", + data: { + email: emailWorker, + project_id: projectBoard.id + } + }).then((el) => { + setActive(false); + setEmailWorker(""); + showNotification({ + show: true, + text: "Приглашение отправлено", + type: "success" + }); + }); + } else { + setEmailError("Некорректный e-mail адрес"); + } + }; + useEffect(() => { modalType === "add-worker" ? apiRequest("/project/my-employee").then((el) => { @@ -426,8 +456,18 @@ export const TrackerModal = ({ } }; + const handleModalClose = () => { + setEmailError(""); + setEmailWorker(""); + }; + return ( - + {modalType === "add-worker" && ( <>
@@ -498,6 +538,7 @@ export const TrackerModal = ({ value={emailWorker} onChange={(e) => setEmailWorker(e.target.value)} /> +
{emailError}
)} - setActive(false)}> + { + setActive(false); + setEmailError(""); + setEmailWorker(""); + }} + >
); }; diff --git a/src/components/Modal/Tracker/TrackerModal/trackerModal.scss b/src/components/Modal/Tracker/TrackerModal/trackerModal.scss index f1bbe9e0..160178ea 100644 --- a/src/components/Modal/Tracker/TrackerModal/trackerModal.scss +++ b/src/components/Modal/Tracker/TrackerModal/trackerModal.scss @@ -227,6 +227,7 @@ min-width: 240px; height: 42px; width: 100%; + margin: 10px 0 10px 0; p { overflow: hidden; diff --git a/src/components/ProfileHeader/ProfileHeader.jsx b/src/components/ProfileHeader/ProfileHeader.jsx index 7bc3a26d..30a41815 100644 --- a/src/components/ProfileHeader/ProfileHeader.jsx +++ b/src/components/ProfileHeader/ProfileHeader.jsx @@ -110,6 +110,10 @@ export const ProfileHeader = () => { } }; + const closeMenu = () => { + setActive(false); + }; + return (
@@ -179,6 +183,7 @@ export const ProfileHeader = () => {
+ {active &&
}
); }; diff --git a/src/components/ProfileHeader/profileHeader.scss b/src/components/ProfileHeader/profileHeader.scss index b76ee8a5..1e330ba3 100644 --- a/src/components/ProfileHeader/profileHeader.scss +++ b/src/components/ProfileHeader/profileHeader.scss @@ -17,7 +17,6 @@ justify-content: space-between; align-items: center; height: 100%; - z-index: 9; max-width: 1160px; width: 100%; margin: 0 auto; @@ -36,6 +35,7 @@ @media (max-width: 414px) { display: block; + z-index: 9; } &__line { @@ -64,9 +64,19 @@ background: white; } + .backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 7; + } + .auth-body { opacity: 0; - z-index: 99; + z-index: 8; position: absolute; top: 0; right: 0; @@ -99,7 +109,7 @@ flex-direction: column; a { - padding: 10px 0 0 0; + padding: 15px 0 0 10px; } a, @@ -134,7 +144,7 @@ opacity: 1; display: flex; overflow: visible; - width: calc(100vw / 3); + width: calc(100vw / 2.5); transition: width 0.3s; height: 100%; flex-direction: column; @@ -188,6 +198,7 @@ &__logout-burger { background: none; border: none; + padding: 15px 0 0 0; font-weight: 500; font-size: 16px; line-height: 32px; diff --git a/src/pages/ProjectTracker/ProjectTracker.jsx b/src/pages/ProjectTracker/ProjectTracker.jsx index 97c79530..c48af8db 100644 --- a/src/pages/ProjectTracker/ProjectTracker.jsx +++ b/src/pages/ProjectTracker/ProjectTracker.jsx @@ -224,11 +224,9 @@ export const ProjectTracker = () => { } function openTicket(e, task) { - if (window.innerWidth < 985) { - return; - } setSelectedTicket(task); setModalActiveTicket(true); + document.body.style.overflow = "hidden"; } function deleteColumn(column) {