@@ -26,6 +26,37 @@ export const formatPrettyDate = (dateString: string): string => {
2626 }
2727}
2828
29+ /**
30+ * Format event date(s) in short format
31+ * Single day: "Friday Oct 31"
32+ * Multiple days: "Fri Oct 31 to Mon Nov 3"
33+ */
34+ export const formatEventDate = ( startDateString : string , endDateString ?: string | null ) : string => {
35+ try {
36+ const startDate = new Date ( removeTimezoneInfo ( startDateString ) ) ;
37+
38+ // If no end date or end date is the same day as start date
39+ if ( ! endDateString ) {
40+ return format ( startDate , "EEEE MMM d" ) ;
41+ }
42+
43+ const endDate = new Date ( removeTimezoneInfo ( endDateString ) ) ;
44+
45+ // Check if events are on the same day (ignoring time)
46+ const startDateOnly = new Date ( startDate . getFullYear ( ) , startDate . getMonth ( ) , startDate . getDate ( ) ) ;
47+ const endDateOnly = new Date ( endDate . getFullYear ( ) , endDate . getMonth ( ) , endDate . getDate ( ) ) ;
48+
49+ if ( startDateOnly . getTime ( ) === endDateOnly . getTime ( ) ) {
50+ return format ( startDate , "EEEE MMM d" ) ;
51+ }
52+
53+ // Multi-day event
54+ return `${ format ( startDate , "EEE MMM d" ) } to ${ format ( endDate , "EEE MMM d" ) } ` ;
55+ } catch {
56+ return startDateString ; // Return original string if parsing fails
57+ }
58+ }
59+
2960/**
3061 * Format a time string to a prettier format (e.g., "3pm" or "3:30pm")
3162 */
@@ -94,10 +125,13 @@ export const formatDtstartToMidnight = (dtstart: string): string => {
94125
95126/**
96127 * Get date category for event grouping (today, tomorrow, later this week, later this month, later, past)
128+ * For multi-day events, checks if today falls within the event's date range
97129 */
98- export const getDateCategory = ( dateString : string ) : 'today' | 'tomorrow' | 'later this week' | 'later this month' | 'later' | 'past' => {
130+ export const getDateCategory = ( startDateString : string , endDateString ?: string | null ) : 'today' | 'tomorrow' | 'later this week' | 'later this month' | 'later' | 'past' => {
99131 try {
100- const eventDate = new Date ( removeTimezoneInfo ( dateString ) ) ;
132+ const eventStartDate = new Date ( removeTimezoneInfo ( startDateString ) ) ;
133+ const eventEndDate = endDateString ? new Date ( removeTimezoneInfo ( endDateString ) ) : null ;
134+
101135 const today = new Date ( ) ;
102136 const tomorrow = new Date ( today ) ;
103137 tomorrow . setDate ( today . getDate ( ) + 1 ) ;
@@ -111,21 +145,28 @@ export const getDateCategory = (dateString: string): 'today' | 'tomorrow' | 'lat
111145 const endOfMonth = new Date ( today . getFullYear ( ) , today . getMonth ( ) + 1 , 0 ) ;
112146
113147 // Reset time to start of day for comparison
114- const eventDateOnly = new Date ( eventDate . getFullYear ( ) , eventDate . getMonth ( ) , eventDate . getDate ( ) ) ;
148+ const eventStartDateOnly = new Date ( eventStartDate . getFullYear ( ) , eventStartDate . getMonth ( ) , eventStartDate . getDate ( ) ) ;
149+ const eventEndDateOnly = eventEndDate ? new Date ( eventEndDate . getFullYear ( ) , eventEndDate . getMonth ( ) , eventEndDate . getDate ( ) ) : eventStartDateOnly ;
115150 const todayOnly = new Date ( today . getFullYear ( ) , today . getMonth ( ) , today . getDate ( ) ) ;
116151 const tomorrowOnly = new Date ( tomorrow . getFullYear ( ) , tomorrow . getMonth ( ) , tomorrow . getDate ( ) ) ;
117152 const endOfWeekOnly = new Date ( endOfWeek . getFullYear ( ) , endOfWeek . getMonth ( ) , endOfWeek . getDate ( ) ) ;
118153 const endOfMonthOnly = new Date ( endOfMonth . getFullYear ( ) , endOfMonth . getMonth ( ) , endOfMonth . getDate ( ) ) ;
119154
120- if ( eventDateOnly . getTime ( ) === todayOnly . getTime ( ) ) {
155+ // Check if today falls within the event's date range (for multi-day events)
156+ const todayTime = todayOnly . getTime ( ) ;
157+ const isHappeningToday = todayTime >= eventStartDateOnly . getTime ( ) && todayTime <= eventEndDateOnly . getTime ( ) ;
158+ const isHappeningTomorrow = tomorrowOnly . getTime ( ) >= eventStartDateOnly . getTime ( ) && tomorrowOnly . getTime ( ) <= eventEndDateOnly . getTime ( ) ;
159+
160+ if ( isHappeningToday ) {
121161 return 'today' ;
122- } else if ( eventDateOnly . getTime ( ) === tomorrowOnly . getTime ( ) ) {
162+ } else if ( isHappeningTomorrow || eventStartDateOnly . getTime ( ) === tomorrowOnly . getTime ( ) ) {
123163 return 'tomorrow' ;
124- } else if ( eventDateOnly . getTime ( ) < todayOnly . getTime ( ) ) {
164+ } else if ( eventEndDateOnly . getTime ( ) < todayOnly . getTime ( ) ) {
165+ // Event has completely ended
125166 return 'past' ;
126- } else if ( eventDateOnly . getTime ( ) <= endOfWeekOnly . getTime ( ) ) {
167+ } else if ( eventStartDateOnly . getTime ( ) <= endOfWeekOnly . getTime ( ) ) {
127168 return 'later this week' ;
128- } else if ( eventDateOnly . getTime ( ) <= endOfMonthOnly . getTime ( ) ) {
169+ } else if ( eventStartDateOnly . getTime ( ) <= endOfMonthOnly . getTime ( ) ) {
129170 return 'later this month' ;
130171 } else {
131172 return 'later' ;
0 commit comments