import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; import { mutate } from "swr"; // react-beautiful-dnd import { DragDropContext, DropResult } from "react-beautiful-dnd"; // services import issuesService from "services/issues.service"; // hooks import useCalendarIssuesView from "hooks/use-calendar-issues-view"; // components import { SingleCalendarDate, CalendarHeader } from "components/core"; // ui import { Spinner } from "components/ui"; // helpers import { renderDateFormat } from "helpers/date-time.helper"; import { startOfWeek, lastDayOfWeek, eachDayOfInterval, weekDayInterval, formatDate, } from "helpers/calendar.helper"; // types import { ICalendarRange, ICurrentUserResponse, IIssue, UserAuth } from "types"; // fetch-keys import { CYCLE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS, PROJECT_ISSUES_LIST_WITH_PARAMS, VIEW_ISSUES, } from "constants/fetch-keys"; type Props = { handleEditIssue: (issue: IIssue) => void; handleDeleteIssue: (issue: IIssue) => void; addIssueToDate: (date: string) => void; isCompleted: boolean; user: ICurrentUserResponse | undefined; userAuth: UserAuth; }; export const CalendarView: React.FC = ({ handleEditIssue, handleDeleteIssue, addIssueToDate, isCompleted = false, user, userAuth, }) => { const [showWeekEnds, setShowWeekEnds] = useState(false); const [currentDate, setCurrentDate] = useState(new Date()); const [isMonthlyView, setIsMonthlyView] = useState(true); const [calendarDates, setCalendarDates] = useState({ startDate: startOfWeek(currentDate), endDate: lastDayOfWeek(currentDate), }); const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; const { calendarIssues, params, setCalendarDateRange } = useCalendarIssuesView(); const totalDate = eachDayOfInterval({ start: calendarDates.startDate, end: calendarDates.endDate, }); const onlyWeekDays = weekDayInterval({ start: calendarDates.startDate, end: calendarDates.endDate, }); const currentViewDays = showWeekEnds ? totalDate : onlyWeekDays; const currentViewDaysData = currentViewDays.map((date: Date) => { const filterIssue = calendarIssues.length > 0 ? calendarIssues.filter( (issue) => issue.target_date && renderDateFormat(issue.target_date) === renderDateFormat(date) ) : []; return { date: renderDateFormat(date), issues: filterIssue, }; }); const weeks = ((date: Date[]) => { const weeks = []; if (showWeekEnds) { for (let day = 0; day <= 6; day++) { weeks.push(date[day]); } } else { for (let day = 0; day <= 4; day++) { weeks.push(date[day]); } } return weeks; })(currentViewDays); const onDragEnd = (result: DropResult) => { const { source, destination, draggableId } = result; if (!destination || !workspaceSlug || !projectId) return; if (source.droppableId === destination.droppableId) return; const fetchKey = cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) : moduleId ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) : viewId ? VIEW_ISSUES(viewId.toString(), params) : PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params); mutate( fetchKey, (prevData) => (prevData ?? []).map((p) => { if (p.id === draggableId) return { ...p, target_date: destination.droppableId, }; return p; }), false ); issuesService .patchIssue( workspaceSlug as string, projectId as string, draggableId, { target_date: destination?.droppableId, }, user ) .then(() => mutate(fetchKey)); }; const changeDateRange = (startDate: Date, endDate: Date) => { setCalendarDates({ startDate, endDate, }); setCalendarDateRange( `${renderDateFormat(startDate)};after,${renderDateFormat(endDate)};before` ); }; useEffect(() => { setCalendarDateRange( `${renderDateFormat(startOfWeek(currentDate))};after,${renderDateFormat( lastDayOfWeek(currentDate) )};before` ); }, [currentDate]); const isNotAllowed = userAuth.isGuest || userAuth.isViewer || isCompleted; return calendarIssues ? (
{weeks.map((date, index) => (
{isMonthlyView ? formatDate(date, "eee").substring(0, 3) : formatDate(date, "eee")} {!isMonthlyView && {formatDate(date, "d")}}
))}
{currentViewDaysData.map((date, index) => ( ))}
) : (
); };