From e1679a769c1ea857962e8061f4e38341ccf8b137 Mon Sep 17 00:00:00 2001 From: ReactRay Date: Sat, 18 Jan 2025 06:02:47 +0200 Subject: [PATCH 1/3] little style update to tasks/groups --- src/cmps/BoardDetails.jsx | 8 +- src/cmps/GroupPreview.jsx | 30 ++++-- src/cmps/dynamicCmps/Date.jsx | 11 ++- src/cmps/dynamicCmps/TaskTitle.jsx | 82 ++++++++-------- src/cmps/dynamicCmps/modals/DateModal.jsx | 17 ++-- src/styles/_Board-details.scss | 97 +++++++++++-------- src/styles/dynamicCmps/TaskTitle.scss | 7 +- src/styles/dynamicCmps/_Members.scss | 45 ++++----- src/styles/dynamicCmps/_Status.scss | 27 +++--- src/styles/dynamicCmps/modals/_ChatModal.scss | 17 ++-- 10 files changed, 178 insertions(+), 163 deletions(-) diff --git a/src/cmps/BoardDetails.jsx b/src/cmps/BoardDetails.jsx index 92c01f4..e8fcdae 100644 --- a/src/cmps/BoardDetails.jsx +++ b/src/cmps/BoardDetails.jsx @@ -49,12 +49,12 @@ const BoardDetails = () => { const onTaskUpdate = async (changeInfo) => await updateTask(currentBoard.id, changeInfo); - const cmpOrder = ["taskTitle", "priority", "status", "members", "date"]; + const cmpOrder = ["taskTitle", "priority", "status", "members", "date", "+"]; const uid = () => Math.random().toString(36).slice(2); - const labels = ["item", "priority", "status", "members", "date"]; + const labels = ["item", "priority", "status", "members", "date", "+"]; - const progress = [null, null, "priority", "status", null, "date"]; + const progress = [null, null, "priority", "status", 'nothing', 'nothing', 'nothing']; const handleCheckBoxClick = (groupId, taskId) => { console.log(groupId, taskId); @@ -120,7 +120,7 @@ const BoardDetails = () => { return (
- +
{groups.map((group) => ( { }} onClick={() => handleMasterCheckboxClick(group)} checked={checkedGroups.includes(group.id)} + /> {cmpOrder.map((cmp, index) => ( -
{labels[index] || ""}
+
{labels[index] || ""}
))}
{/* Render tasks by cmp order */} {group.tasks.map((task) => ( +
) + case "+": + return ( +
+ +
+ ) default: console.error(`Unknown component type: ${cmpType}`); diff --git a/src/cmps/dynamicCmps/Date.jsx b/src/cmps/dynamicCmps/Date.jsx index 9a4e0c4..5d4c395 100644 --- a/src/cmps/dynamicCmps/Date.jsx +++ b/src/cmps/dynamicCmps/Date.jsx @@ -13,8 +13,8 @@ export function Date({ cellId, group, task, date, onTaskUpdate }) { // close and open modal as needed function modalToggle() { modal - ? openModal(null) - : openModal(cellId) + ? openModal(null) + : openModal(cellId) } function onDateChange(date) { @@ -23,12 +23,14 @@ export function Date({ cellId, group, task, date, onTaskUpdate }) { } function handleClickOutsideModal(event) { - if ( modalRef.current && + if (modalRef.current && !modalRef.current.contains(event.target) && !dateCellRef.current.contains(event.target) ) modalToggle() } + + useEffect(() => { if (modal) { document.addEventListener('mousedown', handleClickOutsideModal); @@ -42,8 +44,6 @@ export function Date({ cellId, group, task, date, onTaskUpdate }) { - - return (
{/* Date cell */} @@ -51,6 +51,7 @@ export function Date({ cellId, group, task, date, onTaskUpdate }) { className="date-cell" ref={dateCellRef} onClick={modalToggle}> + {date}
diff --git a/src/cmps/dynamicCmps/TaskTitle.jsx b/src/cmps/dynamicCmps/TaskTitle.jsx index 3a27786..cbb7475 100644 --- a/src/cmps/dynamicCmps/TaskTitle.jsx +++ b/src/cmps/dynamicCmps/TaskTitle.jsx @@ -1,20 +1,18 @@ -import {useState, useRef, useEffect } from "react" +import { useState, useRef, useEffect } from "react" import { showErrorMsg } from '../../services/event-bus.service.js' import { ChatModal } from "./modals/ChatModal.jsx" import ChatIcon from '@mui/icons-material/MapsUgcOutlined'; import { openModal } from '../../store/actions/boards.actions.js' import { useSelector } from "react-redux"; -export function TaskTitle ({cellId, - users, - loggedinUser, - chat, - group, - task, - text, - onTaskUpdate }) - - { +export function TaskTitle({ cellId, + users, + loggedinUser, + chat, + group, + task, + text, + onTaskUpdate }) { const [onEditMode, setOnEditMode] = useState(false) const [textToEdit, setTextToEdit] = useState(text) @@ -24,12 +22,12 @@ export function TaskTitle ({cellId, const modalRef = useRef(null) const ChatButtonRef = useRef(null) - // close and open modal as needed - function modalToggle() { - modal - ? openModal(null) - : openModal(cellId) - } + // close and open modal as needed + function modalToggle() { + modal + ? openModal(null) + : openModal(cellId) + } function handleClickOutsideModal(event) { if (!modalRef.current.contains(event.target) @@ -47,17 +45,18 @@ export function TaskTitle ({cellId, }, [modal]) - function onAddComment(comment){ - const newComment = {userId: loggedinUser.id, - sentAt: new Date().getTime(), - text: comment, - replies:[] + function onAddComment(comment) { + const newComment = { + userId: loggedinUser.id, + sentAt: new Date().getTime(), + text: comment, + replies: [] } - onTaskUpdate({group, task, type:'chat', value: [newComment, ...chat]}) + onTaskUpdate({ group, task, type: 'chat', value: [newComment, ...chat] }) } - function onAddReply(commentSentTime, replyTxt){ - const newReply = {userId: loggedinUser.id, sentAt: new Date().getTime(), text: replyTxt} + function onAddReply(commentSentTime, replyTxt) { + const newReply = { userId: loggedinUser.id, sentAt: new Date().getTime(), text: replyTxt } const updatedChat = chat.map(comment => { return comment.sentAt === commentSentTime ? { ...comment, replies: [newReply, ...comment.replies] } @@ -106,13 +105,13 @@ export function TaskTitle ({cellId, } } - function onUpdateTitleInChat(text){ + function onUpdateTitleInChat(text) { onTaskUpdate({ group, task, type: 'taskTitle', value: text }) } return ( <> -
+
{ !onEditMode @@ -127,25 +126,26 @@ export function TaskTitle ({cellId, /> }
-
+
{/*chat modal*/} - {modal && -
- -
- } + { + modal && +
+ +
+ } ) diff --git a/src/cmps/dynamicCmps/modals/DateModal.jsx b/src/cmps/dynamicCmps/modals/DateModal.jsx index 939721f..1814e8d 100644 --- a/src/cmps/dynamicCmps/modals/DateModal.jsx +++ b/src/cmps/dynamicCmps/modals/DateModal.jsx @@ -7,18 +7,15 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import dayjs from 'dayjs'; -export function DateModal({currentDate, onDateChange }) { +export function DateModal({ currentDate, onDateChange }) { - // the currant day on date cell that convert to dayjs style that DateCalendar supports - const [newJday,setNewJday] = useState(dayjs(currentDate, 'DD-MM-YYYY')) + const [newJday, setNewJday] = useState(dayjs(currentDate, 'DD-MM-YYYY')) - // fixing some library problem with DD-MM form... - useEffect(()=>{ + useEffect(() => { setNewJday(dayjs(currentDate, 'DD-MM-YYYY')) - },[currentDate]) + }, [currentDate]) const handleDateChange = newDate => { - // Format the date to MM-DD-YYYY const formattedDate = newDate.format('DD-MM-YYYY') onDateChange(formattedDate) } @@ -26,9 +23,9 @@ export function DateModal({currentDate, onDateChange }) { return (
- +
) diff --git a/src/styles/_Board-details.scss b/src/styles/_Board-details.scss index 65d5da1..e88d105 100644 --- a/src/styles/_Board-details.scss +++ b/src/styles/_Board-details.scss @@ -1,24 +1,53 @@ /* Main Grid */ .grid { display: grid; - grid-template-columns: 40px 175px repeat(4, 1fr); /* Match grid structure */ - // justify-content: center; - background: white; /* Background for grid */ + grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-rows: 34px; + + background: white; border-left: 0.3rem rgb(148, 182, 210) solid; } +.labels-grid { + display: grid; + grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-rows: 34px; + + width: 100%; +} + +.progress-grid { + display: grid; + grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-rows: 34px; + width: 100%; /* Set a fixed width */ +} + +.group-list { + font-size: 13px; + padding: 3rem 0; + width: 200vh; + + & input[type='checkbox'] { + width: 20px; + height: 20px; + display: flex; + align-self: center; + justify-self: center; + cursor: pointer; + } +} -.board-details{ +.board-details { display: flex; flex-direction: column; background-color: white; border-top-left-radius: 12px; - padding-left: 3rem; + padding-left: 2rem; } - /* Grid Items */ .grid-item { - border: 1px solid #d3d3d3; /* Border for individual cells */ text-align: center; + border-left: 1px solid #e0dede; display: flex; align-items: center; justify-content: center; @@ -61,19 +90,6 @@ } /* Labels and Progress Sections */ -.labels-grid { - display: grid; - grid-template-columns: 40px 175px repeat(4, 1fr); /* Match grid structure */ - border: 1px solid #eae6e6; - border-left: 0.3rem rgb(148, 182, 210) solid; - width: 100%; /* Set a fixed width */ -} - -.progress-grid { - display: grid; - grid-template-columns: 40px 175px repeat(4, 1fr); /* Match grid structure */ - width: 100%; /* Set a fixed width */ -} .prog-box { border: 1px solid #e0dede; /* Ensure cell borders match */ @@ -88,28 +104,12 @@ } .labels-grid div { - border: 1px solid #e0dede; /* Ensure cell borders match */ + border-left: 1px solid #e0dede; /* Ensure cell borders match */ padding: 0.7rem; text-align: center; font-weight: 800; } -.group-list { - font-size: 13px; - font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; - width: 100%; /* Set a fixed width */ - padding: 1rem 0; - padding-right: 1rem; - & input[type='checkbox'] { - width: 20px; - height: 20px; - display: flex; - align-self: center; - justify-self: center; - cursor: pointer; - } -} - div { font-family: 'Quicksand'; font-weight: 500; @@ -183,7 +183,7 @@ div { .add-input { border: none; - padding: 1rem 1rem; + padding: 0.5rem 3rem; } .modal-save-btn { @@ -217,5 +217,24 @@ div { } .checkbox { - border: 1px solid #333; + border: 1px solid #e0dddd; +} + +.nothing { + border: 1px solid #e1dede; +} + +.add-column { +} + +.add-task { + opacity: 0.5; + border-top: 1px solid #e0dede; +} + +.chat-icon { + color: rgb(128, 128, 128); + cursor: pointer; + border-left: 1px solid #e1e1e1; + padding: 0.2rem 1rem; } diff --git a/src/styles/dynamicCmps/TaskTitle.scss b/src/styles/dynamicCmps/TaskTitle.scss index ecc8787..8af03aa 100644 --- a/src/styles/dynamicCmps/TaskTitle.scss +++ b/src/styles/dynamicCmps/TaskTitle.scss @@ -3,13 +3,12 @@ .grid-item.taskTitle { .task-title { width: 100%; - height: 100%; display: flex; align-items: center; justify-content: space-between; .title-part { - padding: 10px; + padding: 0 10px; } button { @@ -29,10 +28,6 @@ display: flex; } -.chat-btn { - width: 20%; -} - .task-title-flex { width: 100%; height: 100%; diff --git a/src/styles/dynamicCmps/_Members.scss b/src/styles/dynamicCmps/_Members.scss index 3710159..bb37483 100644 --- a/src/styles/dynamicCmps/_Members.scss +++ b/src/styles/dynamicCmps/_Members.scss @@ -1,29 +1,26 @@ -@use "./modals/MembersModal"; +@use './modals/MembersModal'; -.grid-item.members{ +.grid-item.members { + .members { + width: 100%; + height: 100%; + color: white; - .members{ - width: 100%; - height: 100%; - color: white; + .members-cell { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + margin-left: 5px; - .members-cell{ - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - margin-left: 5px; - - img{ - width: 35px; - height: 35px; - border-radius: 50%; - border: solid white 2px; - margin-left: -10px; - - } - - } + img { + width: 35px; + height: 35px; + border-radius: 50%; + border: solid white 2px; + margin-left: -10px; + } } + } } diff --git a/src/styles/dynamicCmps/_Status.scss b/src/styles/dynamicCmps/_Status.scss index a84c82b..9757238 100644 --- a/src/styles/dynamicCmps/_Status.scss +++ b/src/styles/dynamicCmps/_Status.scss @@ -1,19 +1,16 @@ -@use "./modals/StatusModal"; +@use './modals/StatusModal'; -.grid-item.status{ +.grid-item.status { + .status { + width: 100%; + height: 100%; + color: white; - .status{ - width: 100%; - height: 100%; - color: white; - - .status-cell{ - display: grid; - align-items: center; - width: 100%; - height: 100%; - - } + .status-cell { + display: grid; + align-items: center; + width: 100%; + height: 100%; } + } } - diff --git a/src/styles/dynamicCmps/modals/_ChatModal.scss b/src/styles/dynamicCmps/modals/_ChatModal.scss index efb06c4..c591e70 100644 --- a/src/styles/dynamicCmps/modals/_ChatModal.scss +++ b/src/styles/dynamicCmps/modals/_ChatModal.scss @@ -17,7 +17,7 @@ list-style: none; } - .exis-button{ + .exis-button { margin-bottom: 10px; display: flex; width: 25px; @@ -33,14 +33,13 @@ align-items: start; width: 100%; text-align: left; - + textarea { font-size: 30px; width: 100%; padding: 10px; } } - .create-comment { display: flex; @@ -130,16 +129,15 @@ .create-reply { margin-top: 30px; display: flex; - gap:10px; + gap: 10px; - img{ + img { width: 35px; height: 35px; border-radius: 50%; } - form{ - + form { display: flex; flex-direction: column; width: 100%; @@ -154,15 +152,12 @@ border: none; outline: none; } - + button { width: 50px; align-self: end; } - } - - } } } From 992db36864f3d9c16d21916ae0982ee6630c8137 Mon Sep 17 00:00:00 2001 From: ReactRay Date: Sat, 18 Jan 2025 06:07:17 +0200 Subject: [PATCH 2/3] made images smaller --- src/styles/dynamicCmps/_Members.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/styles/dynamicCmps/_Members.scss b/src/styles/dynamicCmps/_Members.scss index bb37483..b108629 100644 --- a/src/styles/dynamicCmps/_Members.scss +++ b/src/styles/dynamicCmps/_Members.scss @@ -15,8 +15,8 @@ margin-left: 5px; img { - width: 35px; - height: 35px; + width: 25px; + height: 25px; border-radius: 50%; border: solid white 2px; margin-left: -10px; From 54b50009e4a86d15c2f27b60a6e5a68cd7b3eb5e Mon Sep 17 00:00:00 2001 From: ReactRay Date: Sat, 18 Jan 2025 15:26:45 +0200 Subject: [PATCH 3/3] little changes and sticky positions --- src/cmps/GroupPreview.jsx | 14 ++++++++---- src/cmps/dynamicCmps/TaskTitle.jsx | 8 +++---- src/styles/_Board-details-header.scss | 7 ++++++ src/styles/_Board-details.scss | 33 ++++++++++++++++++++------- src/styles/_sideBar.scss | 17 +++++--------- src/styles/dynamicCmps/TaskTitle.scss | 6 +++++ 6 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/cmps/GroupPreview.jsx b/src/cmps/GroupPreview.jsx index c1885c0..17bb550 100644 --- a/src/cmps/GroupPreview.jsx +++ b/src/cmps/GroupPreview.jsx @@ -5,6 +5,10 @@ import { TaskTitle } from "./dynamicCmps/TaskTitle"; import { Priority } from "./dynamicCmps/Priority"; import { AddTask } from "./AddTask.jsx"; import { useState } from "react"; +import ArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; +import { ArrowRightIcon } from "@mui/x-date-pickers/icons"; +import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; + export const GroupPreview = ({ labels, @@ -38,6 +42,10 @@ export const GroupPreview = ({ return ( <>
+ + setExpanded((prev) => !prev)}> + {expanded ? : } + handleGroupNameChange(groupTitle, group)} style={titleHead} @@ -47,11 +55,9 @@ export const GroupPreview = ({ onChange={(e) => setGroupTitle(e.target.value)} /> - setExpanded((prev) => !prev)}> - {expanded ? "👇🏻" : "👉🏻"} - - + +
diff --git a/src/cmps/dynamicCmps/TaskTitle.jsx b/src/cmps/dynamicCmps/TaskTitle.jsx index cbb7475..dfdcf72 100644 --- a/src/cmps/dynamicCmps/TaskTitle.jsx +++ b/src/cmps/dynamicCmps/TaskTitle.jsx @@ -63,19 +63,19 @@ export function TaskTitle({ cellId, : comment }) - console.log(updatedChat[0].replies) // reply not here + console.log(updatedChat[0].replies) onTaskUpdate({ group, task, type: 'chat', value: updatedChat }) } - // toggel btween spectate and edit mode + function toggleEditMode() { if (onEditMode) { - // not alowing user insert unvalid title + if (!checkTitleValidation(textToEdit)) { setTextToEdit(text) showErrorMsg("Name can't be empty") } - // if everyting ok update title changes + else { onTaskUpdate({ group, task, type: 'taskTitle', value: textToEdit }) } diff --git a/src/styles/_Board-details-header.scss b/src/styles/_Board-details-header.scss index 95b1144..166d787 100644 --- a/src/styles/_Board-details-header.scss +++ b/src/styles/_Board-details-header.scss @@ -41,3 +41,10 @@ .board-details-header > hr { width: 95%; } + +header.board-details-header { + position: sticky; + top: 0; + background-color: #fff; + z-index: 11; +} diff --git a/src/styles/_Board-details.scss b/src/styles/_Board-details.scss index e88d105..f0d0ebd 100644 --- a/src/styles/_Board-details.scss +++ b/src/styles/_Board-details.scss @@ -1,15 +1,15 @@ /* Main Grid */ .grid { display: grid; - grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-columns: 40px 400px repeat(4, 1fr) 500px; grid-template-rows: 34px; - background: white; border-left: 0.3rem rgb(148, 182, 210) solid; } .labels-grid { display: grid; - grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-columns: 40px 400px repeat(4, 1fr) 500px; + grid-template-rows: 34px; width: 100%; @@ -17,15 +17,16 @@ .progress-grid { display: grid; - grid-template-columns: 40px 3fr repeat(4, 1fr) 1fr; + grid-template-columns: 40px 400px repeat(4, 1fr) 500px; + grid-template-rows: 34px; width: 100%; /* Set a fixed width */ } .group-list { font-size: 13px; - padding: 3rem 0; - width: 200vh; + width: 110%; + position: relative; & input[type='checkbox'] { width: 20px; @@ -38,6 +39,8 @@ } .board-details { + overflow: auto; + position: relative; display: flex; flex-direction: column; background-color: white; @@ -212,8 +215,7 @@ div { .group-title-flex { display: flex; - align-items: center; - gap: 1rem; + gap: 10px; } .checkbox { @@ -238,3 +240,18 @@ div { border-left: 1px solid #e1e1e1; padding: 0.2rem 1rem; } +section.labels-grid { + position: sticky; + top: 140px; + z-index: 10; + background-color: #fff; + border: 1px solid #e0dddd; +} + +div.group-title-flex { + position: sticky; + padding: 1rem; + top: 90px; + background-color: #fff; + z-index: 8; +} diff --git a/src/styles/_sideBar.scss b/src/styles/_sideBar.scss index 9fc7a78..5ccb879 100644 --- a/src/styles/_sideBar.scss +++ b/src/styles/_sideBar.scss @@ -1,17 +1,13 @@ -@import "./vars"; +@import './vars'; .side-bar { width: 200px; - background: linear-gradient( - 135deg, - #ffffff 5%, - #eceff8 100% - ); + background: linear-gradient(135deg, #ffffff 5%, #eceff8 100%); // background: linear-gradient(135deg, #0073ea 5%, #00c6ff 100%); display: flex; flex-direction: column; padding-left: 1rem; - font-family: "Roboto", sans-serif; + font-family: 'Roboto', sans-serif; border-top-right-radius: 12px; // border-bottom-right-radius: 12px; font-size: 10px; @@ -93,12 +89,11 @@ } .remove { - border: 1px solid #cfcece; - padding: 0.4em; + border: none; background-color: #fff; + opacity: 0; &:hover { - border: 1px solid #333; + opacity: 1; } } - diff --git a/src/styles/dynamicCmps/TaskTitle.scss b/src/styles/dynamicCmps/TaskTitle.scss index 8af03aa..ea0efda 100644 --- a/src/styles/dynamicCmps/TaskTitle.scss +++ b/src/styles/dynamicCmps/TaskTitle.scss @@ -46,3 +46,9 @@ font-weight: 600; } } + +section.task-title { + position: sticky; + left: 0; + z-index: 6; +}