@@ -34,8 +34,8 @@ export interface Class {
3434 term : Term ;
3535 instructors : string [ ] ;
3636 location ?: string ;
37- startTime : string ;
38- endTime : string ;
37+ startTime : string | undefined ;
38+ endTime : string | undefined ;
3939 status : "open" | "closed" | "waitlist" ;
4040 waitlistNum ?: number ;
4141 isCorequisite : boolean ;
@@ -112,92 +112,101 @@ export function ScheduleCalendar({
112112 return < Skeleton className = "h-full w-full rounded-lg" /> ;
113113 }
114114
115- const transformedClasses : Class [ ] = classes . map ( ( c ) => {
116- const offering = c . courseOffering ;
117- const startTime = `${ offering . startTime . split ( ":" ) [ 0 ] } ${ offering . startTime . split ( ":" ) [ 1 ] } ` ;
118- const endTime = `${ offering . endTime . split ( ":" ) [ 0 ] } ${ offering . endTime . split ( ":" ) [ 1 ] } ` ;
115+ const transformedClasses : Class [ ] = classes
116+ . filter ( ( c ) => {
117+ const offering = c . courseOffering ;
118+ return offering . startTime && offering . endTime ;
119+ } )
120+ . map ( ( c ) => {
121+ const offering = c . courseOffering ;
122+ // biome-ignore lint/style/noNonNullAssertion: we just filtered above
123+ const startTime = `${ offering . startTime ! . split ( ":" ) [ 0 ] } ${ offering . startTime ! . split ( ":" ) [ 1 ] } ` ;
124+ // biome-ignore lint/style/noNonNullAssertion: we just filtered above
125+ const endTime = `${ offering . endTime ! . split ( ":" ) [ 0 ] } ${ offering . endTime ! . split ( ":" ) [ 1 ] } ` ;
119126
120- // Format times like "Monday 9 15 11 15"
121- const times = offering . days . map ( ( day ) => {
122- const dayName = day . charAt ( 0 ) . toUpperCase ( ) + day . slice ( 1 ) ;
123- return `${ dayName } ${ startTime } ${ endTime } ` ;
124- } ) ;
127+ // Format times like "Monday 9 15 11 15"
128+ const times = offering . days . map ( ( day ) => {
129+ const dayName = day . charAt ( 0 ) . toUpperCase ( ) + day . slice ( 1 ) ;
130+ return `${ dayName } ${ startTime } ${ endTime } ` ;
131+ } ) ;
125132
126- const color = getColor ( offering . _id ) ;
133+ const color = getColor ( offering . _id ) ;
127134
128- const slots : { start : Date ; end : Date } [ ] = [ ] ;
135+ const slots : { start : Date ; end : Date } [ ] = [ ] ;
129136
130- // Map weekday names to 0-6 offset from start of week (Sunday = 0)
131- const weekdayMap : Record < string , number > = {
132- Sunday : 0 ,
133- Monday : 1 ,
134- Tuesday : 2 ,
135- Wednesday : 3 ,
136- Thursday : 4 ,
137- Friday : 5 ,
138- Saturday : 6 ,
139- } ;
137+ // Map weekday names to 0-6 offset from start of week (Sunday = 0)
138+ const weekdayMap : Record < string , number > = {
139+ Sunday : 0 ,
140+ Monday : 1 ,
141+ Tuesday : 2 ,
142+ Wednesday : 3 ,
143+ Thursday : 4 ,
144+ Friday : 5 ,
145+ Saturday : 6 ,
146+ } ;
140147
141- // Get the start of the current week (Sunday)
142- const startOfCurrentWeek = startOfWeek ( new Date ( ) , { weekStartsOn : 0 } ) ; // Sunday = 0
148+ // Get the start of the current week (Sunday)
149+ const startOfCurrentWeek = startOfWeek ( new Date ( ) , { weekStartsOn : 0 } ) ; // Sunday = 0
143150
144- for ( const slot of times ) {
145- const parts = slot . split ( " " ) ;
146- const day = parts [ 0 ] ;
147- const startHour = Number ( parts [ 1 ] ) ;
148- const startMinute = Number ( parts [ 2 ] ) ;
149- const endHour = Number ( parts [ 3 ] ) ;
150- const endMinute = Number ( parts [ 4 ] ) ;
151+ for ( const slot of times ) {
152+ const parts = slot . split ( " " ) ;
153+ const day = parts [ 0 ] ;
154+ const startHour = Number ( parts [ 1 ] ) ;
155+ const startMinute = Number ( parts [ 2 ] ) ;
156+ const endHour = Number ( parts [ 3 ] ) ;
157+ const endMinute = Number ( parts [ 4 ] ) ;
151158
152- const dayOffset = weekdayMap [ day ] ;
153- if ( dayOffset === undefined ) {
154- throw new Error ( `Invalid day: ${ day } ` ) ;
155- }
159+ const dayOffset = weekdayMap [ day ] ;
160+ if ( dayOffset === undefined ) {
161+ throw new Error ( `Invalid day: ${ day } ` ) ;
162+ }
156163
157- const date = addDays ( startOfCurrentWeek , dayOffset ) ;
164+ const date = addDays ( startOfCurrentWeek , dayOffset ) ;
158165
159- const start = new Date ( date ) ;
160- start . setHours ( startHour , startMinute , 0 , 0 ) ;
166+ const start = new Date ( date ) ;
167+ start . setHours ( startHour , startMinute , 0 , 0 ) ;
161168
162- const end = new Date ( date ) ;
163- end . setHours ( endHour , endMinute , 0 , 0 ) ;
169+ const end = new Date ( date ) ;
170+ end . setHours ( endHour , endMinute , 0 , 0 ) ;
164171
165- slots . push ( { start, end } ) ;
166- }
172+ slots . push ( { start, end } ) ;
173+ }
167174
168- return {
169- id : offering . _id ,
170- userCourseOfferingId : c . _id ,
171- classNumber : c . classNumber ,
172- courseCode : offering . courseCode ,
173- title : `${ offering . courseCode } - ${ offering . title } ` ,
174- color,
175- times : slots ,
176- description : `${ offering . instructors . join ( ", " ) } • ${ offering . section . toUpperCase ( ) } • ${ offering . term } ${ offering . year } ` ,
177- section : offering . section ,
178- year : offering . year ,
179- term : offering . term ,
180- instructors : offering . instructors ,
181- location : offering . location ,
182- startTime : offering . startTime ,
183- endTime : offering . endTime ,
184- status : offering . status ,
185- waitlistNum : offering . waitlistNum ,
186- isCorequisite : offering . isCorequisite ,
187- corequisiteOf : offering . corequisiteOf ,
188- } ;
189- } ) ;
175+ return {
176+ id : offering . _id ,
177+ userCourseOfferingId : c . _id ,
178+ classNumber : c . classNumber ,
179+ courseCode : offering . courseCode ,
180+ title : `${ offering . courseCode } - ${ offering . title } ` ,
181+ color,
182+ times : slots ,
183+ description : `${ offering . instructors . join ( ", " ) } • ${ offering . section . toUpperCase ( ) } • ${ offering . term } ${ offering . year } ` ,
184+ section : offering . section ,
185+ year : offering . year ,
186+ term : offering . term ,
187+ instructors : offering . instructors ,
188+ location : offering . location ,
189+ startTime : offering . startTime ,
190+ endTime : offering . endTime ,
191+ status : offering . status ,
192+ waitlistNum : offering . waitlistNum ,
193+ isCorequisite : offering . isCorequisite ,
194+ corequisiteOf : offering . corequisiteOf ,
195+ } ;
196+ } ) ;
190197
191198 // Add hovered course preview
192- if ( hoveredCourse ) {
199+ if ( hoveredCourse ?. startTime && hoveredCourse . endTime ) {
193200 const isAlreadyAdded = classes . some (
194201 ( c ) => c . courseOffering . _id === hoveredCourse . _id ,
195202 ) ;
196203
197204 if ( ! isAlreadyAdded ) {
198205 const offering = hoveredCourse ;
199- const startTime = `${ offering . startTime . split ( ":" ) [ 0 ] } ${ offering . startTime . split ( ":" ) [ 1 ] } ` ;
200- const endTime = `${ offering . endTime . split ( ":" ) [ 0 ] } ${ offering . endTime . split ( ":" ) [ 1 ] } ` ;
206+ // biome-ignore lint/style/noNonNullAssertion: we just filtered above
207+ const startTime = `${ offering . startTime ! . split ( ":" ) [ 0 ] } ${ offering . startTime ! . split ( ":" ) [ 1 ] } ` ;
208+ // biome-ignore lint/style/noNonNullAssertion: we just filtered above
209+ const endTime = `${ offering . endTime ! . split ( ":" ) [ 0 ] } ${ offering . endTime ! . split ( ":" ) [ 1 ] } ` ;
201210
202211 const times = offering . days . map ( ( day ) => {
203212 const dayName = day . charAt ( 0 ) . toUpperCase ( ) + day . slice ( 1 ) ;
@@ -248,8 +257,8 @@ export function ScheduleCalendar({
248257 term : offering . term ,
249258 instructors : offering . instructors ,
250259 location : offering . location ,
251- startTime : offering . startTime ,
252- endTime : offering . endTime ,
260+ startTime : offering . startTime as string ,
261+ endTime : offering . endTime as string ,
253262 status : offering . status ,
254263 waitlistNum : offering . waitlistNum ,
255264 isCorequisite : offering . isCorequisite ,
0 commit comments