diff --git a/__test__/components/MiniCalendarColor.test.tsx b/__test__/components/MiniCalendarColor.test.tsx index c89f957..6aff578 100644 --- a/__test__/components/MiniCalendarColor.test.tsx +++ b/__test__/components/MiniCalendarColor.test.tsx @@ -30,6 +30,7 @@ describe("MiniCalendar", () => { "667037022b752d0026472254/cal1": { name: "Calendar 1", color: "#FF0000", + ownerEmails: ["test@test.com"], events: { event1: { calId: "667037022b752d0026472254/cal1", @@ -139,6 +140,7 @@ describe("Found Bugs", () => { "667037022b752d0026472254/cal1": { name: "Calendar 1", color: "#FF0000", + ownerEmails: ["test.test@test.com"], events: { event1: { calId: "667037022b752d0026472254/cal1", diff --git a/src/components/Calendar/Calendar.css b/src/components/Calendar/Calendar.css index 25b0eb7..769dcac 100644 --- a/src/components/Calendar/Calendar.css +++ b/src/components/Calendar/Calendar.css @@ -27,6 +27,18 @@ main { position: relative; } +.declined-event { + opacity: 0.7; +} + +.tentative-event { +} + +.needs-action-event { + opacity: 0.7; + border: dashed 1px #ffffff; +} + .fc .fc-timegrid-slot { height: 30px !important; min-height: 30px !important; diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 2018731..ecea758 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -27,12 +27,17 @@ import { Calendars } from "../../features/Calendars/CalendarTypes"; import { push } from "redux-first-history"; import EventDisplayModal from "../../features/Events/EventDisplay"; import { createSelector } from "@reduxjs/toolkit"; +import HelpOutlineIcon from "@mui/icons-material/HelpOutline"; +import ClearIcon from "@mui/icons-material/Clear"; +import AccessTimeIcon from "@mui/icons-material/AccessTime"; +import { userAttendee } from "../../features/User/userDataTypes"; export default function CalendarApp() { const calendarRef = useRef(null); const [selectedDate, setSelectedDate] = useState(new Date()); const [selectedMiniDate, setSelectedMiniDate] = useState(new Date()); const tokens = useAppSelector((state) => state.user.tokens); + const user = useAppSelector((state) => state.user.userData); const dispatch = useAppDispatch(); if (!tokens) { @@ -372,6 +377,82 @@ export default function CalendarApp() { center: "prev,today,next", right: "dayGridMonth,timeGridWeek,timeGridDay", }} + eventContent={(arg) => { + const event = arg.event; + if (!calendars[arg.event._def.extendedProps.calId]) return; + + const attendees = event._def.extendedProps.attendee || []; + let Icon = null; + let titleStyle: React.CSSProperties = {}; + const ownerEmails = new Set( + calendars[arg.event._def.extendedProps.calId].ownerEmails?.map( + (email) => email.toLowerCase() + ) + ); + const showSpecialDisplay = attendees.filter((att: userAttendee) => + ownerEmails.has(att.cal_address.toLowerCase()) + ); + if (!showSpecialDisplay[0]) return; + switch (showSpecialDisplay[0].partstat) { + case "DECLINED": + Icon = null; + titleStyle.textDecoration = "line-through"; + break; + case "TENTATIVE": + Icon = HelpOutlineIcon; + break; + case "NEEDS-ACTION": + Icon = AccessTimeIcon; + break; + case "ACCEPTED": + Icon = null; + break; + default: + break; + } + + return ( +
+ {Icon && } + {event.title} +
+ ); + }} + eventDidMount={(arg) => { + const attendees = arg.event._def.extendedProps.attendee || []; + if (!calendars[arg.event._def.extendedProps.calId]) return; + const ownerEmails = new Set( + calendars[arg.event._def.extendedProps.calId].ownerEmails?.map( + (email) => email.toLowerCase() + ) + ); + const showSpecialDisplay = attendees.filter((att: userAttendee) => + ownerEmails.has(att.cal_address.toLowerCase()) + ); + + if (!showSpecialDisplay[0]) return; + + // Clear previously applied classes + arg.el.classList.remove( + "declined-event", + "tentative-event", + "needs-action-event" + ); + + switch (showSpecialDisplay[0].partstat) { + case "DECLINED": + arg.el.classList.add("declined-event"); + break; + case "TENTATIVE": + arg.el.classList.add("tentative-event"); + break; + case "NEEDS-ACTION": + arg.el.classList.add("needs-action-event"); + break; + default: + break; + } + }} />