@@ -73,6 +73,7 @@ const TimeBlockContext = createContext({
73
73
prev : 'login' | 'account-switcher' | undefined
74
74
) => 'login' | 'account-switcher' | undefined )
75
75
) => { } ,
76
+ syncTimeBlocks : ( ) => Promise . resolve ( ) ,
76
77
} ) ;
77
78
78
79
const TimeBlockingProvider = ( {
@@ -272,16 +273,29 @@ const TimeBlockingProvider = ({
272
273
} ) ;
273
274
} , [ plan . id , editing ] ) ;
274
275
275
- useEffect ( ( ) => {
276
+ // --- Move syncTimeBlocks outside useEffect and expose it via context ---
277
+ const syncTimeBlocks = useCallback ( async ( ) => {
278
+ if ( ! plan . id || ! user ?. id ) return ;
279
+
280
+ const fetchCurrentTimeBlocks = async ( planId : string ) => {
281
+ const res = await fetch ( `/api/meet-together/plans/${ planId } /timeblocks` ) ;
282
+ if ( ! res . ok ) return [ ] ;
283
+ const timeblocks = ( await res . json ( ) ) as Timeblock [ ] ;
284
+ return timeblocks
285
+ ?. flat ( )
286
+ . filter (
287
+ ( tb : Timeblock ) =>
288
+ tb . user_id === user ?. id && tb . is_guest === ( user ?. is_guest ?? false )
289
+ ) ;
290
+ } ;
291
+
276
292
const addTimeBlock = async ( timeblock : Timeblock ) => {
277
293
if ( plan . id !== selectedTimeBlocks . planId ) return ;
278
-
279
294
const data = {
280
295
user_id : user ?. id ,
281
296
password_hash : user ?. password_hash ,
282
297
timeblock,
283
298
} ;
284
-
285
299
await fetch ( `/api/meet-together/plans/${ plan . id } /timeblocks` , {
286
300
method : 'POST' ,
287
301
body : JSON . stringify ( data ) ,
@@ -290,12 +304,10 @@ const TimeBlockingProvider = ({
290
304
291
305
const removeTimeBlock = async ( timeblock : Timeblock ) => {
292
306
if ( plan . id !== selectedTimeBlocks . planId ) return ;
293
-
294
307
const data = {
295
308
user_id : user ?. id ,
296
309
password_hash : user ?. password_hash ,
297
310
} ;
298
-
299
311
await fetch (
300
312
`/api/meet-together/plans/${ plan . id } /timeblocks/${ timeblock . id } ` ,
301
313
{
@@ -305,115 +317,80 @@ const TimeBlockingProvider = ({
305
317
) ;
306
318
} ;
307
319
308
- const fetchCurrentTimeBlocks = async ( planId : string ) => {
309
- const res = await fetch ( `/api/meet-together/plans/${ planId } /timeblocks` ) ;
310
- if ( ! res . ok ) return [ ] ;
311
-
312
- const timeblocks = ( await res . json ( ) ) as Timeblock [ ] ;
313
- return timeblocks
314
- ?. flat ( )
315
- . filter (
316
- ( tb : Timeblock ) =>
317
- tb . user_id === user ?. id && tb . is_guest === ( user ?. is_guest ?? false )
318
- ) ;
319
- } ;
320
-
321
- const syncTimeBlocks = async ( ) => {
322
- if ( ! plan . id || ! user ?. id ) return ;
323
-
324
- const serverTimeblocks = await fetchCurrentTimeBlocks ( plan ?. id ) ;
325
- const localTimeblocks = selectedTimeBlocks . data ;
326
-
327
- if ( ! serverTimeblocks || ! localTimeblocks ) return ;
328
- if ( serverTimeblocks . length === 0 && localTimeblocks . length === 0 ) return ;
329
-
330
- // If server timeblocks are empty and local timeblocks are not,
331
- // add all local timeblocks to server
332
- if ( serverTimeblocks . length === 0 && localTimeblocks . length > 0 ) {
333
- await Promise . all (
334
- localTimeblocks . map ( ( timeblock ) => addTimeBlock ( timeblock ) )
335
- ) ;
336
- return ;
337
- }
338
-
339
- // If local timeblocks are empty, remove all server timeblocks
340
- if ( serverTimeblocks . length > 0 && localTimeblocks . length === 0 ) {
341
- await Promise . all (
342
- serverTimeblocks . map ( ( timeblock ) => removeTimeBlock ( timeblock ) )
343
- ) ;
344
- return ;
345
- }
346
-
347
- // If there are no timeblocks to sync (both local and server have
348
- // the same timeblocks), return early
349
- if (
350
- serverTimeblocks . every ( ( serverTimeblock : Timeblock ) =>
351
- localTimeblocks . some (
352
- ( localTimeblock : Timeblock ) =>
353
- localTimeblock . date === serverTimeblock . date &&
354
- localTimeblock . start_time === serverTimeblock . start_time &&
355
- localTimeblock . end_time === serverTimeblock . end_time
356
- )
357
- ) &&
358
- localTimeblocks . every ( ( localTimeblock : Timeblock ) =>
359
- serverTimeblocks . some (
360
- ( serverTimeblock : Timeblock ) =>
361
- serverTimeblock . date === localTimeblock . date &&
362
- serverTimeblock . start_time === localTimeblock . start_time &&
363
- serverTimeblock . end_time === localTimeblock . end_time
364
- )
365
- ) &&
366
- serverTimeblocks . length === localTimeblocks . length
367
- )
368
- return ;
369
-
370
- // For each time block, remove timeblocks that are not on local
371
- // and add timeblocks that are not on server
372
- const timeblocksToRemove = serverTimeblocks . filter (
373
- ( serverTimeblock : Timeblock ) =>
374
- ! localTimeblocks . some (
375
- ( localTimeblock : Timeblock ) =>
376
- localTimeblock . date === serverTimeblock . date &&
377
- localTimeblock . start_time === serverTimeblock . start_time &&
378
- localTimeblock . end_time === serverTimeblock . end_time
379
- )
320
+ const serverTimeblocks = await fetchCurrentTimeBlocks ( plan ?. id ) ;
321
+ const localTimeblocks = selectedTimeBlocks . data ;
322
+ if ( ! serverTimeblocks || ! localTimeblocks ) return ;
323
+ if ( serverTimeblocks . length === 0 && localTimeblocks . length === 0 ) return ;
324
+ if ( serverTimeblocks . length === 0 && localTimeblocks . length > 0 ) {
325
+ await Promise . all (
326
+ localTimeblocks . map ( ( timeblock ) => addTimeBlock ( timeblock ) )
380
327
) ;
381
-
382
- const timeblocksToAdd = localTimeblocks . filter (
383
- ( localTimeblock : Timeblock ) =>
384
- ! serverTimeblocks ?. some (
385
- ( serverTimeblock : Timeblock ) =>
386
- serverTimeblock . date === localTimeblock . date &&
387
- serverTimeblock . start_time === localTimeblock . start_time &&
388
- serverTimeblock . end_time === localTimeblock . end_time
389
- )
328
+ return ;
329
+ }
330
+ if ( serverTimeblocks . length > 0 && localTimeblocks . length === 0 ) {
331
+ await Promise . all (
332
+ serverTimeblocks . map ( ( timeblock ) => removeTimeBlock ( timeblock ) )
390
333
) ;
334
+ return ;
335
+ }
336
+ if (
337
+ serverTimeblocks . every ( ( serverTimeblock : Timeblock ) =>
338
+ localTimeblocks . some (
339
+ ( localTimeblock : Timeblock ) =>
340
+ localTimeblock . date === serverTimeblock . date &&
341
+ localTimeblock . start_time === serverTimeblock . start_time &&
342
+ localTimeblock . end_time === serverTimeblock . end_time
343
+ )
344
+ ) &&
345
+ localTimeblocks . every ( ( localTimeblock : Timeblock ) =>
346
+ serverTimeblocks . some (
347
+ ( serverTimeblock : Timeblock ) =>
348
+ serverTimeblock . date === localTimeblock . date &&
349
+ serverTimeblock . start_time === localTimeblock . start_time &&
350
+ serverTimeblock . end_time === localTimeblock . end_time
351
+ )
352
+ ) &&
353
+ serverTimeblocks . length === localTimeblocks . length
354
+ )
355
+ return ;
356
+ const timeblocksToRemove = serverTimeblocks . filter (
357
+ ( serverTimeblock : Timeblock ) =>
358
+ ! localTimeblocks . some (
359
+ ( localTimeblock : Timeblock ) =>
360
+ localTimeblock . date === serverTimeblock . date &&
361
+ localTimeblock . start_time === serverTimeblock . start_time &&
362
+ localTimeblock . end_time === serverTimeblock . end_time
363
+ )
364
+ ) ;
365
+ const timeblocksToAdd = localTimeblocks . filter (
366
+ ( localTimeblock : Timeblock ) =>
367
+ ! serverTimeblocks ?. some (
368
+ ( serverTimeblock : Timeblock ) =>
369
+ serverTimeblock . date === localTimeblock . date &&
370
+ serverTimeblock . start_time === localTimeblock . start_time &&
371
+ serverTimeblock . end_time === localTimeblock . end_time
372
+ )
373
+ ) ;
374
+ if ( timeblocksToRemove . length === 0 && timeblocksToAdd . length === 0 ) return ;
375
+ if ( timeblocksToRemove . length > 0 )
376
+ await Promise . all (
377
+ timeblocksToRemove . map ( ( timeblock ) =>
378
+ timeblock . id ? removeTimeBlock ( timeblock ) : null
379
+ )
380
+ ) ;
381
+ if ( timeblocksToAdd . length > 0 )
382
+ await Promise . all (
383
+ timeblocksToAdd . map ( ( timeblock ) => addTimeBlock ( timeblock ) )
384
+ ) ;
385
+ const syncedServerTimeblocks = await fetchCurrentTimeBlocks ( plan ?. id ) ;
386
+ setSelectedTimeBlocks ( {
387
+ planId : plan . id ,
388
+ data : syncedServerTimeblocks ,
389
+ } ) ;
390
+ } , [ plan . id , user , selectedTimeBlocks ] ) ;
391
391
392
- if ( timeblocksToRemove . length === 0 && timeblocksToAdd . length === 0 )
393
- return ;
394
-
395
- if ( timeblocksToRemove . length > 0 )
396
- await Promise . all (
397
- timeblocksToRemove . map ( ( timeblock ) =>
398
- timeblock . id ? removeTimeBlock ( timeblock ) : null
399
- )
400
- ) ;
401
-
402
- if ( timeblocksToAdd . length > 0 )
403
- await Promise . all (
404
- timeblocksToAdd . map ( ( timeblock ) => addTimeBlock ( timeblock ) )
405
- ) ;
406
-
407
- const syncedServerTimeblocks = await fetchCurrentTimeBlocks ( plan ?. id ) ;
408
- setSelectedTimeBlocks ( {
409
- planId : plan . id ,
410
- data : syncedServerTimeblocks ,
411
- } ) ;
412
- } ;
413
-
414
- if ( editing . enabled ) return ;
415
- syncTimeBlocks ( ) ;
416
- } , [ plan . id , user , selectedTimeBlocks , editing . enabled ] ) ;
392
+ // --- Remove the auto-sync useEffect ---
393
+ // useEffect(() => { ... if (editing.enabled) return; syncTimeBlocks(); }, [plan.id, user, selectedTimeBlocks, editing.enabled]);
417
394
418
395
return (
419
396
< TimeBlockContext . Provider
@@ -436,6 +413,7 @@ const TimeBlockingProvider = ({
436
413
edit,
437
414
endEditing,
438
415
setDisplayMode,
416
+ syncTimeBlocks, // Expose syncTimeBlocks in context
439
417
} }
440
418
>
441
419
{ children }
0 commit comments