import React, { useState } from "react"; import { EventClickArg } from "@fullcalendar/core"; import { DateClickArg } from "@fullcalendar/interaction"; import { useGlobalState } from "providers"; import { useMobile, useSnackbar } from "hooks"; import { useTaskAPI } from "providers"; import { useEffect, useCallback } from "react"; import TaskCalendar from "./TaskCalendar"; import TaskList from "./TaskList"; import { Box, Button, Fab, Grid2 as Grid, LinearProgress, Theme, Typography } from "@mui/material"; import { Task } from "models"; import TaskSettings from "./TaskSettings"; import { DayPicker } from "react-day-picker"; import "react-day-picker/dist/style.css"; import AddIcon from "@mui/icons-material/Add"; import TaskDrawer from "./TaskDrawer"; import moment from "moment"; import { makeStyles } from "@mui/styles"; interface ViewProps { // objectKey?: string; //only used to save it for the object --Deprecated with new permission structure-- keys?: string[]//the keys and types are used to give th object permissions to the task, that is how they will be linked now types?: string[] label?: string; drawerView?: boolean; // loadKeys?: string[]; //if you want to load tasks for a specific object(s) --Deprecated with new permission structure-- it should use the keys and types now overlayButton?: boolean; } interface TabPanelProps { children?: React.ReactNode; index: any; value: any; } const useStyles = makeStyles((theme: Theme) => { return ({ active: { color: theme.palette.getContrastText(theme.palette.secondary.main), backgroundColor: theme.palette.secondary.main, width: theme.spacing(5), height: theme.spacing(5), border: 0, "&:hover": { backgroundColor: theme.palette.secondary.main } }, fab: { zIndex: 20, background: theme.palette.primary.main, "&:hover": { background: theme.palette.primary.main }, "&:focus": { background: theme.palette.primary.main }, position: "absolute", bottom: theme.spacing(8), //for mobile navigator right: theme.spacing(2), [theme.breakpoints.up("sm")]: { bottom: theme.spacing(2) } }, overlayFab: { zIndex: 20, background: theme.palette.primary.main, "&:hover": { background: theme.palette.primary.main }, "&:focus": { background: theme.palette.primary.main }, position: "fixed", bottom: theme.spacing(8), //for mobile navigator right: theme.spacing(2), [theme.breakpoints.up("sm")]: { bottom: theme.spacing(2) } } }); }); export default function TaskViewer(props: ViewProps) { const { //objectKey, label, drawerView, //loadKeys, keys, types, overlayButton } = props; const [{ user, as }] = useGlobalState(); const taskAPI = useTaskAPI(); const { openSnack } = useSnackbar(); const [tasks, setTasks] = useState>(new Map([])); const [viewTask, setViewTask] = useState(); const [newTaskDialog, setNewTaskDialog] = useState(false); const [editTask, setEditTask] = useState(); const [loaded, setLoaded] = useState(false); const [currentDate, setCurrentDate] = useState(new Date()); const isMobile = useMobile(); const [value, setValue] = useState(0); const classes = useStyles(); const [expand, setExpand] = useState(false); const [hideCal, setHideCal] = useState(false); const [openDrawer, setOpenDrawer] = useState(false); const [nextMonth, setNextMonth] = useState( moment(currentDate) .add(2, "month") .format("YYYY-MM") ); const [prevMonth, setPrevMonth] = useState( moment(currentDate) .subtract(1, "month") .format("YYYY-MM") ); //initial states for the task variables const [startDate, setStartDate] = useState(); //functions for opening and closing the newTaskDialog const openCalendarDialog = (args: DateClickArg) => { //assign the date of task when the dialog box is opened setStartDate(args.dateStr); openDialog(); }; const openDialog = () => { setNewTaskDialog(true); }; //functions for opening and closing the selectedTaskDialog if selected from the calendar const openSelectedTask = (taskId: string) => { let task = tasks.get(taskId); if (task) { setOpenDrawer(true); setViewTask(task); } }; //loads tasks from the backend database const loadTasks = useCallback(() => { if (!user.id()) return; let temp = new Map(); taskAPI .listTasks(50, 0, "asc", "start", undefined, undefined, as, prevMonth, nextMonth, keys, types) .then(resp => { if(resp.data.tasks){ resp.data.tasks.forEach(task => { if (task.settings) { temp.set(task.key, Task.any(task)); } }); } setTasks(temp); setLoaded(true); }) .catch(err => { openSnack("Failed to load tasks"); }); }, [taskAPI, as, user, openSnack, nextMonth, prevMonth, keys, types]); useEffect(() => { // if (drawerView) { // setTasks(new Map()); // setValue(1); // loadMultitask(); // } else { // loadTasks(); // } loadTasks() }, [loadTasks, as, drawerView]); const markComplete = (task: Task) => { task.settings.complete = !task.settings.complete; taskAPI .updateTask(task.key, task.settings, undefined, as) .then(resp => { openSnack("Task Updated"); loadTasks(); }) .catch(err => { openSnack("Failed to update task"); }); }; const deleteTask = (task: Task) => { taskAPI .removeTask(task.key, as) .then(resp => { openSnack("Task Removed"); loadTasks(); }) .catch(err => { openSnack("Failed to remove task"); }); }; function TabPanelMine(props: TabPanelProps) { const { children, value, index, ...other } = props; return ( ); } const resize = () => { setHideCal(!hideCal); setExpand(!expand); }; const viewer = () => { return ( {isMobile || drawerView ? ( openSelectedTask(arg.event.id)} centerToolbar={"hide"} initialView="dayGridWeek" initialDate={currentDate} calHeight={"22vh"} hideToday hideCal={hideCal} hideCalCallback={resize} changeDateCallback={date => { if (currentDate.getMonth() !== date.getMonth()) { setCurrentDate(date); setNextMonth( moment(date) .add(2, "month") .format("YYYY-MM") ); setPrevMonth( moment(date) .subtract(1, "month") .format("YYYY-MM") ); loadTasks(); } setCurrentDate(date); }} /> openSelectedTask(arg.event.id)} initialView="timeGridDay" initialDate={currentDate} calHeight={expand ? "59vh" : "37vh"} hideTitle changeDateCallback={date => { if (currentDate.getMonth() !== date.getMonth()) { setCurrentDate(date); setNextMonth( moment(date) .add(2, "month") .format("YYYY-MM") ); setPrevMonth( moment(date) .subtract(1, "month") .format("YYYY-MM") ); loadTasks(); } setCurrentDate(date); }} /> loadTasks()} dateToView={drawerView ? undefined : currentDate} openTask={(taskId: string) => openSelectedTask(taskId)} keys={[]} types={[]} /> ) : ( { if (!date) return; if (currentDate.getMonth() !== date.getMonth()) { setCurrentDate(date); setNextMonth( moment(date) .add(2, "month") .format("YYYY-MM") ); setPrevMonth( moment(date) .subtract(1, "month") .format("YYYY-MM") ); loadTasks(); } setCurrentDate(date); }} /> loadTasks()} listHeight={"40vh"} dateToView={currentDate} openTask={(taskId: string) => openSelectedTask(taskId)} keys={[]} types={[]} /> openSelectedTask(arg.event.id)} initialView="timeGridWeek" centerToolbar="dayGridMonth,timeGridWeek,timeGridDay" initialDate={currentDate} calHeight={"80vh"} changeDateCallback={date => { if (currentDate.getMonth() !== date.getMonth()) { setCurrentDate(date); setNextMonth( moment(date) .add(2, "month") .format("YYYY-MM") ); setPrevMonth( moment(date) .subtract(1, "month") .format("YYYY-MM") ); loadTasks(); } setCurrentDate(date); }} /> )} ); }; return ( {!loaded ? : viewer()} { loadTasks(); setEditTask(undefined); setNewTaskDialog(false); }} /> {viewTask && { setOpenDrawer(false) loadTasks() }} completeTask={markComplete} deleteTask={deleteTask} keys={keys ?? []} types={types ?? []} /> } ); }