주간달력 및 월간달력 구현

Project Diary/Next.js + Prisma + MariaDB (KiloFlow)

 

1. 주간달력과 월간달력 구현을 위한 라이브러리 설정

Kiloflow 프로젝트에서 주간달력과 월간달력을 구현하기 위해 react-calendar와 dayjs 라이브러리를 사용합니다.

npm install react-calendar dayjs

 

 

2. 달력 컴포넌트 설정 및 기본 렌더링

 

2-1 상태값 정의 및 초기 설정

// 상태값 정의
const [currentTab, setCurrentTab] = useState<Tab>('week'); // 현재 활성화된 탭(주간 또는 월간)을 나타내는 상태값
const [selectedDate, setSelectedDate] = useState(dayjs().toDate()); // 현재 선택된 날짜를 저장하는 상태값

// 탭 변경 핸들러
const handleTabChange = (tab: Tab) => {
  setCurrentTab(tab); // 탭 변경
  setSelectedDate(dayjs().toDate()); // 선택된 날짜를 현재 날짜로 초기화
};

 

2-2 날짜 선택 핸들러

// 날짜 변경 핸들러
const handleDateChange = (value: Date) => {
  setSelectedDate(dayjs(value).toDate()); // 선택된 날짜를 상태값으로 설정
};

날짜를 선택할 때 호출되는 함수입니다.

 

 

3. 달력 타일 클래스 설정

 

3-1 타일 클래서 설정

// 타일 클래스 설정
const tileClassName = ({ date }: { date: Date }) => {
  if (currentTab === 'week') {
    const startOfWeek = dayjs(selectedDate).startOf('week').toDate(); // 현재 주의 시작 날짜
    const endOfWeek = dayjs(selectedDate).endOf('week').toDate(); // 현재 주의 끝 날짜
    if (date < startOfWeek || date > endOfWeek) {
      return 'react-calendar__tile--hidden'; // 현재 주에 해당하지 않는 날짜 숨김
    }
  }
  return null;
};

주간 탭일 경우, 현재 주에 해당하지 않는 날짜를 숨기는 클래스를 반환합니다.

  • startOfWeek, endOfWeek의 기준이 일요일 부터 시작이기 때문에 달력의 한주가 일요일 부터 시작하도록 설정해야 합니다

3-2 주간탭일경우 StyledCalendar 스타일링

const StyledCalendar = styled(Calendar)`
  width: 100%;
  background-color: inherit;
  border: none;
  border-bottom: 1px solid #ccc;
  .react-calendar__navigation {
    display: none; // 네비게이션 숨김
  }
  .react-calendar__tile--hidden {
    display: none !important; // 현재 주에 해당하지 않는 날짜 숨김
  }
  abbr {
    text-decoration: none; // 밑줄 제거
  }
`;
  • .react-calendar__tile--hidden : 주간 탭에서 현재 주에 해당하지 않는 날짜를 숨깁니다.

 

4. 이전 및 다음 버튼 핸들러

 

4-1 이전 버튼 핸들러

// 이전 버튼 핸들러
const handlePrev = () => {
  const newDate =
    currentTab === 'week'
      ? dayjs(selectedDate).subtract(1, 'week').toDate() // 이전 주로 이동
      : dayjs(selectedDate).subtract(1, 'month').toDate(); // 이전 달로 이동
  setSelectedDate(newDate); // 선택된 날짜 업데이트
};

이전 주 또는 이전 달로 이동하는 함수입니다.

 

4-2  다음 버튼 핸들러

// 다음 버튼 핸들러
const handleNext = () => {
  const newDate =
    currentTab === 'week'
      ? dayjs(selectedDate).add(1, 'week').toDate() // 다음 주로 이동
      : dayjs(selectedDate).add(1, 'month').toDate(); // 다음 달로 이동
  setSelectedDate(newDate); // 선택된 날짜 업데이트
};

다음 주 또는 다음 달로 이동하는 함수입니다.

 

 

5. 주간 및 월간 달력 렌더링

return (
  <HomeBlock>
    <CalendarTab
      currentTab={currentTab}
      setCurrentTab={handleTabChange}
      selectedDate={selectedDate}
      handlePrev={handlePrev}
      handleNext={handleNext}
    />
    {currentTab === 'month' && (
      <StyledCalendar
        key={selectedDate.toString()}
        onChange={(value) => handleDateChange(value as Date)}
        value={selectedDate}
        view='month'
        tileClassName={tileClassName}
        formatMonthYear={(locale, date) => `${dayjs(date).year()}년 ${dayjs(date).month() + 1}월`}
        formatDay={(locale, date) => dayjs(date).date().toString()}
        locale='en-US'
      />
    )}
    {currentTab === 'week' && (
      <StyledCalendar
        key={selectedDate.toString()}
        onChange={(value) => handleDateChange(value as Date)}
        value={selectedDate}
        view='month'
        tileClassName={tileClassName}
        formatMonthYear={(locale, date) => `${dayjs(date).year()}년 ${dayjs(date).month() + 1}월`}
        formatDay={(locale, date) => dayjs(date).date().toString()}
        locale='en-US'
      />
    )}
  </HomeBlock>
);
  • StyledCalendar : react-calendar 컴포넌트를 스타일링
  • locale='en-US' : 한 주가 일요일부터 시작하도록 설정합니다.

 

주간탭 > 주간달력
월간탭 > 월간달력