You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
orario/src/components/view/Course.jsx

77 lines
2.9 KiB
JavaScript

import { format } from 'date-fns'
import _ from 'lodash'
import { useEffect, useRef, useState } from 'preact/hooks'
import { prettyCourseName, WEEK_DAYS } from '../../utils.jsx'
export const Course = ({ events, selection, setSelection, hideOtherCourses }) => {
const selectionSet = new Set(selection)
const visibleEvents = !hideOtherCourses ? events : events.filter(e => selectionSet.has(e.id))
const eventsByCourse = _.groupBy(_.sortBy(visibleEvents, 'id'), 'id')
const profsPerCourse = _.mapValues(eventsByCourse, events =>
_.uniq(events.flatMap(event => event.docenti))
)
const [currentlyHovered, setCurrentlyHovered] = useState(null)
const element = useRef()
useEffect(() => {
if (element.current) {
const l = e => {
const isMobile = window.matchMedia('(pointer: coarse)').matches
const $course = e.target.closest('.course')
if ($course && !isMobile) {
setCurrentlyHovered($course.dataset.courseId)
} 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 (
<div class="course-view" ref={element}>
<div class="wrap-container">
{Object.entries(eventsByCourse).map(([id, courseEvents]) => (
<div
class={
'course' +
(currentlyHovered === id ? ' highlight' : '') +
(selectionSet.has(id) ? ' selected' : '')
}
data-course-id={id}
onClick={() => {
if (!selectionSet.has(id)) setSelection([...selection, id])
else setSelection(selection.filter(selId => selId !== id))
}}
>
<div class="title">{prettyCourseName(courseEvents[0].name)}</div>
<div class="docenti">{profsPerCourse[id].join(', ')}</div>
<div class="events">
{courseEvents.map(course => (
<div>
{WEEK_DAYS[course.start.getDay()]}{' '}
{format(course.start, 'H:mm')}&ndash;
{format(course.end, 'H:mm')} {course.aule.join(', ')}
</div>
))}
</div>
</div>
))}
</div>
</div>
)
}