@@ -14,6 +14,105 @@ interface TextItemProps {
1414 onChange ?: ( value : string ) => void ;
1515}
1616
17+
18+
19+ function getFirstAndLastEventDatetime ( selectedSessionEvents : SessionEvent [ ] ) {
20+ const eventStartTimes = selectedSessionEvents . map ( event => new Date ( event . startDatetime ) ) ;
21+ const eventEndTimes = selectedSessionEvents . map ( event => new Date ( event . endDatetime || new Date ( ) . toISOString ( ) ) ) ;
22+ const firstEventStart = new Date ( Math . min ( ...eventStartTimes . map ( date => date . getTime ( ) ) ) ) ;
23+ const lastEventEnd = new Date ( Math . max ( ...eventEndTimes . map ( date => date . getTime ( ) ) ) ) ;
24+ return { firstEventStart, lastEventEnd } ;
25+ }
26+
27+
28+ function doesOverlapExist ( candidateStart : Date , candidateEnd : Date , firstEventStart : Date , lastEventEnd : Date ) {
29+ if ( candidateStart > lastEventEnd || candidateEnd < firstEventStart ) {
30+ return false ;
31+ }
32+ return true ;
33+ }
34+
35+ function timeStringToDate ( timeStringStart : string , timeStringEnd : string , selectedSessionEvents : SessionEvent [ ] ) : [ Date | null , Date | null ] {
36+ const convertLocalHourToUTC = ( localHour : number ) : number => {
37+ const localDate = new Date ( ) ;
38+ localDate . setHours ( localHour ) ;
39+ const utcHour = localDate . getUTCHours ( ) ;
40+ console . log ( "Local hour" , localHour , "UTC hour" , utcHour ) ;
41+ return utcHour ;
42+ } ;
43+ const { firstEventStart, lastEventEnd } = getFirstAndLastEventDatetime ( selectedSessionEvents ) ;
44+ let [ hoursStart , minutesStart ] = timeStringStart . split ( ':' ) . map ( Number ) ;
45+ let [ hoursEnd , minutesEnd ] = timeStringEnd . split ( ':' ) . map ( Number ) ;
46+ hoursStart = convertLocalHourToUTC ( hoursStart ) ;
47+ hoursEnd = convertLocalHourToUTC ( hoursEnd ) ;
48+ console . log ( "Time string start" , timeStringStart , "UTC hour:" , hoursStart ) ;
49+ console . log ( "Time string end" , timeStringEnd , "UTC hour:" , hoursEnd ) ;
50+
51+ console . log ( "First event start" , firstEventStart . toISOString ( ) ) ;
52+ console . log ( "Last event end" , lastEventEnd . toISOString ( ) ) ;
53+
54+ if ( hoursStart > hoursEnd ) {
55+ console . log ( "Different days" ) ;
56+ let startDate = new Date ( firstEventStart ) ;
57+ let endDate = new Date ( firstEventStart ) ;
58+ endDate . setUTCDate ( endDate . getUTCDate ( ) + 1 ) ; // Set endDate to be 1 day after startDate
59+ startDate . setUTCHours ( hoursStart , minutesStart , 0 , 0 ) ;
60+ endDate . setUTCHours ( hoursEnd , minutesEnd , 0 , 0 ) ;
61+ console . log ( "Start date" , startDate . toISOString ( ) ) ;
62+ console . log ( "End date" , endDate . toISOString ( ) ) ;
63+ const overlapExists = doesOverlapExist ( startDate , endDate , firstEventStart , lastEventEnd ) ;
64+ if ( overlapExists ) {
65+ return [ startDate , endDate ] ;
66+ }
67+ else {
68+ return [ null , null ] ;
69+ }
70+ } else if ( firstEventStart . getUTCDate ( ) === lastEventEnd . getUTCDate ( ) ) {
71+ console . log ( "Same day" ) ;
72+ let startDate = new Date ( firstEventStart ) ;
73+ let endDate = new Date ( firstEventStart ) ;
74+ startDate . setUTCHours ( hoursStart , minutesStart , 0 , 0 ) ;
75+ endDate . setUTCHours ( hoursEnd , minutesEnd , 0 , 0 ) ;
76+ const overlapExists = doesOverlapExist ( startDate , endDate , firstEventStart , lastEventEnd ) ;
77+ if ( overlapExists ) {
78+ return [ startDate , endDate ] ;
79+ }
80+ else {
81+ return [ null , null ] ;
82+ }
83+ } else {
84+ console . log ( "Same day" ) ;
85+ let startDateA = new Date ( firstEventStart ) ;
86+ let endDateA = new Date ( firstEventStart ) ;
87+ startDateA . setUTCHours ( hoursStart , minutesStart , 0 , 0 ) ;
88+ endDateA . setUTCHours ( hoursEnd , minutesEnd , 0 , 0 ) ;
89+ const optionAWorks = doesOverlapExist ( startDateA , endDateA , firstEventStart , lastEventEnd ) ;
90+ console . log ( "Start date A" , startDateA . toISOString ( ) ) ;
91+ console . log ( "End date A" , endDateA . toISOString ( ) ) ;
92+ console . log ( "Option A works" , optionAWorks ) ;
93+
94+ let startDateB = new Date ( lastEventEnd ) ;
95+ let endDateB = new Date ( lastEventEnd ) ;
96+ startDateB . setUTCHours ( hoursStart , minutesStart , 0 , 0 ) ;
97+ endDateB . setUTCHours ( hoursEnd , minutesEnd , 0 , 0 ) ;
98+ const optionBWorks = doesOverlapExist ( startDateB , endDateB , firstEventStart , lastEventEnd ) ;
99+
100+ console . log ( "Start date B" , startDateB . toISOString ( ) ) ;
101+ console . log ( "End date B" , endDateB . toISOString ( ) ) ;
102+ console . log ( "Option B works" , optionBWorks ) ;
103+
104+ if ( optionAWorks && ! optionBWorks ) {
105+ return [ startDateA , endDateA ] ;
106+ }
107+ else if ( ! optionAWorks && optionBWorks ) {
108+ return [ startDateB , endDateB ] ;
109+ }
110+ else {
111+ return [ null , null ] ;
112+ }
113+ }
114+ }
115+
17116const TextItem : React . FC < TextItemProps > = ( { content, isInput, onChange } ) => {
18117 const handleKeyDown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
19118 const allowedKeys = [ 'Backspace' , 'Tab' , 'ArrowLeft' , 'ArrowRight' , 'Delete' ] ;
@@ -131,67 +230,39 @@ const EditModal: React.FC<EditModalProps> = ({ sessionId, sessionStart, sessionN
131230
132231 useEffect ( ( ) => {
133232 const checkButtonActive = ( ) => {
134- console . log ( "Selected time box ID" , selectedTimeBoxId ) ;
135- console . log ( "From time" , fromTime ) ;
136- console . log ( "To time" , toTime ) ;
137- console . log ( "Selected session events" , selectedSessionEvents ) ;
138- console . log ( "Time boxes" , timeBoxes ) ;
139- console . log ( "Session start" , sessionStart ) ;
140- console . log ( "Session ID" , sessionId ) ;
141- console . log ( "Session number" , sessionNumber ) ;
142-
143-
144- if ( selectedTimeBoxId === '' ) {
145- console . log ( "Selected time box ID is empty" ) ;
233+ if ( ! selectedTimeBoxId ) {
234+ setWarningMessage ( 'Please select a time box to reassign time frame too.' ) ;
146235 setIsButtonActiveState ( false ) ;
147236 return ;
148237 }
149-
238+
150239 // Check if both fromTime and toTime are complete
151240 if ( ! fromTime || ! toTime || fromTime . length < 4 || toTime . length < 4 ) {
152241 console . log ( "From-time to-time not long enough." ) ;
153242 setIsButtonActiveState ( false ) ;
154243 // setWarningMessage('');
155244 return ;
156245 }
246+ const isValidTimeFormat = ( time : string ) : boolean => {
247+ const timePattern = / ^ ( [ 0 1 ] \d | 2 [ 0 - 3 ] ) : ( [ 0 - 5 ] \d ) $ / ;
248+ return timePattern . test ( time ) ;
249+ } ;
157250
158- const eventStartTimes = selectedSessionEvents . map ( event => new Date ( event . startDatetime ) ) ;
159- const eventEndTimes = selectedSessionEvents . map ( event => new Date ( event . endDatetime || new Date ( ) . toISOString ( ) ) ) ;
160- const firstEventStart = new Date ( Math . min ( ...eventStartTimes . map ( date => date . getTime ( ) ) ) ) ;
161- const lastEventEnd = new Date ( Math . max ( ...eventEndTimes . map ( date => date . getTime ( ) ) ) ) ;
162-
163- const [ startHours , startMinutes ] = fromTime . split ( ':' ) . map ( Number ) ;
164- const [ endHours , endMinutes ] = toTime . split ( ':' ) . map ( Number ) ;
165-
166- const enteredStartTime = new Date ( firstEventStart ) ;
167- enteredStartTime . setHours ( startHours , startMinutes , 0 , 0 ) ;
168-
169- const enteredEndTime = new Date ( firstEventStart ) ;
170- enteredEndTime . setHours ( endHours , endMinutes , 0 , 0 ) ;
171-
172- if ( enteredEndTime <= enteredStartTime ) {
173- setWarningMessage ( 'End time must be later than start time.' ) ;
251+ if ( ! isValidTimeFormat ( fromTime ) || ! isValidTimeFormat ( toTime ) ) {
252+ setWarningMessage ( 'Invalid time format. Please use HH:MM format.' ) ;
174253 setIsButtonActiveState ( false ) ;
175254 return ;
176255 }
256+ const [ enteredStartTime , enteredEndTime ] = timeStringToDate ( fromTime , toTime , selectedSessionEvents ) ;
177257
178- if ( enteredEndTime < firstEventStart ) {
179- setWarningMessage ( 'New end time cannot be earlier than the start of first event .' ) ;
258+ if ( enteredStartTime === null || enteredEndTime === null ) {
259+ setWarningMessage ( 'Invalid time range. New time must overlap .' ) ;
180260 setIsButtonActiveState ( false ) ;
181261 return ;
262+ } else {
263+ setWarningMessage ( '' ) ;
264+ setIsButtonActiveState ( true ) ;
182265 }
183-
184- console . log ( "Last event end" , lastEventEnd . toISOString ( ) ) ;
185- console . log ( "Entered start time" , enteredStartTime . toISOString ( ) ) ;
186-
187- if ( enteredStartTime > lastEventEnd ) {
188- setWarningMessage ( 'Start time cannot be later than the end of the last event.' ) ;
189- setIsButtonActiveState ( false ) ;
190- return ;
191- }
192-
193- setWarningMessage ( '' ) ;
194- setIsButtonActiveState ( true ) ;
195266 } ;
196267
197268 checkButtonActive ( ) ;
@@ -216,14 +287,11 @@ const EditModal: React.FC<EditModalProps> = ({ sessionId, sessionStart, sessionN
216287 let eventsToUpdate : SessionEvent [ ] = [ ] ;
217288 let newEvents : SessionEvent [ ] = [ ] ;
218289
219- const startDatetime = new Date ( selectedSessionEvents [ 0 ] . startDatetime ) ;
220- const endDatetime = new Date ( selectedSessionEvents [ 0 ] . startDatetime ) ;
221-
222- const [ startHours , startMinutes ] = fromTime . split ( ':' ) . map ( Number ) ;
223- const [ endHours , endMinutes ] = toTime . split ( ':' ) . map ( Number ) ;
224-
225- startDatetime . setHours ( startHours , startMinutes , 0 , 0 ) ;
226- endDatetime . setHours ( endHours , endMinutes , 0 , 0 ) ;
290+ const [ startDatetime , endDatetime ] = timeStringToDate ( fromTime , toTime , selectedSessionEvents ) ;
291+ if ( ! startDatetime || ! endDatetime ) {
292+ console . error ( "Start and end datetime cannot be null." ) ;
293+ return ;
294+ }
227295
228296 selectedSessionEvents . forEach ( event => {
229297 const eventStartDatetime = new Date ( event . startDatetime ) ;
@@ -296,9 +364,9 @@ const EditModal: React.FC<EditModalProps> = ({ sessionId, sessionStart, sessionN
296364 } ) ;
297365
298366 // log to check if everythingis correct
299- console . log ( "Events to update" , eventsToUpdate ) ;
300- console . log ( "Events to delete" , eventIdsToDelete ) ;
301- console . log ( "New events" , newEvents ) ;
367+ // console.log("Events to update", eventsToUpdate);
368+ // console.log("Events to delete", eventIdsToDelete);
369+ // console.log("New events", newEvents);
302370
303371 let transaction ;
304372 try {
0 commit comments