11import { Table , TableBody , TableCell , TableContainer , TableHead , TableRow , Typography } from '@mui/material' ;
2- import { Availability , Event , getDayOfWeek , getNextSevenDays , User } from 'shared' ;
2+ import { Availability , Event , EventWithMembers , getDayOfWeek , getNextSevenDays , User } from 'shared' ;
33import React , { useState } from 'react' ;
44import { enumToArray , getBackgroundColor , NUMBER_OF_TIME_SLOTS , REVIEW_TIMES } from '../../utils/design-review.utils' ;
55import { datePipe } from '../../utils/pipes' ;
@@ -11,8 +11,10 @@ interface AvailabilityScheduleViewProps {
1111 usersToAvailabilities : Map < User , Availability [ ] > ;
1212 setCurrentAvailableUsers : ( val : User [ ] ) => void ;
1313 setCurrentUnavailableUsers : ( val : User [ ] ) => void ;
14- event : Event ;
14+ setCurrentHoveredSlot ?: ( slot : { day : Date ; startHour : number ; endHour : number } | null ) => void ;
15+ event : Event | EventWithMembers ;
1516 displayDate ?: Date ;
17+ onSlotScheduleClick ?: ( day : Date | null , startHour : number , endHour : number ) => void ;
1618}
1719
1820const AvailabilityScheduleView : React . FC < AvailabilityScheduleViewProps > = ( {
@@ -21,24 +23,56 @@ const AvailabilityScheduleView: React.FC<AvailabilityScheduleViewProps> = ({
2123 usersToAvailabilities,
2224 setCurrentAvailableUsers,
2325 setCurrentUnavailableUsers,
26+ setCurrentHoveredSlot,
2427 event,
25- displayDate
28+ displayDate,
29+ onSlotScheduleClick
2630} ) => {
2731 const totalUsers = usersToAvailabilities . size ;
2832 const [ selectedTimeslot , setSelectedTimeslot ] = useState < number | null > ( null ) ;
2933 // Use displayDate if provided, otherwise fall back to event's initial date
3034 const initialDate = displayDate || event . initialDateScheduled || new Date ( ) ;
3135 const potentialDays = getNextSevenDays ( initialDate ) ;
3236
33- const handleTimeslotClick = ( index : number , _day : Date ) => {
37+ // Handle hover - updates the sidebar with available/unavailable users and slot info
38+ const handleTimeslotHover = ( index : number , day : Date , timeIndex : number ) => {
39+ setCurrentAvailableUsers ( availableUsers . get ( index ) || [ ] ) ;
40+ setCurrentUnavailableUsers ( unavailableUsers . get ( index ) || [ ] ) ;
41+ if ( setCurrentHoveredSlot ) {
42+ const startHour = 10 + timeIndex ;
43+ const endHour = 11 + timeIndex ;
44+ setCurrentHoveredSlot ( { day, startHour, endHour } ) ;
45+ }
46+ } ;
47+
48+ // Handle mouse leave - clears the hover state and shows selected slot's users if any
49+ const handleMouseLeave = ( ) => {
50+ if ( setCurrentHoveredSlot ) {
51+ setCurrentHoveredSlot ( null ) ;
52+ }
53+ // If there's a selected slot, show its users
54+ if ( selectedTimeslot !== null ) {
55+ setCurrentAvailableUsers ( availableUsers . get ( selectedTimeslot ) || [ ] ) ;
56+ setCurrentUnavailableUsers ( unavailableUsers . get ( selectedTimeslot ) || [ ] ) ;
57+ }
58+ } ;
59+
60+ // Handle click - selects/deselects the time slot
61+ const handleTimeslotClick = ( index : number , day : Date , timeIndex : number ) => {
3462 if ( selectedTimeslot === index ) {
63+ // Deselect
3564 setSelectedTimeslot ( null ) ;
36- setCurrentAvailableUsers ( [ ] ) ;
37- setCurrentUnavailableUsers ( [ ] ) ;
65+ if ( onSlotScheduleClick ) {
66+ onSlotScheduleClick ( null , 0 , 0 ) ; // Clear selection in parent
67+ }
3868 } else {
69+ // Select
3970 setSelectedTimeslot ( index ) ;
40- setCurrentAvailableUsers ( availableUsers . get ( index ) || [ ] ) ;
41- setCurrentUnavailableUsers ( unavailableUsers . get ( index ) || [ ] ) ;
71+ if ( onSlotScheduleClick ) {
72+ const startHour = 10 + timeIndex ;
73+ const endHour = 11 + timeIndex ;
74+ onSlotScheduleClick ( day , startHour , endHour ) ;
75+ }
4276 }
4377 } ;
4478
@@ -77,17 +111,30 @@ const AvailabilityScheduleView: React.FC<AvailabilityScheduleViewProps> = ({
77111 < TableContainer
78112 sx = { {
79113 overflowX : 'auto' ,
80- overflowY : 'auto' ,
81- maxWidth : '100%'
114+ overflowY : 'hidden' ,
115+ height : '100%' ,
116+ display : 'flex' ,
117+ flexDirection : 'column'
82118 } }
119+ onMouseLeave = { handleMouseLeave }
83120 >
84121 < Table
85122 stickyHeader
123+ size = "small"
86124 sx = { {
125+ height : '100%' ,
126+ tableLayout : 'fixed' ,
87127 '& .MuiTableCell-head' : {
88- bgcolor : 'background.paper'
128+ bgcolor : 'background.paper' ,
129+ px : 0.5 ,
130+ py : 0.5
131+ } ,
132+ '& .MuiTableCell-body' : {
133+ px : 0 ,
134+ py : 0 ,
135+ height : `calc((100% - 40px) / 12)` // 12 time slots, minus header height
89136 } ,
90- minWidth : 650
137+ minWidth : 400
91138 } }
92139 >
93140 < TableHead >
@@ -113,12 +160,12 @@ const AvailabilityScheduleView: React.FC<AvailabilityScheduleViewProps> = ({
113160 { potentialDays . map ( ( day , dayIndex ) => {
114161 const index = dayIndex * enumToArray ( REVIEW_TIMES ) . length + timeIndex ;
115162 return (
116- < TableCell sx = { { p : 0 } } >
163+ < TableCell key = { index } sx = { { p : 0 } } >
117164 < EventTimeSlot
118- key = { index }
119165 backgroundColor = { getBackgroundColor ( availableUsers . get ( index ) ?. length , totalUsers ) }
120166 selected = { selectedTimeslot === index }
121- onClick = { ( ) => handleTimeslotClick ( index , day ) }
167+ onClick = { ( ) => handleTimeslotClick ( index , day , timeIndex ) }
168+ onMouseEnter = { ( ) => handleTimeslotHover ( index , day , timeIndex ) }
122169 />
123170 </ TableCell >
124171 ) ;
0 commit comments