diff --git a/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx b/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx index bbe670e33..817d4cf1d 100644 --- a/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx +++ b/apps/antalmanac/src/components/Calendar/CalendarRoot.tsx @@ -1,9 +1,9 @@ import 'react-big-calendar/lib/css/react-big-calendar.css'; import './calendar.css'; -import { Box, ClickAwayListener, Popper } from '@material-ui/core'; +import { Box, Popover } from '@material-ui/core'; import moment from 'moment'; -import { memo, SyntheticEvent, useCallback, useEffect, useMemo, useState } from 'react'; +import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { Calendar, DateLocalizer, momentLocalizer, Views } from 'react-big-calendar'; import { shallow } from 'zustand/shallow'; @@ -14,17 +14,16 @@ import { CalendarCourseEvent } from '$components/Calendar/calendar-course-event' import { getDefaultFinalsStartDate, getFinalsStartDateForTerm } from '$lib/termData'; import AppStore from '$stores/AppStore'; import { useHoveredStore } from '$stores/HoveredStore'; +import { useSelectedEventStore } from '$stores/SelectedEventStore'; import { useTimeFormatStore } from '$stores/SettingsStore'; const localizer = momentLocalizer(moment); const views = [Views.WEEK, Views.WORK_WEEK]; const components = { event: CalendarCourseEvent }; +const max = new Date(2018, 0, 1, 23); export const ScheduleCalendar = memo(() => { - const [anchorEl, setAnchorEl] = useState(null); const [showFinalsSchedule, setShowFinalsSchedule] = useState(false); - const [courseInMoreInfo, setCourseInMoreInfo] = useState(null); - const [calendarEventKey, setCalendarEventKey] = useState(null); const [eventsInCalendar, setEventsInCalendar] = useState(() => AppStore.getEventsInCalendar()); const [finalsEventsInCalendar, setFinalEventsInCalendar] = useState(() => AppStore.getFinalEventsInCalendar()); const [currentScheduleIndex, setCurrentScheduleIndex] = useState(() => AppStore.getCurrentScheduleIndex()); @@ -35,6 +34,10 @@ export const ScheduleCalendar = memo(() => { (state) => [state.hoveredCalendarizedCourses, state.hoveredCalendarizedFinal], shallow ); + const [anchorEl, selectedEvent, setSelectedEvent] = useSelectedEventStore( + (state) => [state.selectedEventAnchorEl, state.selectedEvent, state.setSelectedEvent], + shallow + ); const getEventsForCalendar = useCallback((): CalendarEvent[] => { if (showFinalsSchedule) @@ -54,25 +57,14 @@ export const ScheduleCalendar = memo(() => { const events = useMemo(() => getEventsForCalendar(), [getEventsForCalendar]); const handleClosePopover = useCallback(() => { - setAnchorEl(null); - }, []); + setSelectedEvent(null, null); + }, [setSelectedEvent]); const toggleDisplayFinalsSchedule = useCallback(() => { handleClosePopover(); setShowFinalsSchedule((prevState) => !prevState); }, [handleClosePopover]); - const handleEventClick = useCallback((event: CalendarEvent, e: SyntheticEvent) => { - const { currentTarget } = e; - e.stopPropagation(); - - if (event.isCustomEvent || event.sectionType !== 'Fin') { - setAnchorEl((prevAnchorEl) => (prevAnchorEl === currentTarget ? null : currentTarget)); - setCourseInMoreInfo(event); - setCalendarEventKey(Math.random()); - } - }, []); - /** * Finds the earliest start time and returns that or 7AM, whichever is earlier * @returns A date with the earliest time or 7AM @@ -198,35 +190,27 @@ export const ScheduleCalendar = memo(() => { /> - - - - - - - + {selectedEvent ? ( + + + + ) : null} localizer={localizer} @@ -235,18 +219,23 @@ export const ScheduleCalendar = memo(() => { views={views} defaultView={Views.WORK_WEEK} view={hasWeekendCourse ? Views.WEEK : Views.WORK_WEEK} - onView={undefined} + onView={() => { + return; + }} step={15} timeslots={2} date={date} - onNavigate={undefined} + onNavigate={() => { + return; + }} min={getStartTime()} - max={new Date(2018, 0, 1, 23)} + max={max} events={events} eventPropGetter={eventStyleGetter} showMultiDayTimes={false} components={components} - onSelectEvent={handleEventClick} + onSelectEvent={undefined} + onSelectSlot={undefined} /> diff --git a/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx b/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx index f1636ce66..b16ebf1aa 100644 --- a/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx +++ b/apps/antalmanac/src/components/Calendar/CourseCalendarEvent.tsx @@ -23,7 +23,7 @@ import { formatTimes } from '$stores/calendarizeHelpers'; const styles: Styles = { courseContainer: { padding: '0.5rem', - margin: '0 1rem', + margin: '0 0.5rem', minWidth: '15rem', }, customEventContainer: { @@ -125,7 +125,7 @@ export interface CourseEvent extends CommonCalendarEvent { } /** - * There is another CustomEvent interface in CourseCalendarEvent and they are slightly different. The this one represents only one day, like the event on Monday, and needs to be duplicated to be repeated across multiple days. The other one, `CustomEventDialog`'s `RepeatingCustomEvent`, encapsulates the occurences of an event on multiple days, like Monday Tuesday Wednesday all in the same object as specified by the `days` array. + * There is another CustomEvent interface in CourseCalendarEvent and they are slightly different. The this one represents only one day, like the event on Monday, and needs to be duplicated to be repeated across multiple days. The other one, `CustomEventDialog`'s `RepeatingCustomEvent`, encapsulates the occurrences of an event on multiple days, like Monday Tuesday Wednesday all in the same object as specified by the `days` array. * https://github.com/icssc/AntAlmanac/wiki/The-Great-AntAlmanac-TypeScript-Rewritening%E2%84%A2#duplicate-interface-names-%EF%B8%8F */ export interface CustomEvent extends CommonCalendarEvent { @@ -139,7 +139,7 @@ export type CalendarEvent = CourseEvent | CustomEvent; interface CourseCalendarEventProps { classes: ClassNameMap; - courseInMoreInfo: CalendarEvent; + selectedEvent: CalendarEvent; scheduleNames: string[]; closePopover: () => void; } @@ -172,10 +172,10 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => { setActiveTab(2); }, [setActiveTab]); - const { classes, courseInMoreInfo } = props; + const { classes, selectedEvent } = props; - if (!courseInMoreInfo.isCustomEvent) { - const { term, instructors, sectionCode, title, finalExam, locations, sectionType } = courseInMoreInfo; + if (!selectedEvent.isCustomEvent) { + const { term, instructors, sectionCode, title, finalExam, locations, sectionType } = selectedEvent; let finalExamString = ''; @@ -269,10 +269,10 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => { Color @@ -282,7 +282,7 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => { ); } else { - const { title, customEventID, building } = courseInMoreInfo; + const { title, customEventID, building } = selectedEvent; return (
{title}
@@ -301,9 +301,9 @@ const CourseCalendarEvent = (props: CourseCalendarEventProps) => {
diff --git a/apps/antalmanac/src/components/Calendar/calendar-course-event.tsx b/apps/antalmanac/src/components/Calendar/calendar-course-event.tsx index c19829abb..601644e8b 100644 --- a/apps/antalmanac/src/components/Calendar/calendar-course-event.tsx +++ b/apps/antalmanac/src/components/Calendar/calendar-course-event.tsx @@ -1,13 +1,25 @@ import { Box } from '@material-ui/core'; import { memo } from 'react'; +import { shallow } from 'zustand/shallow'; import { CalendarEvent } from '$components/Calendar/CourseCalendarEvent'; import locationIds from '$lib/location_ids'; +import { useSelectedEventStore } from '$stores/SelectedEventStore'; export const CalendarCourseEvent = memo(({ event }: { event: CalendarEvent }) => { + const setSelectedEvent = useSelectedEventStore((state) => state.setSelectedEvent, shallow); + + const handleClick = (e: React.MouseEvent) => { + console.log('what'); + e.preventDefault(); + e.stopPropagation(); + + setSelectedEvent(e, event); + }; + if (event.isCustomEvent) { return ( - + } return ( - + {event.showLocationInfo ? event.locations.map((location) => `${location.building} ${location.room}`).join(', ') : event.locations.length > 1 - ? `${event.locations.length} Locations` - : `${event.locations[0].building} ${event.locations[0].room}`} + ? `${event.locations.length} Locations` + : `${event.locations[0].building} ${event.locations[0].room}`} {event.sectionCode} diff --git a/apps/antalmanac/src/stores/SelectedEventStore.ts b/apps/antalmanac/src/stores/SelectedEventStore.ts new file mode 100644 index 000000000..8f779d20f --- /dev/null +++ b/apps/antalmanac/src/stores/SelectedEventStore.ts @@ -0,0 +1,23 @@ +import { SyntheticEvent } from 'react'; +import { create } from 'zustand'; + +import { CalendarEvent } from '$components/Calendar/CourseCalendarEvent'; + +export interface SelectedEventStore { + selectedEvent: CalendarEvent | null; + selectedEventAnchorEl: Element | null; + setSelectedEvent: (anchorEl: SyntheticEvent | null, selectedEvent: CalendarEvent | null) => void; +} + +export const useSelectedEventStore = create((set) => { + return { + selectedEvent: null, + selectedEventAnchorEl: null, + setSelectedEvent: (anchorEl: SyntheticEvent | null, selectedEvent: CalendarEvent | null) => { + set({ + selectedEvent: selectedEvent, + selectedEventAnchorEl: anchorEl?.currentTarget, + }); + }, + }; +});