import { useEffect, useRef, useState } from 'preact/hooks' import _ from 'lodash' import { differenceInMinutes, startOfDay } from 'date-fns' import { hashString, normalizeCourseName, WEEK_DAYS } from '../../utils.jsx' import { layoutIntervals } from '../../interval-layout.js' export const WorkWeekGrid = ({ events, selection, setSelection, hideOtherCourses }) => { const selectionSet = new Set(selection) const colorList = [ 'red', 'purple', 'blue', 'yellow', 'green', 'orange', 'lightblue', ]; const courses = _.uniqBy(!hideOtherCourses ? events : events.filter(e => selectionSet.has(e.id)), event => event.id); const colors = Object.fromEntries(courses.map((course, index) => { return [ course.id, [ colorList[index % colorList.length], courses.length <= colorList.length ? '' : String.fromCharCode(65 + Math.floor(index / colorList.length)) ] ]; })); const base = { 1: [], 2: [], 3: [], 4: [], 5: [], } const eventsByWeekday = { ... base, ... _.groupBy( !hideOtherCourses ? events : events.filter(e => selectionSet.has(e.id)), event => event.start.getDay() ) } const dayIntervalLayout = _.mapValues(eventsByWeekday, events => layoutIntervals( events.map(e => ({ start: differenceInMinutes(e.start, startOfDay(e.start)), end: differenceInMinutes(e.end, startOfDay(e.start)), data: e, })) ) ) const startsAndEnds = Object.entries(dayIntervalLayout).flatMap(([index, layout]) => layout.flatMap(events => events.map(event => [event.start, event.end]))); const minStart = Math.min(...startsAndEnds.map(([s, e]) => s)) / 60; const maxEnd = Math.max(...startsAndEnds.map(([s, e]) => e)) / 60; // const timeStart = minStart < 9 ? 7 : // minStart < 11 ? 9 : // minStart < 13 ? 11 : // minStart < 14 ? 13 : // minStart < 16 ? 14 : // minStart < 18 ? 16 : // 18; // const timeEnd = maxEnd > 18 ? 20 : // maxEnd > 16 ? 18 : // maxEnd > 14 ? 16 : // maxEnd > 13 ? 14 : // maxEnd > 11 ? 13 : // maxEnd > 9 ? 11 : // 9; const timeStart = minStart < 9 ? 7 : 9; const timeEnd = maxEnd > 18 ? 20 : 18; const daySizes = Object.entries(dayIntervalLayout).map(([index, layout]) => Math.max(1, layout.length)); const dayOffsets = daySizes.map((v, i) => { let sum = 0; for(let j = 0; j < i; j++) { sum += daySizes[j]; } return sum; }); const daysLength = daySizes[4] + dayOffsets[4]; const [currentlyHovered, setCurrentlyHovered] = useState(null) const element = useRef() useEffect(() => { if (element.current) { const l = e => { const $event = e.target.closest('.event') if ($event) { setCurrentlyHovered($event.dataset.eventId) } else { setCurrentlyHovered(null) } } element.current.addEventListener('mousemove', l) element.current.addEventListener('mouseleave', l) return () => { element.current.removeEventListener('mousemove', l) element.current.removeEventListener('mouseleave', l) } } }, [element.current]) return (