[React] 요일과 날짜 표시하기🖐✌ 달력 만들기

: ) YOUNG·2021년 10월 26일
3

React

목록 보기
11/13
post-thumbnail

궁금하신 점이나 고칠 부분이 있다면 언제든지 댓글 남겨주세요!

기존의 쓰던 달력이 구리다는 걸 알게되서 다시 바꿔보기로 했다

어떻게 바꿔볼까 하면서 자료를 찾아보다 우연히 현대카드 DIVE에서 너무 이쁘게 표현이 되어있는걸 보고 따라해보기로 했다

내가 기존에 만들었던 방식은 날짜만 표시되는데 반해,
현대카드 홈페이지는 요일과 날짜가 표시되면서 홈페이지 접속 기준 당일은 테두리로 표시해주고 일요일은 공휴일로 빨간색으로 표시된다 그리고 날짜에 마우스를 올리면 색상이 반전되도록 만들어 놓은 모습!

날짜표시되는 부분을 컴포넌트로 한번 만들어보자

컴포넌트 수정시작🚧

함수와 Hooks

먼저 Calendar컴포넌트에서 날짜 계산을 위해 변수와 state 생성합니다.

Calendar.js

  const now = new Date();
  const todayWeak = now.getDay();
  const today = now.getDate();
  const lastday = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();

  const [daylist, setDaylist] = useState([]);
  const [weaklist, setWeaklist] = useState([]);

일주일 = todayWeak , 오늘의 날짜 = today, 이번달의 마지막날짜 = lastday

함수는 컴포넌트 밖에서 계산!

오늘 기준 날짜를 계산하는 함수

const getAlldate = (today, lastday) => {
  let dates = [];

  dates[0] = today;
  for (let i = 1; i <= 6; i++) {
    today++;
    //마지막 날보다 날짜가 클경우 today를 1로 초기화.
    if (today > lastday) {
      today = 1;
      dates[i] = today;
    }
    //일반 경우 그냥 날짜 추가
    else {
      dates[i] = today;
    }
  }

  //요일 정상적으로 뜨는지 확인해보자
  //console.log(dates[1].getDay());

  return dates;
};

요일을 계산 하는 함수

//요일 표시 평일 검정색, 토요일 파란색, 일요일 빨간색
const getAllweak = (todayWeak) => {
  let strWeak = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  let weaklist = [];

  //첫번째 오늘 날짜 적용

  weaklist[0] = strWeak[todayWeak];

  for (let i = 1; i <= 6; i++) {
    todayWeak++;
    if (todayWeak > 6) {
      todayWeak = 0;
      weaklist[i] = strWeak[todayWeak];
    } else {
      weaklist[i] = strWeak[todayWeak];
    }
  }

  return weaklist;
};

묶어서 표현을 위해 객체로 표현하는기로 결정!

  const CalendarDay = getAlldate(today, lastday);
  const CalendarWeak = getAllweak(todayWeak);

  /*⭐⭐날짜와 요일을 같이 표시하기위해서 만들어 놓은 객체
  날짜를 하나씩 출력해서 객체로 만들기위해서 함수를 실행시킨뒤
  분해로 하나씩 넣는 방법을 사용했음 ⭐⭐*/
  const CalendarObject = [
    { weak: CalendarWeak[0], day: CalendarDay[0] },
    { weak: CalendarWeak[1], day: CalendarDay[1] },
  
    { weak: CalendarWeak[2], day: CalendarDay[2] },
    { weak: CalendarWeak[3], day: CalendarDay[3] },
    { weak: CalendarWeak[4], day: CalendarDay[4] },
    { weak: CalendarWeak[5], day: CalendarDay[5] },
    { weak: CalendarWeak[6], day: CalendarDay[6] },
  ];
 
    useEffect(() => {
    return () => console.log("Clean up");
  });

  const Weak = useRef(null);

태그

토요일 일요일 색상구분을 위해서 className "weak"에서
CalendarWeak의 값이 Sat, Sun일 경우 CSS의 .Sat과 .Sun으로 스타일을 적용하도록 지정해서 색상을 표현하도록 했습니다.

요일과 날짜가 같이 마우스오버 효과를 얻기위해서 하나의 태그로 묶어줍니다.

return (
    <div className={cn("Calendar")}>
      <div className="Year-MonthList">
        <p>
          <span className={cn("Year")}>
            <Year
              id="Year"
              format={"YYYY"}
              ticking={false}
              timezone={"KR/Pacific"}
            />
          </span>
          &nbsp;&nbsp;
          <span className={cn("Month")}>
            <Month format={"MMMM"} ticking={false} timezone={"KR/Pacific"} />
          </span>
        </p>
      </div>
      <div className={cn("DayList")} onChange={getList} ticking={false}>
        <div className={cn("daylistContainer")}>
          {CalendarObject.map((calendar, index) => (
            <div className={cn("daylistSector")}>
              <div
                className={cn(
                  "weak",
                  calendar.weak === "Sun" ? "Sun" : "weak",
                  calendar.weak === "Sat" ? "Sat" : "weak"
                )}
                ref={Weak}

                {calendar.weak}
              </div>
              <div className={cn("day")}>{calendar.day}</div>
            </div>
          ))}
        </div>
      </div>
      <div className={cn("CalendarIconContainer")}>
        <span className={cn("CalendarIconText")}>전체 보기</span>
        <BiCalendar className={cn("CalendarIcon")} />
      </div>
    </div>
  );
};

SCSS

$lightblue: #3ea8ff;
$deepblue: #156fb9;
$darkblue: rgb(12, 86, 129);

.Calendar {
  margin-bottom: 140px;
  align-items: center; //수직 중앙 정렬
  justify-content: center; //수평 중앙 정렬
  text-align: center;
  height: 20vh;
  width: 100%;
  overflow: initial;

  .Year-MonthList {
    font-family: "SEBANG";
    font-style: italic;
    color: #1864ab;
    .Year {
      font-size: 2.4rem;
    }

    .Month {
      font-size: 1.55rem;
    }
  }

  /* 요일과 날짜를 표시하는 컨테이너 (List)*/
  .DayList {
    position: relative;
    width: auto;
    height: 3.5rem;
    font-size: 1.4rem;
    color: #005096;
    float: left;
    justify-content: center;
    align-items: center;
    text-align: center;
    left: 17%;

    .daylistSector {
      width: 40px;
      height: 70px;
      justify-content: center;
      align-items: center;
      text-align: center;
      float: left;
      margin-left: 4em;
      cursor: pointer;
      width: 70px;
      height: 110px;
      border-radius: 40px;
      padding-top: 40px;

      .Sun {
        color: red !important;
      }

      .Sat {
        color: $deepblue !important;
      }

      &:hover {
        background: #224861;
        color: white;
        .weak {
          color: white;
        }
      }

      &:nth-child(1) {
        border: 0.04em solid rgb(12, 86, 129);
      }

      .weak {
        font-family: "Nanum Myeongjo";
        font-size: 0.8em;
        align-items: center; //수직 중앙 정렬
        justify-content: center; //수평 중앙 정렬
        color: black;
        text-align: center;
        margin-bottom: 20px;
      }

      .day {
        font-weight: bold;
      }
    }

    /* 버튼 이벤트를 위해서 버튼을 만들었지만 
    아이콘에서 이벤트 처리를 하기위해 보이지는 않도록 만들었음 */

    .CalendarIconContainer {
      align-items: center; //수직 중앙 정렬
      justify-content: center; //수평 중앙 정렬
      position: absolute;
      width: 150px;
      height: 100px;
      font-style: bold;
      cursor: pointer;
      color: #353535;

      .CalendarIconText {
        font-size: 23px;
      }

      .CalendarIconSpan {
        position: absolute;
        left: 50%;
        right: 40%;
        margin-top: 40px;

        .CalendarIcon {
          color: #353535;
          margin-bottom: -12px;
          font-size: 3rem;
          text-align: center;
        }
      }
    }
  }
}

완성

수정이 완료된 모습!

0개의 댓글