import type FullCalendar from '@fullcalendar/react'; import type { EventResizeDoneArg } from '@fullcalendar/interaction/index.js'; import type { ICalendarView, ICalendarRange, ICalendarEvent } from 'src/types/calendar'; import type { EventDropArg, DateSelectArg, EventClickArg } from '@fullcalendar/core/index.js'; import { useRef, useState, useCallback } from 'react'; import useMediaQuery from '@mui/material/useMediaQuery'; // ---------------------------------------------------------------------- export function useCalendar() { const calendarRef = useRef(null); const calendarEl = calendarRef.current; const smUp = useMediaQuery((theme) => theme.breakpoints.up('sm')); const [date, setDate] = useState(new Date()); const [openForm, setOpenForm] = useState(false); const [selectEventId, setSelectEventId] = useState(''); const [selectedRange, setSelectedRange] = useState(null); const [view, setView] = useState(smUp ? 'dayGridMonth' : 'listWeek'); const onOpenForm = useCallback(() => { setOpenForm(true); }, []); const onCloseForm = useCallback(() => { setOpenForm(false); setSelectedRange(null); setSelectEventId(''); }, []); const onInitialView = useCallback(() => { if (calendarEl) { const calendarApi = calendarEl.getApi(); const newView = smUp ? 'dayGridMonth' : 'listWeek'; calendarApi.changeView(newView); setView(newView); } }, [calendarEl, smUp]); const onChangeView = useCallback( (newView: ICalendarView) => { if (calendarEl) { const calendarApi = calendarEl.getApi(); calendarApi.changeView(newView); setView(newView); } }, [calendarEl] ); const onDateToday = useCallback(() => { if (calendarEl) { const calendarApi = calendarEl.getApi(); calendarApi.today(); setDate(calendarApi.getDate()); } }, [calendarEl]); const onDatePrev = useCallback(() => { if (calendarEl) { const calendarApi = calendarEl.getApi(); calendarApi.prev(); setDate(calendarApi.getDate()); } }, [calendarEl]); const onDateNext = useCallback(() => { if (calendarEl) { const calendarApi = calendarEl.getApi(); calendarApi.next(); setDate(calendarApi.getDate()); } }, [calendarEl]); const onSelectRange = useCallback( (arg: DateSelectArg) => { if (calendarEl) { const calendarApi = calendarEl.getApi(); calendarApi.unselect(); } onOpenForm(); setSelectedRange({ start: arg.startStr, end: arg.endStr }); }, [calendarEl, onOpenForm] ); const onClickEvent = useCallback( (arg: EventClickArg) => { const { event } = arg; onOpenForm(); setSelectEventId(event.id); }, [onOpenForm] ); const onResizeEvent = useCallback( (arg: EventResizeDoneArg, updateEvent: (eventData: Partial) => void) => { const { event } = arg; updateEvent({ id: event.id, allDay: event.allDay, start: event.startStr, end: event.endStr, }); }, [] ); const onDropEvent = useCallback( (arg: EventDropArg, updateEvent: (eventData: Partial) => void) => { const { event } = arg; updateEvent({ id: event.id, allDay: event.allDay, start: event.startStr, end: event.endStr, }); }, [] ); const onClickEventInFilters = useCallback( (eventId: string) => { if (eventId) { onOpenForm(); setSelectEventId(eventId); } }, [onOpenForm] ); return { calendarRef, /********/ view, date, /********/ onDatePrev, onDateNext, onDateToday, onDropEvent, onClickEvent, onChangeView, onSelectRange, onResizeEvent, onInitialView, /********/ openForm, onOpenForm, onCloseForm, /********/ selectEventId, selectedRange, /********/ onClickEventInFilters, }; }