0

I got an issue I can't seem to resolve, problem is as follows:
I got a custom hook which opens a modal whenever an event on calendar is clicked.
It also returns the state and setState so that I can manipulate that state from wherever.

const useEventModal = () => {
  const [selectedEvent, setSelectedEvent] = useState<ReactElement>()
  const [isOpen, setIsOpen] = useState<boolean>(false)

  const handleSelectEvent = (event: EventInterface, e) => {
    setIsOpen(!isOpen)
    const { innerWidth, innerHeight } = window

    const mouseEvent = e as React.MouseEvent<HTMLElement, EventInterface>

    const { positionX, positionY } = getModalCoordinates(
      innerHeight,
      innerWidth,
      mouseEvent
    )

    setSelectedEvent(
      <div
        className={styles.eventModalWrapper}
        style={{ left: positionX, top: positionY }}
      >
        <div className={styles.eventModalHeader}>
          <img
            alt="lecturer"
            className={styles.eventPhoto}
            src={event.mentorPic || 'https://picsum.photos/200'}
          />

          <CloseBtn
            className={styles.closeBtn}
            onClick={() => setIsOpen(false)}
          />
        </div>

        <div className={styles.eventInfoWrapper}>
          <div className={styles.eventTitleWrapper}>
            <h2 className={styles.eventTitle}>{event.title}</h2>

            <p className={styles.eventMentor}>{event.mentorName}</p>
          </div>

          <div className={styles.contentAndFooterWrapper}>
            <div className={styles.eventInfo}>
              <div className={styles.eventTimeWrapper}>
                <Watch />

                <p className={styles.eventText}>
                  {`Time: ${event.start?.getHours()} - ${event.end?.getHours()}`}
                </p>
              </div>

              <div className={styles.eventDurationWrapper}>
                <Timer />

                <p className={styles.eventText}>{`Duration: ${
                  Number(event.end?.getHours()) -
                  Number(event.start?.getHours())
                } Hours`}</p>
              </div>

              {event.type === 'lesson' && (
                <div className={styles.eventNameWrapper}>
                  <ArchiveBook />

                  <p
                    className={styles.eventText}
                  >{`Lesson ${event.lessonNumber}: ${event.title}`}</p>
                </div>
              )}
            </div>

            <div className={styles.modalFooter}>
              <div>
                <LiveButton />
              </div>

              <Vector />
            </div>
          </div>
        </div>
      </div>
    )
  }
  return { handleSelectEvent, isOpen, selectedEvent, setIsOpen }
}

export default useEventModal

now the issue is that when I call the setState action on page like so in useEffect it doesn't work

const CalendarToolbar: React.FC<props> = ({
  onNavigate,
  setActiveView,
  views,
  activeView,
  date,
}): React.ReactElement => {
  const { isOpen, setIsOpen } = useEventModal()
  console.log(isOpen)

  const [selectedDate, setSelectedDate] = useState<Date>(dayjs().toDate())
  const [isCalendarVisible, setIsCalendarVisible] = useState(false)
  const [coordinates, setCoordinates] = useState<number[]>([])

  const selectDateRef = useRef<HTMLDivElement>(null)

  const onSelectSlot = (slotInfo: SlotInfo) => {
    setSelectedDate(slotInfo.start)
  }

  const handleNavigate = (nav: NavigateAction) => {
    onNavigate(nav)
    setIsCalendarVisible(false)
  }

  useEffect(() => {
    onNavigate('DATE', selectedDate, Views.DAY)
    setIsCalendarVisible(false)
    setIsOpen(false)
  }, [selectedDate, isOpen])

  return (
    <div className={styles.toolbarWrapper}>
      <div className={styles.dateViewsWrapper}>
        <div className={styles.calendarViews}>
          {views.map((item) => (
            <button
              key={item}
              className={
                // eslint-disable-next-line no-nested-ternary
                !activeView && item === 'week'
                  ? `${styles.view} ${styles.active}`
                  : activeView?.toLowerCase() === item
                  ? `${styles.view} ${styles.active}`
                  : styles.view
              }
              onClick={() => {
                setActiveView(item)
              }}
              type="button"
            >
              {camelCaseToTitleCase(item)}
            </button>
          ))}
        </div>
      </div>

      <div className={styles.navigationWrapper}>
        <div
          ref={selectDateRef}
          className={styles.daysDropdown}
          onClick={() => {
            if (selectDateRef.current) {
              const rect = selectDateRef.current.getBoundingClientRect()

              setCoordinates([rect.top + 40, rect.left - 100])
            }
            setIsCalendarVisible(!isCalendarVisible)
          }}
        >
          <p className={styles.date}>{dayjs(date).format('DD MMMM, YYYY')}</p>
        </div>
        {isCalendarVisible && (
          <SmallCalendar
            coordinates={coordinates}
            height="378px"
            isDropdown
            isFooterVisible={false}
            localizer={localizer}
            onSelectSlot={onSelectSlot}
            zIndex={99999999}
          />
        )}

        <div className={styles.navigation}>
          <Left onClick={() => handleNavigate('PREV')} />

          <Right onClick={() => handleNavigate('NEXT')} />
        </div>
      </div>
    </div>
  )
}

export default CalendarToolbar

Can anyone explain why?, I've tried chatGPT but nothing, I have searched for similar post but could not find an answer.
The goal is that whenever user navigates to a specific date if the modal is open, it should close hence the useEffect.

any help at all would be much appreciated, THANKS!!

Jerryh001
  • 766
  • 2
  • 11
ikkako
  • 29
  • 9

0 Answers0