2023-05-31 08:36:15 +03:00
|
|
|
|
import moment from "moment";
|
|
|
|
|
import "moment/locale/ru";
|
|
|
|
|
import React, { useEffect, useState } from "react";
|
2023-05-24 15:34:43 +03:00
|
|
|
|
import { useDispatch } from "react-redux";
|
|
|
|
|
import { Link } from "react-router-dom";
|
|
|
|
|
|
|
|
|
|
import {
|
2024-02-09 17:59:19 +03:00
|
|
|
|
setEditReport,
|
2023-05-24 15:34:43 +03:00
|
|
|
|
setReportDate,
|
|
|
|
|
setRequestDate,
|
2023-12-19 17:36:30 +03:00
|
|
|
|
setSendRequest
|
2023-05-30 10:10:34 +03:00
|
|
|
|
} from "@redux/reportSlice";
|
2023-10-06 17:41:26 +03:00
|
|
|
|
|
2023-05-11 19:54:15 +03:00
|
|
|
|
import {
|
|
|
|
|
calendarHelper,
|
2023-12-21 17:31:52 +03:00
|
|
|
|
correctDay,
|
2023-05-11 19:54:15 +03:00
|
|
|
|
currentMonthAndDay,
|
2023-10-06 17:41:26 +03:00
|
|
|
|
getCorrectDate,
|
2023-05-11 19:54:15 +03:00
|
|
|
|
getReports,
|
2023-12-21 17:31:52 +03:00
|
|
|
|
hourOfNum
|
2024-02-15 14:29:00 +03:00
|
|
|
|
} from "@utils/calendarHelper";
|
2024-02-15 15:37:15 +03:00
|
|
|
|
import { getCorrectYYMMDD } from "@utils/helper";
|
|
|
|
|
|
|
|
|
|
import { apiRequest } from "@api/request";
|
|
|
|
|
|
|
|
|
|
import "@components/Calendar/calendarComponent.scss";
|
2023-10-24 19:41:59 +03:00
|
|
|
|
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
2023-05-11 19:54:15 +03:00
|
|
|
|
|
2023-05-30 10:10:34 +03:00
|
|
|
|
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
|
|
|
|
import calendarIcon from "assets/icons/calendar.svg";
|
2023-10-24 19:41:59 +03:00
|
|
|
|
// import close from "assets/icons/closeProjectPersons.svg";
|
2023-10-10 16:32:30 +03:00
|
|
|
|
import rectangle from "assets/images/rectangle__calendar.png";
|
2023-05-11 19:54:15 +03:00
|
|
|
|
|
|
|
|
|
export const ProfileCalendarComponent = React.memo(
|
2023-10-10 19:21:46 +03:00
|
|
|
|
({
|
2024-02-02 18:43:52 +03:00
|
|
|
|
userId,
|
2023-10-10 19:21:46 +03:00
|
|
|
|
value,
|
|
|
|
|
setValueHandler,
|
|
|
|
|
reports,
|
|
|
|
|
totalHours,
|
|
|
|
|
startRangeDays,
|
|
|
|
|
toggleRangeDays,
|
2023-10-12 12:50:02 +03:00
|
|
|
|
startDate,
|
2023-12-19 17:36:30 +03:00
|
|
|
|
setStartDateRange
|
2023-10-10 19:21:46 +03:00
|
|
|
|
}) => {
|
2022-12-26 15:12:01 +03:00
|
|
|
|
const dispatch = useDispatch();
|
2023-05-18 19:52:37 +03:00
|
|
|
|
|
2023-05-11 19:54:15 +03:00
|
|
|
|
const [calendar, setCalendar] = useState([]);
|
|
|
|
|
const [month, setMonth] = useState("");
|
2023-10-06 17:40:53 +03:00
|
|
|
|
const [endDate, setEndDate] = useState(null);
|
2023-10-06 17:41:26 +03:00
|
|
|
|
const [totalRangeHours, setTotalRangeHours] = useState(0);
|
2023-10-10 16:32:30 +03:00
|
|
|
|
const [selectedRangeDays, setSelectedRangeDays] = useState({});
|
2023-10-24 19:41:59 +03:00
|
|
|
|
const [activePeriod, setActivePeriod] = useState(false);
|
2022-12-26 15:12:01 +03:00
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2023-05-11 19:54:15 +03:00
|
|
|
|
setCalendar(calendarHelper(value));
|
2023-10-10 16:31:40 +03:00
|
|
|
|
calendarHelper(value).map((array) => {
|
2023-10-10 16:32:30 +03:00
|
|
|
|
setSelectedRangeDays((prevState) => ({
|
|
|
|
|
...prevState,
|
2023-12-19 17:36:30 +03:00
|
|
|
|
[array[0]]: false
|
2023-10-10 16:32:30 +03:00
|
|
|
|
}));
|
|
|
|
|
});
|
2023-10-12 12:50:02 +03:00
|
|
|
|
if (endDate) {
|
2023-10-12 12:50:17 +03:00
|
|
|
|
resetRangeDays();
|
2023-10-12 12:50:02 +03:00
|
|
|
|
}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
}, [value]);
|
2022-12-26 15:12:01 +03:00
|
|
|
|
|
2023-02-17 15:19:49 +03:00
|
|
|
|
useEffect(() => {
|
2023-05-11 19:54:15 +03:00
|
|
|
|
setMonth(value.format("MMMM"));
|
2023-02-17 15:19:49 +03:00
|
|
|
|
}, [month]);
|
2022-12-26 15:12:01 +03:00
|
|
|
|
|
|
|
|
|
function isToday(day) {
|
2023-05-11 19:54:15 +03:00
|
|
|
|
return day.isSame(new Date(), "day");
|
2022-12-26 15:12:01 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function dayStyles(day) {
|
2023-12-20 16:14:30 +03:00
|
|
|
|
if (moment() < day) return `block`;
|
2023-05-11 19:54:15 +03:00
|
|
|
|
for (const date of reports) {
|
|
|
|
|
if (
|
|
|
|
|
`${new Date(day).getFullYear()}-${correctDay(
|
2023-12-05 14:15:04 +03:00
|
|
|
|
new Date(day).getMonth() + 1
|
2023-05-11 19:54:15 +03:00
|
|
|
|
)}-${correctDay(new Date(day).getDate())}` === date.created_at
|
|
|
|
|
) {
|
|
|
|
|
return `before`;
|
2022-12-26 15:12:01 +03:00
|
|
|
|
}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
}
|
|
|
|
|
if (day.day() === 6 || day.day() === 0) return `selected`;
|
|
|
|
|
if (isToday(day)) return `today`;
|
|
|
|
|
return "pass";
|
2022-12-26 15:12:01 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-16 16:28:56 +03:00
|
|
|
|
function correctRoute(day) {
|
2023-05-11 19:54:15 +03:00
|
|
|
|
for (const date of reports) {
|
|
|
|
|
if (
|
|
|
|
|
`${new Date(day).getFullYear()}-${correctDay(
|
2023-12-05 14:15:04 +03:00
|
|
|
|
new Date(day).getMonth() + 1
|
2023-05-11 19:54:15 +03:00
|
|
|
|
)}-${correctDay(new Date(day).getDate())}` === date.created_at
|
|
|
|
|
) {
|
2024-02-02 18:43:52 +03:00
|
|
|
|
if (userId) {
|
2024-02-07 18:54:21 +03:00
|
|
|
|
return `/profile/calendar/view/${date.created_at}/${userId}`;
|
2024-02-02 18:43:52 +03:00
|
|
|
|
}
|
2024-02-07 18:54:55 +03:00
|
|
|
|
return `/profile/calendar/view/${
|
|
|
|
|
date.created_at
|
|
|
|
|
}/${localStorage.getItem("id")}`;
|
2023-01-16 16:28:56 +03:00
|
|
|
|
}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
}
|
2024-02-02 18:43:52 +03:00
|
|
|
|
|
|
|
|
|
if (userId) {
|
2024-02-02 18:44:11 +03:00
|
|
|
|
return "#";
|
2024-02-02 18:43:52 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-07 18:54:21 +03:00
|
|
|
|
return "/profile/calendar/report";
|
2023-01-16 16:28:56 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-12-20 16:14:30 +03:00
|
|
|
|
const prevMonth = () => value.clone().subtract(1, "month");
|
2023-02-09 20:46:02 +03:00
|
|
|
|
|
2023-12-20 16:14:30 +03:00
|
|
|
|
const nextMonth = () => value.clone().add(1, "month");
|
2022-12-26 15:12:01 +03:00
|
|
|
|
|
2023-10-10 16:31:40 +03:00
|
|
|
|
function reportsByDate(endDay) {
|
2023-10-12 12:50:17 +03:00
|
|
|
|
const requestDates =
|
|
|
|
|
startDate < endDay
|
|
|
|
|
? `fromDate=${getCorrectYYMMDD(
|
2023-12-05 14:15:04 +03:00
|
|
|
|
startDate._d
|
2023-10-12 12:50:17 +03:00
|
|
|
|
)}&toDate=${getCorrectYYMMDD(endDay._d)}`
|
|
|
|
|
: `fromDate=${getCorrectYYMMDD(endDay._d)}&toDate=${getCorrectYYMMDD(
|
2023-12-05 14:15:04 +03:00
|
|
|
|
startDate._d
|
2023-10-12 12:50:17 +03:00
|
|
|
|
)}`;
|
2023-10-06 17:41:26 +03:00
|
|
|
|
apiRequest(
|
2024-02-02 18:44:11 +03:00
|
|
|
|
`/reports/index?${requestDates}&user_id=${
|
|
|
|
|
userId ? userId : localStorage.getItem("id")
|
|
|
|
|
}`
|
2023-10-06 17:41:26 +03:00
|
|
|
|
).then((reports) => {
|
|
|
|
|
let spendTime = 0;
|
2023-12-20 16:14:30 +03:00
|
|
|
|
reports.map((report) => {
|
|
|
|
|
spendTime += report.task.reduce(
|
|
|
|
|
(acc, task) => acc + task.hours_spent,
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
setTotalRangeHours(Math.floor(spendTime));
|
2023-10-06 17:41:26 +03:00
|
|
|
|
});
|
2023-10-06 17:40:53 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 16:32:30 +03:00
|
|
|
|
function rangeDays(day) {
|
|
|
|
|
if (!startDate) {
|
2023-10-12 12:50:02 +03:00
|
|
|
|
setStartDateRange(day);
|
2023-10-10 16:32:30 +03:00
|
|
|
|
} else {
|
|
|
|
|
setEndDate(day);
|
|
|
|
|
reportsByDate(day);
|
|
|
|
|
}
|
2023-10-10 16:31:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 16:32:30 +03:00
|
|
|
|
function onMouseRangeDays(day) {
|
|
|
|
|
let selectRange = {};
|
2023-12-22 14:47:55 +03:00
|
|
|
|
for (let curDay in selectedRangeDays)
|
|
|
|
|
selectRange[curDay] =
|
|
|
|
|
day > startDate
|
|
|
|
|
? new Date(curDay) > startDate && new Date(curDay) < day
|
|
|
|
|
: new Date(curDay) < startDate && new Date(curDay) > day;
|
|
|
|
|
|
2023-10-10 16:32:30 +03:00
|
|
|
|
setSelectedRangeDays(selectRange);
|
2023-10-10 16:31:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 16:32:30 +03:00
|
|
|
|
function resetRangeDays() {
|
2023-10-12 12:50:02 +03:00
|
|
|
|
setStartDateRange(null);
|
2023-10-10 16:32:30 +03:00
|
|
|
|
setEndDate(null);
|
|
|
|
|
setTotalRangeHours(0);
|
|
|
|
|
calendarHelper(value).map((array) => {
|
|
|
|
|
setSelectedRangeDays((prevState) => ({
|
|
|
|
|
...prevState,
|
2023-12-19 17:36:30 +03:00
|
|
|
|
[array[0]]: false
|
2023-10-10 16:32:30 +03:00
|
|
|
|
}));
|
|
|
|
|
});
|
2023-10-10 16:31:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-26 15:12:01 +03:00
|
|
|
|
return (
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<div className="calendar-component">
|
|
|
|
|
<div className="calendar-component__header">
|
|
|
|
|
<div className="calendar-component__header-info">
|
2024-02-02 18:44:11 +03:00
|
|
|
|
{!userId && <h3>Мои отчеты за </h3>}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<p className="calendar__hours">
|
|
|
|
|
{month}
|
|
|
|
|
<span>
|
2023-12-04 21:08:15 +03:00
|
|
|
|
({totalHours} {hourOfNum(totalHours)})
|
2023-05-11 19:54:15 +03:00
|
|
|
|
</span>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="calendar-component__header-switcher">
|
|
|
|
|
<div
|
|
|
|
|
className="calendar-component__header-box"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setValueHandler(prevMonth());
|
|
|
|
|
dispatch(setRequestDate(getReports(prevMonth())));
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<img src={arrow} alt="" />
|
|
|
|
|
<span>{prevMonth().format("MMMM")}</span>
|
2022-12-26 15:12:01 +03:00
|
|
|
|
</div>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<div className="calendar-component__header-box">
|
|
|
|
|
<span>{value.format("YYYY")}</span>
|
2022-12-26 15:12:01 +03:00
|
|
|
|
</div>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<div
|
|
|
|
|
className="calendar-component__header-box"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setValueHandler(nextMonth());
|
|
|
|
|
dispatch(setRequestDate(getReports(nextMonth())));
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<span>{nextMonth().format("MMMM")}</span>
|
|
|
|
|
<img src={arrow} alt="" />
|
2022-12-26 15:12:01 +03:00
|
|
|
|
</div>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="calendar-component__rectangle">
|
|
|
|
|
<img src={rectangle} alt="" />
|
2022-12-26 15:12:01 +03:00
|
|
|
|
</div>
|
|
|
|
|
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<div className="calendar-component__body">
|
|
|
|
|
<div>
|
|
|
|
|
<p>Пн</p>
|
|
|
|
|
<p>Вт</p>
|
|
|
|
|
<p>Ср</p>
|
|
|
|
|
<p>Чт</p>
|
|
|
|
|
<p>Пт</p>
|
|
|
|
|
<p>Сб</p>
|
|
|
|
|
<p>Вс</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="calendar-component__form">
|
|
|
|
|
{calendar.map((week) =>
|
|
|
|
|
week.map((day) => (
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => {
|
2023-12-22 14:47:55 +03:00
|
|
|
|
if (startRangeDays) rangeDays(day);
|
|
|
|
|
else {
|
2023-10-10 16:32:30 +03:00
|
|
|
|
dispatch(setReportDate(day));
|
|
|
|
|
dispatch(setSendRequest(true));
|
2024-02-09 17:59:19 +03:00
|
|
|
|
dispatch(setEditReport(""));
|
2023-10-10 16:31:40 +03:00
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
onMouseEnter={() => {
|
2023-12-22 14:47:55 +03:00
|
|
|
|
if (startRangeDays && startDate && !endDate)
|
2023-10-10 16:32:30 +03:00
|
|
|
|
onMouseRangeDays(day);
|
2023-05-11 19:54:15 +03:00
|
|
|
|
}}
|
|
|
|
|
key={day}
|
2023-10-10 16:32:30 +03:00
|
|
|
|
className={
|
|
|
|
|
startRangeDays
|
2024-02-09 18:17:15 +03:00
|
|
|
|
? `select-days ${
|
2023-10-12 12:50:17 +03:00
|
|
|
|
String(startDate?._d) === String(day._d) ||
|
|
|
|
|
endDate === day
|
2024-02-09 18:17:15 +03:00
|
|
|
|
? "selected-day"
|
2023-10-10 16:32:30 +03:00
|
|
|
|
: ""
|
|
|
|
|
} ${endDate ? "disable" : ""} ${
|
2024-02-09 18:17:15 +03:00
|
|
|
|
selectedRangeDays[day] ? "selected-day" : ""
|
2023-10-10 16:32:30 +03:00
|
|
|
|
}`
|
|
|
|
|
: dayStyles(day)
|
|
|
|
|
}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
name={day.format("dddd")}
|
|
|
|
|
id="btn"
|
|
|
|
|
>
|
2023-10-10 16:32:30 +03:00
|
|
|
|
<Link to={startRangeDays ? "#" : correctRoute(day)}>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
<img
|
|
|
|
|
className={"calendar__icon"}
|
|
|
|
|
src={calendarIcon}
|
|
|
|
|
alt=""
|
|
|
|
|
/>
|
|
|
|
|
{currentMonthAndDay(day)}
|
2023-05-16 19:20:37 +03:00
|
|
|
|
</Link>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
</button>
|
2023-12-05 14:15:04 +03:00
|
|
|
|
))
|
2023-05-11 19:54:15 +03:00
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-02-09 18:17:15 +03:00
|
|
|
|
<div className="select-date-range">
|
2023-10-06 17:41:26 +03:00
|
|
|
|
<span
|
|
|
|
|
className="select"
|
|
|
|
|
onClick={() => {
|
2023-10-10 16:32:30 +03:00
|
|
|
|
if (startRangeDays) resetRangeDays();
|
2023-10-10 19:21:46 +03:00
|
|
|
|
toggleRangeDays();
|
2023-12-20 16:14:30 +03:00
|
|
|
|
setActivePeriod(!activePeriod);
|
2023-10-06 17:41:26 +03:00
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{endDate
|
2023-10-12 12:50:17 +03:00
|
|
|
|
? startDate < endDate
|
|
|
|
|
? `${getCorrectDate(startDate)} - ${getCorrectDate(endDate)}`
|
|
|
|
|
: `${getCorrectDate(endDate)} - ${getCorrectDate(startDate)}`
|
2023-10-24 19:41:59 +03:00
|
|
|
|
: activePeriod
|
2024-04-02 18:29:29 +03:00
|
|
|
|
? "Выберите диапазон на календаре"
|
|
|
|
|
: "Выбрать диапазон"}
|
2023-10-06 17:41:26 +03:00
|
|
|
|
</span>
|
|
|
|
|
<span>
|
|
|
|
|
{totalRangeHours
|
|
|
|
|
? `${totalRangeHours} ${hourOfNum(totalRangeHours)}`
|
2023-12-04 21:08:45 +03:00
|
|
|
|
: endDate
|
2024-04-02 18:29:29 +03:00
|
|
|
|
? "0 часов"
|
|
|
|
|
: ""}
|
2023-10-06 17:41:26 +03:00
|
|
|
|
</span>
|
2023-10-10 16:32:30 +03:00
|
|
|
|
{endDate && (
|
2023-10-24 19:41:59 +03:00
|
|
|
|
<BaseButton
|
|
|
|
|
styles={"clear-days"}
|
2023-10-10 16:32:30 +03:00
|
|
|
|
onClick={() => {
|
|
|
|
|
resetRangeDays();
|
2023-12-20 16:14:30 +03:00
|
|
|
|
setActivePeriod(false);
|
2023-10-27 18:32:37 +03:00
|
|
|
|
toggleRangeDays();
|
2023-10-10 16:32:30 +03:00
|
|
|
|
}}
|
2023-10-24 19:41:59 +03:00
|
|
|
|
>
|
|
|
|
|
Сбросить
|
|
|
|
|
</BaseButton>
|
2023-10-10 16:32:30 +03:00
|
|
|
|
)}
|
2023-10-06 17:40:53 +03:00
|
|
|
|
</div>
|
2023-05-11 19:54:15 +03:00
|
|
|
|
</div>
|
|
|
|
|
);
|
2023-12-05 14:15:04 +03:00
|
|
|
|
}
|
2023-05-11 19:54:15 +03:00
|
|
|
|
);
|