frontend/src/tasks/TaskCalendar.tsx
2025-04-07 15:46:59 -06:00

128 lines
3.3 KiB
TypeScript

import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin, { DateClickArg } from "@fullcalendar/interaction";
import React, { useState } from "react";
import { useEffect } from "react";
import { Box } from "@mui/material";
import { Task } from "models";
import { EventClickArg } from "@fullcalendar/core";
interface Props {
dateClickMethod: (args: DateClickArg) => void;
taskClickMethod: (arg: EventClickArg) => void;
tasks: Task[];
changeDateCallback: (date: Date) => void;
initialView?: string;
initialDate?: Date;
centerToolbar?: string;
calHeight?: string | number;
hideToday?: boolean;
hideTitle?: boolean;
hideCal?: boolean;
hideCalCallback?: () => void;
}
interface Event {
id: string;
title: string;
start: Date;
end: Date;
backgroundColor: string;
}
export default function TaskCalendar(props: Props) {
const {
dateClickMethod,
taskClickMethod,
hideCalCallback,
changeDateCallback,
tasks,
initialView,
centerToolbar,
calHeight,
hideToday,
hideTitle,
hideCal
} = props;
const [events, setEvents] = useState<Event[]>([]);
let ref = React.createRef<FullCalendar>();
useEffect(() => {
setEvents([]);
let e: Event[] = [];
tasks.forEach(task => {
let event: Event = {
id: task.key,
title: task.title(),
start: new Date(task.start() + "T" + task.startTime()),
end: new Date(task.end() + "T" + task.endTime()),
backgroundColor: task.settings.colour
};
e.push(event);
setEvents([...e]);
});
}, [tasks]);
useEffect(() => {
if (ref.current && props.initialDate) {
let api = ref.current.getApi();
api.gotoDate(props.initialDate);
}
}, [props.initialDate, ref]);
return (
<Box>
<FullCalendar
ref={ref}
contentHeight={hideCal ? 0 : calHeight}
headerToolbar={{
start: hideTitle ? "" : "title",
center: centerToolbar,
end: hideToday ? "back,forward" : "today back,forward"
}}
titleFormat={{ month: "short", year: "numeric" }}
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
//options for view dayGridWeek, dayGridMonth, timeGridWeek, timeGridMonth, timeGridDay
initialView={initialView}
dateClick={dateClickMethod}
eventClick={taskClickMethod}
events={events}
allDaySlot={false}
slotEventOverlap={false}
nowIndicator
dayHeaders={!hideCal}
customButtons={{
hide: {
text: "Hide",
click: () => {
if (hideCalCallback) {
hideCalCallback();
}
}
},
back: {
text: "<",
click: () => {
if (ref.current) {
let api = ref.current.getApi();
api.prev();
changeDateCallback(api.getDate());
}
}
},
forward: {
text: ">",
click: () => {
if (ref.current) {
let api = ref.current.getApi();
api.next();
changeDateCallback(api.getDate());
}
}
}
}}
/>
</Box>
);
}