import React, { useEffect, useMemo, useState, useRef } from 'react'; import { Calendar, Views, momentLocalizer, SlotInfo, EventProps, } from 'react-big-calendar'; import moment from 'moment'; import 'react-big-calendar/lib/css/react-big-calendar.css'; import ListActionsPopover from './ListActionsPopover'; import Link from 'next/link'; import { useAppSelector } from '../stores/hooks'; import { hasPermission } from '../helpers/userPermissions'; const localizer = momentLocalizer(moment); type TEvent = { id: string; title: string; start: Date; end: Date; }; type Props = { events: any[]; handleDeleteAction: (id: string) => void; handleCreateEventAction: (slotInfo: SlotInfo) => void; onDateRangeChange: (range: { start: string; end: string }) => void; entityName: string; showField: string; pathEdit?: string; pathView?: string; 'start-data-key': string; 'end-data-key': string; }; const BigCalendar = ({ events, handleDeleteAction, handleCreateEventAction, onDateRangeChange, entityName, showField, pathEdit, pathView, 'start-data-key': startDataKey, 'end-data-key': endDataKey, }: Props) => { const [myEvents, setMyEvents] = useState([]); const prevRange = useRef<{ start: string; end: string } | null>(null); const currentUser = useAppSelector((state) => state.auth.currentUser); const hasUpdatePermission = currentUser && hasPermission(currentUser, `UPDATE_${entityName.toUpperCase()}`); const hasCreatePermission = currentUser && hasPermission(currentUser, `CREATE_${entityName.toUpperCase()}`); const { defaultDate, scrollToTime } = useMemo( () => ({ defaultDate: new Date(), scrollToTime: new Date(1970, 1, 1, 6), }), [], ); useEffect(() => { if (!events || !Array.isArray(events) || !events?.length) return; const formattedEvents = events.map((event) => ({ ...event, start: new Date(event[startDataKey]), end: new Date(event[endDataKey]), title: event[showField], })); setMyEvents(formattedEvents); }, [endDataKey, events, startDataKey, showField]); const onRangeChange = ( range: Date[] | { start: Date; end: Date }, ) => { const newRange = { start: '', end: '' }; const format = 'YYYY-MM-DDTHH:mm'; if (Array.isArray(range)) { newRange.start = moment(range[0]).format(format); newRange.end = moment(range[range.length - 1]).format(format); } else { newRange.start = moment(range.start).format(format); newRange.end = moment(range.end).format(format); } if (newRange.start === newRange.end) { newRange.end = moment(newRange.end).add(1, 'days').format(format); } // check if the range fits in the previous range if ( prevRange.current && prevRange.current.start <= newRange.start && prevRange.current.end >= newRange.end ) { return; } prevRange.current = { start: newRange.start, end: newRange.end }; onDateRangeChange(newRange); }; return (
( ), }} />
); }; const MyCustomEvent = ( props: { onDelete: (id: string) => void; hasUpdatePermission: boolean; pathEdit?: string; pathView?: string; } & EventProps, ) => { const { onDelete, hasUpdatePermission, title, event, pathEdit, pathView } = props; return (
{title}
); }; export default BigCalendar;