guild_front/src/components/ProfileCalendar/ProfileCalendarComponent.jsx
2024-04-08 21:05:33 +03:00

321 lines
9.6 KiB
JavaScript

import moment from "moment";
import "moment/locale/ru";
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { Link } from "react-router-dom";
import {
setEditReport,
setReportDate,
setRequestDate,
setSendRequest
} from "@redux/reportSlice";
import {
calendarHelper,
correctDay,
currentMonthAndDay,
getCorrectDate,
getReports,
hourOfNum
} from "@utils/calendarHelper";
import { getCorrectYYMMDD } from "@utils/helper";
import { apiRequest } from "@api/request";
import "@components/Calendar/calendarComponent.scss";
import BaseButton from "@components/Common/BaseButton/BaseButton";
import arrowLeft from "assets/icons/arrows/arrowCalendar_left.png";
import arrowRight from "assets/icons/arrows/arrowCalendar_right.png";
import calendarIcon from "assets/icons/calendar.svg";
// import close from "assets/icons/closeProjectPersons.svg";
import rectangle from "assets/images/rectangle__calendar.png";
export const ProfileCalendarComponent = React.memo(
({
userId,
value,
setValueHandler,
reports,
totalHours,
startRangeDays,
toggleRangeDays,
startDate,
setStartDateRange
}) => {
const dispatch = useDispatch();
const [calendar, setCalendar] = useState([]);
const [month, setMonth] = useState("");
const [endDate, setEndDate] = useState(null);
const [totalRangeHours, setTotalRangeHours] = useState(0);
const [selectedRangeDays, setSelectedRangeDays] = useState({});
const [activePeriod, setActivePeriod] = useState(false);
useEffect(() => {
setCalendar(calendarHelper(value));
calendarHelper(value).map((array) => {
setSelectedRangeDays((prevState) => ({
...prevState,
[array[0]]: false
}));
});
if (endDate) {
resetRangeDays();
}
}, [value]);
useEffect(() => {
setMonth(value.format("MMMM"));
}, [month]);
function isToday(day) {
return day.isSame(new Date(), "day");
}
function dayStyles(day) {
if (moment() < day) return `block`;
for (const date of reports) {
if (
`${new Date(day).getFullYear()}-${correctDay(
new Date(day).getMonth() + 1
)}-${correctDay(new Date(day).getDate())}` === date.created_at
) {
return `before`;
}
}
if (day.day() === 6 || day.day() === 0) return `selected`;
if (isToday(day)) return `today`;
return "pass";
}
function correctRoute(day) {
for (const date of reports) {
if (
`${new Date(day).getFullYear()}-${correctDay(
new Date(day).getMonth() + 1
)}-${correctDay(new Date(day).getDate())}` === date.created_at
) {
if (userId) {
return `/profile/calendar/view/${date.created_at}/${userId}`;
}
return `/profile/calendar/view/${
date.created_at
}/${localStorage.getItem("id")}`;
}
}
if (userId) {
return "#";
}
return "/profile/calendar/report";
}
const prevMonth = () => value.clone().subtract(1, "month");
const nextMonth = () => value.clone().add(1, "month");
function reportsByDate(endDay) {
const requestDates =
startDate < endDay
? `fromDate=${getCorrectYYMMDD(
startDate._d
)}&toDate=${getCorrectYYMMDD(endDay._d)}`
: `fromDate=${getCorrectYYMMDD(endDay._d)}&toDate=${getCorrectYYMMDD(
startDate._d
)}`;
apiRequest(
`/reports/index?${requestDates}&user_id=${
userId ? userId : localStorage.getItem("id")
}`
).then((reports) => {
let spendTime = 0;
reports.map((report) => {
spendTime += report.task.reduce(
(acc, task) => acc + task.hours_spent,
0
);
});
setTotalRangeHours(Math.floor(spendTime));
});
}
function rangeDays(day) {
if (!startDate) {
setStartDateRange(day);
} else {
setEndDate(day);
reportsByDate(day);
}
}
function onMouseRangeDays(day) {
let selectRange = {};
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;
setSelectedRangeDays(selectRange);
}
function resetRangeDays() {
setStartDateRange(null);
setEndDate(null);
setTotalRangeHours(0);
calendarHelper(value).map((array) => {
setSelectedRangeDays((prevState) => ({
...prevState,
[array[0]]: false
}));
});
}
// function errorr(TotalRangeHours) {
// console.error(TotalRangeHours);
// }
return (
<div className="calendar-component">
<div className="calendar-component__header">
<div className="calendar-component__header-info">
<p className="calendar__hours">
{month}&nbsp;
<span>
({totalHours} {hourOfNum(totalHours)})
</span>
</p>
</div>
<div className="calendar-component__header-switcher">
<div
className="calendar-component__header-arrow"
onClick={() => {
setValueHandler(prevMonth());
dispatch(setRequestDate(getReports(prevMonth())));
}}
>
<img src={arrowLeft} alt="" />
</div>
<div className="calendar-component__header-box">
<img className={"calendar__icon"} src={calendarIcon} alt="" />
<span>{value.format("MMMM, YYYY")}</span>
</div>
<div
className="calendar-component__header-arrow"
onClick={() => {
setValueHandler(nextMonth());
dispatch(setRequestDate(getReports(nextMonth())));
}}
>
<img src={arrowRight} alt="" />
</div>
</div>
</div>
<div className="calendar-component__rectangle">
<img src={rectangle} alt="" />
</div>
<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={() => {
if (startRangeDays) rangeDays(day);
else {
dispatch(setReportDate(day));
dispatch(setSendRequest(true));
dispatch(setEditReport(""));
}
}}
onMouseEnter={() => {
if (startRangeDays && startDate && !endDate)
onMouseRangeDays(day);
}}
key={day}
className={
startRangeDays
? `select-days ${
String(startDate?._d) === String(day._d) ||
endDate === day
? "selected-day"
: ""
} ${endDate ? "disable" : ""} ${
selectedRangeDays[day] ? "selected-day" : ""
}`
: dayStyles(day)
}
name={day.format("dddd")}
id="btn"
>
<Link to={startRangeDays ? "#" : correctRoute(day)}>
<div className="form-date">{day.format("D")}</div>
<div className="form-box">
<div className="form-hours">
<span>7/Час</span>
</div>
</div>
{/* {currentMonthAndDay(day)} */}
</Link>
</button>
))
)}
</div>
</div>
<div className="select-date-range">
<span
className="select"
onClick={() => {
if (startRangeDays) resetRangeDays();
toggleRangeDays();
setActivePeriod(!activePeriod);
}}
>
{endDate
? startDate < endDate
? `${getCorrectDate(startDate)} - ${getCorrectDate(endDate)}`
: `${getCorrectDate(endDate)} - ${getCorrectDate(startDate)}`
: activePeriod
? "Выберите диапазон на календаре"
: "Выбрать диапазон"}
</span>
<span>
{totalRangeHours
? `${totalRangeHours} ${hourOfNum(totalRangeHours)}`
: endDate
? "0 часов"
: ""}
</span>
{endDate && (
<BaseButton
styles={"clear-days"}
onClick={() => {
resetRangeDays();
setActivePeriod(false);
toggleRangeDays();
}}
>
Сбросить
</BaseButton>
)}
<span className="hint">Для общего просчета - выберите диапазон</span>
</div>
</div>
);
}
);