diff --git a/src/pages/Tracker/Tracker.jsx b/src/pages/Tracker/Tracker.jsx index 1ab0c9f6..7f74b6bb 100644 --- a/src/pages/Tracker/Tracker.jsx +++ b/src/pages/Tracker/Tracker.jsx @@ -1,5 +1,11 @@ +import { getTheme } from "@table-library/react-table-library/baseline"; +import { CompactTable } from "@table-library/react-table-library/compact"; +import { usePagination } from "@table-library/react-table-library/pagination"; +import { useSort } from "@table-library/react-table-library/sort"; +import { useTheme } from "@table-library/react-table-library/theme"; import React, { useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { Link } from "react-router-dom"; import { getProjects, @@ -9,7 +15,8 @@ import { setToggleTab } from "@redux/projectsTrackerSlice"; -import { caseOfNum } from "@utils/helper"; +import { getCorrectDate } from "@utils/calendarHelper"; +import { caseOfNum, urlForLocal } from "@utils/helper"; import { apiRequest } from "@api/request"; @@ -26,9 +33,10 @@ import ProjectTicket from "@components/ProjectTicket/ProjectTicket"; import addProjectImg from "assets/icons/addProjectImg.svg"; import archiveTrackerProjects from "assets/icons/archiveTrackerProjects.svg"; +import rightArrow from "assets/icons/arrows/arrowRight.svg"; import arrowViewReport from "assets/icons/arrows/arrowViewReport.svg"; import filterIcon from "assets/icons/filterIcon.svg"; -import search from "assets/icons/serchIcon.png"; +import searchImg from "assets/icons/serchIcon.png"; import project from "assets/icons/trackerProject.svg"; import tasks from "assets/icons/trackerTasks.svg"; import archive from "assets/images/archiveIcon.png"; @@ -43,15 +51,110 @@ export const Tracker = () => { const dispatch = useDispatch(); const projects = useSelector(getProjects); const tab = useSelector(getToggleTab); + const theme = useTheme(getTheme()); + const [nodes, setNodes] = useState([]); + const [initialNodes, setInitialNodes] = useState([]); const [allTasks, setAllTasks] = useState([]); const [filteredAllTasks, setFilteredAllTasks] = useState([]); const [loader, setLoader] = useState(false); const [filterCompleteTasks, setFilterCompleteTasks] = useState([]); const [allCompletedTasks, setAllCompletedTasks] = useState([]); + const [search, setSearch] = useState(""); const [modalCreateProject, setModalCreateProject] = useState(false); + const COLUMNS = [ + { + label: "Задача", + renderCell: (item) => ( +

+ ), + sort: { sortKey: "NAME" } + }, + { + label: "Создано", + renderCell: (item) => {getCorrectDate(item.created_at)}, + sort: { sortKey: "CREATE" } + }, + { + label: "Дедлайн", + renderCell: (item) => ( + + {item.dead_line ? getCorrectDate(item.dead_line) : "Без дедлайна"} + + ), + sort: { sortKey: "DEADLINE" } + }, + { + label: "Потраченное время", + renderCell: (item) => ( + + {item.timers.length + ? getSpendTime(item.timers) + : "Трекер не был включен"} + + ), + sort: { sortKey: "SPEND" } + } + ]; + + let data = { nodes }; + + const sort = useSort( + data, + { + onChange: onSortChange + }, + { + sortFns: { + NAME: (array) => array.sort((a, b) => a.title.localeCompare(b.title)), + CREATE: (array) => + array.sort((a, b) => new Date(a.created_at) - new Date(b.created_at)), + DEADLINE: (array) => + array.sort((a, b) => new Date(a.dead_line) - new Date(b.dead_line)), + SPEND: (array) => + array.sort( + (a, b) => + getSpendTime(a.timers, true) - getSpendTime(b.timers, true) + ) + } + } + ); + + const pagination = usePagination(data, { + state: { + page: 0, + size: 11 + } + }); + + function getSpendTime(times, seconds) { + let timerSeconds = 0; + times.forEach((time) => { + timerSeconds += time.deltaSeconds; + }); + if (seconds) { + return timerSeconds; + } + return `${Math.floor(timerSeconds / 60 / 60)}:${Math.floor( + (timerSeconds / 60) % 60 + )}:${timerSeconds % 60}`; + } + + function onSortChange(action, state) { + console.log(action, state); + } + + const handleSearch = (event) => { + setSearch(event.target.value); + setNodes( + initialNodes.filter((item) => + item.title.toLowerCase().includes(event.target.value.toLowerCase()) + ) + ); + }; + useEffect(() => { setLoader(true); apiRequest( @@ -84,6 +187,8 @@ export const Tracker = () => { : []; setAllTasks(allTasks); setFilteredAllTasks(allTasks); + setNodes(allTasks); + setInitialNodes(allTasks); setAllCompletedTasks(completedTasks); setFilterCompleteTasks(completedTasks); }) @@ -238,53 +343,122 @@ export const Tracker = () => { : "tracker__tabs__content__projects" } > -
-
-
-

- {25} - {35} -

-

Сентября,

-

2023

-
+ {/*
*/} + {/*
*/} + {/*
*/} + {/*

*/} + {/* {25} - {35}*/} + {/*

*/} + {/*

Сентября,

*/} + {/*

2023

*/} + {/*
*/} -
- - -
-
+ {/*
*/} + {/* */} + {/* */} + {/*
*/} + {/*
*/} -
- search - filterAllTask(event)} + {/*
*/} + {/* search*/} + {/* filterAllTask(event)}*/} + {/* />*/} + {/*
*/} + + {/*
*/} + {/* */} + {/* #*/} + {/*

Фильтр

*/} + {/*
*/} + {/* */} + {/*

Очистить фильтр

*/} + {/*
*/} + {/*
*/} + {/*
*/} + + {loader ? ( + + ) : ( + <> +
+ search + +
+ -
+
+ + + {pagination.state.getPages(data.nodes).map((_, index) => ( + + ))} + + +
+ + )} -
- - # -

Фильтр

-
- -

Очистить фильтр

-
-
-
- - {loader && } - - + {/**/}
diff --git a/src/pages/Tracker/tracker.scss b/src/pages/Tracker/tracker.scss index b74c2b1f..5b5dad21 100644 --- a/src/pages/Tracker/tracker.scss +++ b/src/pages/Tracker/tracker.scss @@ -1937,4 +1937,100 @@ } } } + + .table { + &__search { + display: flex; + background: #F0F2F5; + border-radius: 5px; + width: 100%; + padding: 14px 12px; + column-gap: 10px; + align-items: center; + margin-bottom: 20px; + + img { + width: 20px; + height: 20px; + } + + input { + background: none; + border: none; + outline: none; + font-size: 16px; + color: #9BABC5; + width: 100%; + + &::placeholder { + color: #9BABC5; + } + } + } + + &__pagination { + display: flex; + margin: 25px auto 0; + column-gap: 12px; + + button { + font-size: 14px; + width: 32px; + border-radius: 5px; + height: 32px; + color: #2E3A59; + } + + .switch { + border: none; + background: #F0F2F5; + font-weight: 600; + } + + .disable { + opacity: 0.7; + } + } + + &__pages { + display: flex; + column-gap: 4px; + color: black; + background: white; + + .page { + border: 1px solid #E8ECF8; + background: none; + + &--active { + border: none; + background: #9DA65D; + color: white; + } + } + } + } + + table { + grid-template-columns: minmax(0px, 2fr) minmax(0px, 1fr) minmax(0px, 1fr) minmax(0px, 1fr); + th { + border-top: none; + border-bottom: 1px solid #F5F6F8; + color: #2E3A59; + padding: 0 7.5px 15px; + } + + td { + padding: 22px 7.5px; + color: #2E3A59; + border-top: none; + + p { + max-width: 430px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + } }