guild_front/src/components/ProfileCalendar/ProfileCalendarComponent.jsx

326 lines
9.4 KiB
React
Raw Normal View History

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 {
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
import { getCorrectYYMMDD } from "@utils/helper";
import { apiRequest } from "@api/request";
2023-05-31 08:36:15 +03:00
import "@components/Calendar/calendarComponent.scss";
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
2023-05-30 10:10:34 +03:00
} from "@components/Calendar/calendarHelper";
2023-10-24 19:41:59 +03:00
import BaseButton from "@components/Common/BaseButton/BaseButton";
2023-05-30 10:10:34 +03:00
import ShortReport from "@components/ShortReport/ShortReport";
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
({
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("");
const [shortReport, setShortReport] = useState(false);
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
) {
2023-05-24 16:04:36 +03:00
return "#";
2023-01-16 16:28:56 +03:00
}
2023-05-11 19:54:15 +03:00
}
return "../../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(
`/reports/reports-by-date?${requestDates}&user_card_id=${localStorage.getItem(
2023-12-05 14:15:04 +03:00
"cardId"
)}`
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 = {};
for (let curDay in selectedRangeDays) {
2023-10-12 12:50:02 +03:00
if (day > startDate) {
if (
2023-10-12 12:50:17 +03:00
day > startDate &&
new Date(curDay) > startDate &&
new Date(curDay) < day
2023-10-12 12:50:02 +03:00
) {
selectRange[curDay] = true;
2023-10-12 12:50:17 +03:00
} else {
2023-10-12 12:50:02 +03:00
selectRange[curDay] = false;
}
2023-10-10 16:32:30 +03:00
} else {
2023-10-12 12:50:02 +03:00
if (
2023-10-12 12:50:17 +03:00
day < startDate &&
new Date(curDay) < startDate &&
new Date(curDay) > day
2023-10-12 12:50:02 +03:00
) {
selectRange[curDay] = true;
2023-10-12 12:50:17 +03:00
} else {
2023-10-12 12:50:02 +03:00
selectRange[curDay] = false;
}
2023-10-10 16:31:40 +03:00
}
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">
2023-12-04 21:08:15 +03:00
<h3>Мои отчеты за </h3>
2023-05-11 19:54:15 +03:00
<p className="calendar__hours">
{month}&nbsp;
<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-10-10 16:32:30 +03:00
if (startRangeDays) {
rangeDays(day);
2023-10-10 16:31:40 +03:00
} else {
2023-10-10 16:32:30 +03:00
dispatch(setReportDate(day));
setShortReport(true);
dispatch(setSendRequest(true));
2023-10-10 16:31:40 +03:00
}
}}
onMouseEnter={() => {
2023-10-10 16:32:30 +03:00
if (startRangeDays && startDate && !endDate) {
onMouseRangeDays(day);
}
2023-05-11 19:54:15 +03:00
}}
key={day}
2023-10-10 16:32:30 +03:00
className={
startRangeDays
? `selectDays ${
2023-10-12 12:50:17 +03:00
String(startDate?._d) === String(day._d) ||
endDate === day
2023-10-10 16:32:30 +03:00
? "selectedDay"
: ""
} ${endDate ? "disable" : ""} ${
selectedRangeDays[day] ? "selectedDay" : ""
}`
: 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>
2023-10-06 17:41:26 +03:00
<div className="selectDateRange">
<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
2023-12-21 17:31:52 +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
2023-12-21 17:31:52 +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
{shortReport && <ShortReport />}
</div>
);
2023-12-05 14:15:04 +03:00
}
2023-05-11 19:54:15 +03:00
);