Skip to content

3. 달력(일정)관련 기능 구현

임예지 edited this page May 30, 2023 · 2 revisions

👩‍⚕️ 병의원 채용프로세스 관리 서비스, 메디매치 👨‍⚕️

  • 관심사의 분리, 추상화를 위해 노력했습니다. 컴포넌트를 기능단위로 나눴고, 가독성과 관심사의 분리를 위해 custom hooks를 사용해 로직과 UI를 분리하였습니다.

  • 제가 구현한 기능의 컴포넌트와 Hook들이 밑에 정리돼있습니다.

달력(일정)관련 기능 구현

서류합격 이메일 전송 시, 자동으로 달력에 면접날짜 등록
달력일정(CRUD)


/src/pages/Calendar.tsx

💻 Calendar Component

Calendar 컴포넌트는 일정을 관리하고 표시하는 데 사용됩니다. 이 컴포넌트는 사용자의 프로필과 캘린더 UI를 포함하고 있습니다.

  • useScheduleManagement hook을 활용해 캘린더 데이터를 가져오고, 등록, 변경, 삭제하는 기능을 구현하였습니다.
  • UserProfile 컴포넌트를 사용하여 사용자 프로필, 정보를 보여주고, CalendarUI를 통해 캘린더 UI를 보여줍니다.

📄 useScheduleManagement Hook

캘린더 데이터를 가져오고, 등록, 변경, 삭제하는 기능을 관리합니다.

  • react-queryuseQuery, useMutation을 커스텀 훅으로 만들었습니다.


/src/components/CalendarUI.tsx

💻 CalendarUI Component

  • react-calendar를 사용해 캘린더 UI 커스터마이징 했습니다.
    • 사용자 친화적이면서도 디자인 요구사항을 충족하는 캘린더 기능을 위해서
  • 일정을 추가하는 form은 react-hook-formyup을 사용해 유효성 검사를 진행합니다.
<StyledCalendar
  value={value} // 현재 선택된 날짜
  showNeighboringMonth={false} // false : 현재 달력에 표시된 달의 이전 달과 다음 달의 날짜는 표시되지 않는다.
  navigationLabel={({ date }: { date: Date }) => `${date.getFullYear()}. ${date.getMonth() + 1}`} // 달력 네비게이션 옆에 년, 월이 표시되는데 어떤 방식으로 표시할 지 커스터마이징
  onChange={onChangeDate}
  tileClassName={tileClassName} // 해당 날짜가 특정 조건을 만족하면 해당 날짜에 css 클래스 이름을 붙여줍니다.('highlighted', 'selected') .highlighted, .selected를 사용해 css코드를 작성해두었습니다.
  formatDay={formatDay} // 원래는 달력에 날짜에 '1일', '2일' 이렇게 적혀있었는데 그냥 숫자만 적히게 하기 위해서
/>
// 모든 등록된 달력 일정 중, 선택 된 날짜에 등록된 일정이 있는지 찾습니다.
const filterSchedule = schedule?.filter(
  (selectDate: GetCalendarData) => selectDate.calendarDate === dateToString(value),
);
const getPreviousDayString = (numDays: number) => {
  const previousDay = new Date(value);
  previousDay.setDate(value.getDate() - numDays);
  return previousDay.getDate();
};

const getAfterDayString = (numDays: number) => {
  const previousDay = new Date(value);
  previousDay.setDate(value.getDate() + numDays);
  return previousDay.getDate();
};

{/* 날짜에 그냥 +1, -1을 해주면 1일을 클릭 시 옆에 -1, -2, -3이라고 나와서 이렇게 getPreviousDayString, getAfterDayString 함수를 만들어 처리했습니다. */}
{[3, 2, 1].map(numDays => (
  <DayGrayBox key={numDays}>
    <p>{getPreviousDayString(numDays)}</p>
      </DayGrayBox>
))}
<DayBox>
  <p className='day'>{value.getDate()}</p>
  <p className='dayOfWeek'>{days[value.getDay()]}</p>
</DayBox>
{[1, 2, 3].map(numDays => (
  <DayGrayBox key={numDays}>
    <p>{getAfterDayString(numDays)}</p>
      </DayGrayBox>
))}

💻 ScheduleElement Component

  • ScheduleElement 컴포넌트를 사용해 각 일정을 렌더링 합니다.