본문 바로가기
728x90
반응형

이번 편에서는 특정 날짜를 클릭하면 해당 날짜에 있는 event가 뜨고, event가 있는 날짜들에 대해 하이라이트 표시를 확인할 수 있도록 설정하는 방법을 말씀해드리겠습니다..

 

저는 Props와 hook(UseState)를 많이 사용하여 CSS에 전달하고 보여주는 편인데요. 아래 코드들과 설명들로 보여드릴게요 ㅎㅎ

 

1. Props 값으로 오늘 날짜와 현재 달, 이전 달, 다음 달 표시 하기 

date-fns라이브러리에서 isSameMonth(), isSameDay()을 활용하여 Day 컴포넌트에서 day에 대해 map()으로 출력할 때 bool 값을 props로 전달하도록 하여 아래 코드처럼 is어쩌고 값을 전달한 후 bool 값에 따라 color와 BackGroundColor를 설정하였다. 

 에를 들어 IsSameDayCheck의 값에 따라 투명색과 하얀색을 구분하였다.

 const Day = styled.div`

  border: 1px solid
    ${({ isSameDayCheck }) => (isSameDayCheck ? "#FFFFFF" : "transparent")};
  color: ${({ iscurrentmonth, istoday, ishighlighted, isSameDayCheck }) =>
    isSameDayCheck
      ? "#FFFFFF"
      : iscurrentmonth
      ? istoday
        ? "#143551"
        : ishighlighted
        ? "#FFFFFF"
        : "#FFFFFF"
      : "transparent"};

  background-color: ${({
    iscurrentmonth,
    istoday,
    ishighlighted,
    isSameDayCheck,
  }) =>
    isSameDayCheck
      ? "transparent"
      : iscurrentmonth
      ? istoday
        ? "#FFFFFF"
        : ishighlighted
        ? "transparent"
        : "transparent"
      : "transparent"};
`;


const renderCalendarDays = () => {


return days.map((day) => {
      const formattedDate = format(day, "yyyy-MM-dd");

      return (
        <Day
          key={day}
          iscurrentmonth={isSameMonth(day, currentMonth)}
          istoday={isSameDay(day, new Date())}
          isSameDayCheck={isSameDay(day, selectedDay)}
        >
        </Day>
      );
    });
  };

2. EventData가 있는 날짜의 경우 데이터 출력하기 

백엔드의 더미데이터가 생기기 전 Json 형식의 더미데이터를 임시로 만들어서 달력이 출력될 때 시각적인 포인트를 주고자 하였고, 클릭하면 Event data 값이 UseState 훅으로 값이 저장되어 보일 수 있도록하였다. 

 날짜에 대해 클릭하였을 때 handleDateClick()에서 전달되는 내용들을 훅으로 저장하여 다른 컴포넌트에서 읽어와 쓸 수 있도록 하였다. 

const data = [
    {
      date: "2023-06-20",
      title: "라이브 통역 사업",
      content:"축구선수"
      category: "축구",
    },
    {
      date: "2023-07-12",
      title: "제목2",
      content: "내용2",
      category: "배구",
    },
    {
      date: "2023-08-20",
      title: "제목1",
      content:"메롱"
      category: "글로벌국",
    },
  ];
  
    const renderCalendarDays = () => {
    const days = getCalendarDays();

	// 클릭함수 추가 
    const handleDateClick = ( 
      day,
      formattedDate,
      title,
      content,
      category,
    ) => {
      const selectedDate = format(new Date(formattedDate), "yyyy.MM.dd(iii)", {
        locale: ko,
      });

      setSelectedDate(selectedDate);
      setSelectedTitle(title);
      setSelectedContent(content);
      setSelectedCategory(category);
      setSelectedDay(day);
    };

    return days.map((day) => {
      const formattedDate = format(day, "yyyy-MM-dd");
      const eventData = data.find((item) => item.date === formattedDate);

      return (
        <Day
          key={day}
          iscurrentmonth={isSameMonth(day, currentMonth)}
          istoday={isSameDay(day, new Date())}
          ishighlighted={eventData !== undefined}
          isSameDayCheck={isSameDay(day, selectedDay)}
          // 클릭되었을 때 기능 시작
          onClick={() => 
            handleDateClick(
              day,
              formattedDate,
              eventData?.title,
              eventData?.content,
              eventData?.category,
            )
          }
        >
         // 이벤트가 있는 날짜의 경우 아래의 컴포넌트가 같이 출력되도록 하였다.
          {eventData && (
            <ScheduleDot
              src={require("../../../Assets/Img/MainHome_Img/일정Dot.png")}
            />
          )}
          {format(day, "d", { locale: ko })}
        </Day>
      );
    });
  };

3. 저장된 값들 출력하여 보여주기 

<>
       <WeekdayDiv>
          <Weekday left={25}>일</Weekday>
          <Weekday left={61}>월</Weekday>
          <Weekday left={61}>화</Weekday>
          <Weekday left={61}>수</Weekday>
          <Weekday left={61}>목</Weekday>
          <Weekday left={61}>금</Weekday>
          <Weekday left={61}>토</Weekday>
        </WeekdayDiv>
        // 달력 함수 출력 
        <CalendarWrapper>{renderCalendarDays()}</CalendarWrapper> 
        // 클릭한 날짜에 대한 정보 출력하기
		<ScheduleDiv> 
          {selectedDate && (
            <>
              <ScheduleDate>{selectedDate}</ScheduleDate>
              <EventTitleDiv>
                <CategoryDiv IsselectedCategory={selectedCategory}>
                  {selectedCategory}
                </CategoryDiv>
                <EventTitle>{selectedTitle}</EventTitle>
              </EventTitleDiv>
              <EventContet>{selectedContent}</EventContet>
            </>
          )}
        </ScheduleDiv>
</>
728x90
반응형