@@ -100,7 +100,7 @@ const Animation: React.FC<{
100100 opacity : 0 ,
101101 height : 0 ,
102102 } }
103- className = "overflow-hidden"
103+ className = "flex flex-col overflow-hidden"
104104 >
105105 { children }
106106 </ motion . div >
@@ -294,12 +294,18 @@ export const ManageLessonDialog: React.FC<{
294294 } , [ selectDaySlots , date , bookedSlots ] ) ;
295295
296296 const daySlots = useMemo (
297- ( ) => allSlots . filter ( ( slot ) => dayjs ( slot . start ) . hour ( ) <= 12 ) ,
297+ ( ) =>
298+ allSlots . filter (
299+ ( slot ) => dayjs ( slot . start ) . hour ( ) <= 12 && dayjs ( ) . isBefore ( slot . start )
300+ ) ,
298301 [ allSlots ]
299302 ) ;
300303
301304 const nightSlots = useMemo (
302- ( ) => allSlots . filter ( ( slot ) => dayjs ( slot . start ) . hour ( ) > 12 ) ,
305+ ( ) =>
306+ allSlots . filter (
307+ ( slot ) => dayjs ( slot . start ) . hour ( ) > 12 && dayjs ( ) . isBefore ( slot . start )
308+ ) ,
303309 [ allSlots ]
304310 ) ;
305311
@@ -346,123 +352,126 @@ export const ManageLessonDialog: React.FC<{
346352 </ div >
347353 }
348354 className = { cn (
349- "!w-auto max-w-[350px] md:max-w-[550px] mx-auto py-4 lg:!py-6 _sm:w-[512px] [&>div:first-child]:!px-4 sm:[&>div:first-child]:!px-0" ,
355+ "flex flex-col !w-auto max-w-[350px] md:max-w-[550px] mx-auto py-4 lg:!py-6 _sm:w-[512px] [&>div:first-child]:!px-4 sm:[&>div:first-child]:!px-0" ,
350356 {
351357 "!left-0 right-0 translate-x-0" : ! sm ,
352358 }
353359 ) }
354360 >
355- < div className = "mt-4" >
356- < AnimatePresence initial = { false } mode = "wait" >
357- { loading ? (
358- < Animation key = "loading" id = "loading" >
359- < LoadingWrapper tutorName = { name } />
360- </ Animation >
361- ) : null }
362-
363- { error && ! loading ? (
364- < Animation key = "error" id = "error" >
365- < Error retry = { retry } tutorName = { name } />
366- </ Animation >
367- ) : null }
368-
369- { depletedSubscription && ! error && ! loading ? (
370- < Animation key = "depleted-subscription" id = "depleted-subscription" >
371- < DepletedSubscription />
372- </ Animation >
373- ) : null }
374-
375- { /* TODO: substitute this with subscription promotion */ }
376- { hasBookedMaxLessons &&
377- ! subscribed &&
378- ! depletedSubscription &&
379- ! error &&
380- ! loading &&
381- type === "book" ? (
382- < Animation key = "has-booked-lesson" id = "has-booked-lesson" >
383- < Block close = { close } type = "has-booked" />
384- </ Animation >
385- ) : null }
386-
387- { canBook ? (
388- < Animation key = "date-selection" id = "selection" >
389- < div className = "flex flex-col gap-6 !max-w-[350px]" >
390- < div className = "flex flex-col gap-4" >
391- < div className = "flex flex-col gap-2" >
392- < LessonDuration />
393- < Divider />
394- </ div >
361+ < AnimatePresence initial = { false } mode = "wait" >
362+ { loading ? (
363+ < Animation key = "loading" id = "loading" >
364+ < LoadingWrapper tutorName = { name } />
365+ </ Animation >
366+ ) : null }
395367
396- < DateSelection
397- min = { dateBounds . start }
398- max = { dateBounds . start . add ( 1 , "week" ) }
399- selected = { date }
400- onSelect = { ( params ) => {
401- setDate ( params ) ;
402- setLessonDetails ( { start : null , slotId : null } ) ;
403- } }
404- isSelectable = { isValidDate }
405- prev = { ( ) => {
406- setLessonDetails ( { start : null , slotId : null } ) ;
407- setDateBounds ( ( prev ) => {
408- setDate ( prev . start . subtract ( 1 , "week" ) ) ;
409- return {
410- start : prev . start . subtract ( 1 , "week" ) ,
411- end : prev . end . subtract ( 1 , "week" ) ,
412- } ;
413- } ) ;
414- } }
415- next = { ( ) => {
416- setLessonDetails ( { start : null , slotId : null } ) ;
417- setDateBounds ( ( prev ) => {
418- setDate ( prev . start . add ( 1 , "week" ) ) ;
419- return {
420- start : prev . start . add ( 1 , "week" ) ,
421- end : prev . end . add ( 1 , "week" ) ,
422- } ;
423- } ) ;
424- } }
425- />
368+ { error && ! loading ? (
369+ < Animation key = "error" id = "error" >
370+ < Error retry = { retry } tutorName = { name } />
371+ </ Animation >
372+ ) : null }
426373
374+ { depletedSubscription && ! error && ! loading ? (
375+ < Animation key = "depleted-subscription" id = "depleted-subscription" >
376+ < DepletedSubscription />
377+ </ Animation >
378+ ) : null }
379+
380+ { /* TODO: substitute this with subscription promotion */ }
381+ { hasBookedMaxLessons &&
382+ ! subscribed &&
383+ ! depletedSubscription &&
384+ ! error &&
385+ ! loading &&
386+ type === "book" ? (
387+ < Animation key = "has-booked-lesson" id = "has-booked-lesson" >
388+ < Block close = { close } type = "has-booked" />
389+ </ Animation >
390+ ) : null }
391+
392+ { canBook ? (
393+ < Animation key = "date-selection" id = "selection" >
394+ < div className = "flex-1 flex flex-col gap-6 !max-w-[350px] overflow-hidden" >
395+ < div className = "flex flex-col gap-4 overflow-hidden" >
396+ < div className = "flex flex-col gap-2" >
397+ < LessonDuration />
427398 < Divider />
399+ </ div >
428400
429- < div className = "flex flex-col" >
430- < div
431- className = { cn (
432- "flex flex-col gap-4" ,
433- "max-h-[322px] overflow-y-scroll pe-2 [direction:ltr] scrollbar !scrollbar-thumb-natural-500 !scrollbar-track-natural-100"
434- ) }
435- >
436- < SlotsContainer
437- slots = { daySlots }
438- atNight = { false }
439- lessonDetails = { lessonDetails }
440- setLessonDetails = { ( start , slotId ) =>
441- setLessonDetails ( ( ) => ( { start, slotId } ) )
442- }
443- />
444- < SlotsContainer
445- slots = { nightSlots }
446- atNight = { true }
447- lessonDetails = { lessonDetails }
448- setLessonDetails = { ( start , slotId ) =>
449- setLessonDetails ( ( ) => ( { start, slotId } ) )
450- }
451- />
452- </ div >
453- < Typography
454- tag = "p"
455- className = "text-tiny text-natural-600 mt-2"
456- >
457- { intl ( "book-lesson.labels.time-zone" , {
458- value :
459- arabicTimezoneNames [
460- dayjs . tz . guess ( ) as keyof typeof arabicTimezoneNames
461- ] ,
462- } ) }
463- </ Typography >
401+ < DateSelection
402+ min = { dateBounds . start }
403+ max = { dateBounds . start . add ( 1 , "week" ) }
404+ selected = { date }
405+ onSelect = { ( params ) => {
406+ setDate ( params ) ;
407+ setLessonDetails ( { start : null , slotId : null } ) ;
408+ } }
409+ isSelectable = { isValidDate }
410+ prev = { ( ) => {
411+ setLessonDetails ( { start : null , slotId : null } ) ;
412+ setDateBounds ( ( prev ) => {
413+ setDate ( prev . start . subtract ( 1 , "week" ) ) ;
414+ return {
415+ start : prev . start . subtract ( 1 , "week" ) ,
416+ end : prev . end . subtract ( 1 , "week" ) ,
417+ } ;
418+ } ) ;
419+ } }
420+ next = { ( ) => {
421+ setLessonDetails ( { start : null , slotId : null } ) ;
422+ setDateBounds ( ( prev ) => {
423+ setDate ( prev . start . add ( 1 , "week" ) ) ;
424+ return {
425+ start : prev . start . add ( 1 , "week" ) ,
426+ end : prev . end . add ( 1 , "week" ) ,
427+ } ;
428+ } ) ;
429+ } }
430+ />
431+
432+ < Divider />
433+
434+ < div
435+ className = { cn (
436+ "flex flex-col" ,
437+ "[direction:ltr] scrollbar" ,
438+ "!scrollbar-thumb-natural-500 !scrollbar-track-natural-100" ,
439+ {
440+ "overflow-y-auto" :
441+ daySlots . length + nightSlots . length > 10 ,
442+ }
443+ ) }
444+ >
445+ < div className = "flex flex-col gap-4 max-h-[322px] pe-2" >
446+ < SlotsContainer
447+ slots = { daySlots }
448+ atNight = { false }
449+ lessonDetails = { lessonDetails }
450+ setLessonDetails = { ( start , slotId ) =>
451+ setLessonDetails ( ( ) => ( { start, slotId } ) )
452+ }
453+ />
454+ < SlotsContainer
455+ slots = { nightSlots }
456+ atNight = { true }
457+ lessonDetails = { lessonDetails }
458+ setLessonDetails = { ( start , slotId ) =>
459+ setLessonDetails ( ( ) => ( { start, slotId } ) )
460+ }
461+ />
464462 </ div >
465463 </ div >
464+ </ div >
465+
466+ < div className = "flex flex-col gap-1 w-full" >
467+ < Typography tag = "p" className = "text-tiny text-natural-600" >
468+ { intl ( "book-lesson.labels.time-zone" , {
469+ value :
470+ arabicTimezoneNames [
471+ dayjs . tz . guess ( ) as keyof typeof arabicTimezoneNames
472+ ] ,
473+ } ) }
474+ </ Typography >
466475 < Button
467476 size = "large"
468477 className = "w-full"
@@ -481,10 +490,10 @@ export const ManageLessonDialog: React.FC<{
481490 </ Typography >
482491 </ Button >
483492 </ div >
484- </ Animation >
485- ) : null }
486- </ AnimatePresence >
487- </ div >
493+ </ div >
494+ </ Animation >
495+ ) : null }
496+ </ AnimatePresence >
488497 </ Dialog >
489498 ) ;
490499} ;
@@ -497,11 +506,6 @@ const SlotsContainer: React.FC<{
497506} > = ( { slots, atNight, lessonDetails, setLessonDetails } ) => {
498507 const intl = useFormatMessage ( ) ;
499508
500- const filtered = useMemo (
501- ( ) => slots . filter ( ( s ) => dayjs ( ) . isBefore ( s . start ) ) ,
502- [ slots ]
503- ) ;
504-
505509 return (
506510 < div className = "[direction:rtl] flex flex-col gap-2" >
507511 < div className = "flex gap-1 items-center" >
@@ -517,7 +521,7 @@ const SlotsContainer: React.FC<{
517521 </ Typography >
518522 </ div >
519523 < div >
520- { isEmpty ( filtered ) ? (
524+ { isEmpty ( slots ) ? (
521525 < Typography
522526 tag = "p"
523527 className = "text-caption font-semibold text-center my-6"
@@ -527,7 +531,7 @@ const SlotsContainer: React.FC<{
527531 ) : null }
528532
529533 < div className = { cn ( { grid : ! isEmpty ( slots ) } , "grid-cols-3 gap-2" ) } >
530- { filtered . map ( ( slot , i ) => {
534+ { slots . map ( ( slot , i ) => {
531535 const isSelected =
532536 lessonDetails . slotId === slot . parent &&
533537 lessonDetails . start === slot . start ;
0 commit comments