1- import { useState } from 'react' ;
1+ import { useState , useRef , useEffect } from 'react' ;
22import { Box , Card , CardContent , Grid , Stack , Tooltip , Typography , useTheme } from '@mui/material' ;
33import { Calendar , ConflictStatus , DayOfWeek , EventInstance , EventStatus , EventType } from 'shared' ;
44import ConstructionIcon from '@mui/icons-material/Construction' ;
@@ -48,6 +48,11 @@ interface CalendarDayCardProps {
4848 onCreateEventClick : ( date : Date ) => void ;
4949}
5050
51+ // Constants for dynamic event display calculation
52+ const TITLE_HEIGHT = 28 ; // Height of the day number title
53+ const EVENT_CARD_HEIGHT = 24 ; // Height of each event card
54+ const EVENT_MARGIN = 4 ; // Margin between events
55+
5156const CalendarDayCard : React . FC < CalendarDayCardProps > = ( {
5257 cardDate,
5358 displayMonth,
@@ -78,6 +83,28 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
7883 const [ selectedEvent , setSelectedEvent ] = useState < EventInstance | null > ( null ) ;
7984 const toast = useToast ( ) ;
8085
86+ // Ref and state for dynamic event count calculation
87+ const containerRef = useRef < HTMLDivElement > ( null ) ;
88+ const [ maxVisibleEvents , setMaxVisibleEvents ] = useState ( 2 ) ;
89+
90+ // Calculate how many events can fit based on container height
91+ useEffect ( ( ) => {
92+ const calculateMaxEvents = ( ) => {
93+ if ( containerRef . current ) {
94+ const containerHeight = containerRef . current . clientHeight ;
95+ const availableHeight = containerHeight - TITLE_HEIGHT ;
96+ const eventSlotHeight = EVENT_CARD_HEIGHT + EVENT_MARGIN ;
97+ // Reserve space for the "+N more" card if there are extra events
98+ const maxEvents = Math . max ( 1 , Math . floor ( availableHeight / eventSlotHeight ) ) ;
99+ setMaxVisibleEvents ( maxEvents ) ;
100+ }
101+ } ;
102+
103+ calculateMaxEvents ( ) ;
104+ window . addEventListener ( 'resize' , calculateMaxEvents ) ;
105+ return ( ) => window . removeEventListener ( 'resize' , calculateMaxEvents ) ;
106+ } , [ ] ) ;
107+
81108 const { mutateAsync : deleteEvent } = useDeleteEvent ( selectedEvent ?. eventId ?? '' ) ;
82109 const { mutateAsync : deleteScheduleSlot } = useDeleteScheduleSlot (
83110 selectedEvent ?. eventId ?? '' ,
@@ -169,7 +196,7 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
169196 return (
170197 < Box
171198 marginLeft = { 0.5 }
172- marginBottom = { 0.5 }
199+ marginBottom = { 0.25 }
173200 marginRight = { 0.5 }
174201 onMouseEnter = { ( ) => setIsHovered ( true ) }
175202 onMouseLeave = { ( ) => {
@@ -194,8 +221,8 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
194221 backgroundColor : bgColor ,
195222 borderRadius : 1 ,
196223 width : '100%' ,
197- minHeight : 30 ,
198- maxHeight : 30 ,
224+ minHeight : EVENT_CARD_HEIGHT ,
225+ maxHeight : EVENT_CARD_HEIGHT ,
199226 ...( isPending && {
200227 border : `1px dashed ${ baseColor } ` ,
201228 opacity : 0.8
@@ -259,7 +286,7 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
259286 >
260287 < Typography
261288 marginX = { 0.5 }
262- marginY = { 0.6 }
289+ marginY = { 0.3 }
263290 lineHeight = "120%"
264291 fontSize = { 14 }
265292 fontWeight = "bold"
@@ -359,7 +386,7 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
359386
360387 const ExtraEventsCard = ( { extraEvents } : { extraEvents : EventInstance [ ] } ) => {
361388 return (
362- < Box marginLeft = { 0.5 } marginRight = { 0.5 } marginBottom = { 0.2 } sx = { { position : 'relative' , zIndex : 2 } } >
389+ < Box marginLeft = { 0.5 } marginRight = { 0.5 } marginBottom = { 0.25 } sx = { { position : 'relative' , zIndex : 2 } } >
363390 < Tooltip
364391 placement = "right"
365392 arrow
@@ -406,8 +433,8 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
406433 backgroundColor : theme . palette . grey [ 800 ] ,
407434 borderRadius : 1 ,
408435 width : '100%' ,
409- minHeight : 30 ,
410- maxHeight : 30 ,
436+ minHeight : EVENT_CARD_HEIGHT ,
437+ maxHeight : EVENT_CARD_HEIGHT ,
411438 display : 'flex' ,
412439 alignItems : 'center' ,
413440 justifyContent : 'center'
@@ -441,6 +468,7 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
441468 ) }
442469
443470 < Card
471+ ref = { containerRef }
444472 onMouseEnter = { ( ) => isClickable && setIsHovered ( true ) }
445473 onMouseLeave = { ( ) => setIsHovered ( false ) }
446474 sx = { {
@@ -470,19 +498,22 @@ const CalendarDayCard: React.FC<CalendarDayCardProps> = ({
470498
471499 < CardContent sx = { { padding : 0 } } >
472500 < DayCardTitle />
473- { events . length === 1 ? (
474- < EventCard event = { events [ 0 ] } />
475- ) : events . length === 2 ? (
476- < >
477- < EventCard event = { events [ 0 ] } />
478- < EventCard event = { events [ 1 ] } />
479- </ >
480- ) : events . length >= 3 ? (
501+ { events . length > 0 && (
481502 < >
482- < EventCard event = { events [ 0 ] } />
483- < ExtraEventsCard extraEvents = { events . slice ( 1 ) } />
503+ { events . length <= maxVisibleEvents ? (
504+ // All events fit - show them all
505+ events . map ( ( event ) => < EventCard key = { event . eventId } event = { event } /> )
506+ ) : (
507+ // Too many events - show as many as possible with "+N more"
508+ < >
509+ { events . slice ( 0 , maxVisibleEvents - 1 ) . map ( ( event ) => (
510+ < EventCard key = { event . eventId } event = { event } />
511+ ) ) }
512+ < ExtraEventsCard extraEvents = { events . slice ( maxVisibleEvents - 1 ) } />
513+ </ >
514+ ) }
484515 </ >
485- ) : null }
516+ ) }
486517 </ CardContent >
487518 </ Card >
488519
0 commit comments