Files
HKSingleParty/03_source/frontend/src/sections/calendar/hooks/use-calendar.ts

175 lines
4.0 KiB
TypeScript

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<FullCalendar>(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<ICalendarRange>(null);
const [view, setView] = useState<ICalendarView>(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<ICalendarEvent>) => 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<ICalendarEvent>) => 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,
};
}