구글 캘린더 주별 화면을 클론하여 사용할 수 있도록 함
yarn install
yarn start
localhost:3000
접속
- React
- CRA
- tailwind css
- typescript
- redux
화면 사이즈 및 사이드바 여부에 따라 달력의 크기도 변화
반응형 | 사이드 메뉴 |
---|---|
월별 이동 | 주별 이동 | 오늘 날짜로 이동 및 날짜 선택 시 이동 |
---|---|---|
클릭한 일정칸에 맞게 날짜와 시간 자동 반영된 모달 | 종료 시간을 시작 시간을 기준으로 변경 |
---|---|
일정 생성 | 일정 유지 |
---|---|
커서 위치에 따른 삭제 모달 | 일정 삭제 |
---|---|
src/util
함수 | 역할 |
---|---|
addMonth |
1달 더하기 |
addWeek |
1주 더하기 |
checkIsThisWeek |
날짜가 포커스된 날짜의 주차에 포함되는지 체크 |
createSelectTimes |
일정 생성 모달의 시간 선택 option 리스트 생성 |
dayOfWeek |
일~월까지의 한글 요일 배열 |
formatDay |
yyyy-mm-dd 형식으로 변환 |
getCalendar |
포커스된 월의 데이터 생성 |
getThisWeek |
isThisWeek 가 표시된 1주 추출 |
hours24 |
24시간 리스트 생성 |
src/components
함수 | 역할 |
---|---|
AddScheduleButton |
왼쪽 위의 일정 생성 버튼 |
AddScheduleModal |
일정 생성 모달 |
Header |
헤더 |
ScheduleCalendar |
주별 달력 |
SideCalendar |
사이드바 월별 달력 |
SideCalendarTitle |
사이드바 월별 달력의 헤더영역 |
src/store/module
함수 | 역할 |
---|---|
calendar |
포커스된 날짜 기준 달력 |
schedule |
일정 |
redux
를 사용- 달력 이동 시
nextWeek
등의 리듀서 실행 - 변경된 데이터가 관련 컴포넌트에 자동 반영
{
select: 월 달력에서 날짜 선택 시,
current: { 월별 이동, 주별 이동 등 포커스 이동에 따라
days: 포커스된 월 달력 리스트,
day: 현재 포커스된 날짜,
year: 포커스된 년도,
month: 포커스된 월,
},
}
day, year, month
를 저장하는 이유- 달력 타이틀에 쉽게 반영하기 위해
redux
를 사용- 날짜를 key로 value를 배열로 사용하는 데이터 형태 사용
- 시작 시간, 종료 시간 저장
'2022-01-01': [
{
start: { hour: 1, minute: 20 },
end: { hour: 1, minute: 40 },
color: 'pink',
title: '코딩하기',
},
],
hour
과minute
을 따로 저장하는 이유- 일정 컴포넌트를 생성할 때 높이를 쉽게 지정하기 위해
높이 = (end.hour - start.hour) * (한 칸 높이) - start.minute + end.minute
- 해당 일정의 key(날짜)와 배열 index 값을 사용해서 삭제
delete 일정[날짜][순서(index)]
- 시작 시간 <= 종료 시간이 되도록
- 가능한 시간의 수로 배열 생성
- 0~24 시
- 00, 15, 30, 45 분
- 선택한 시작 시간이 종료 시간의 Index보다 클 경우
- 종료 시간의 Index을 변경
if (endSelectTimeIndex < startSelectTimeIndex) {
endTimeChange(...)
}
- 부모 컴포넌트에서
useState
로 state 생성 - 일정 모달 트리거가 있는 자식 요소에
SetStateAction
전달 - 자식 요소에서
SetStateAction
로 제어
- 부모 요소에서
state
생성한 이유- 왼쪽 위의 일정 생성 버튼 트리거도 같은 모달컴포넌트를 사용하기 위해
- 모달의
Input
값을state
로 적용 - 달력의 날짜 클릭시 모달
Input state
를 변경
문제
- redux state에
Date
타입의 값을 넣었더니 에러
해결
- Json에는
Date
형식이 없다는 것을 학습 string
으로 변환하여 저장
문제
- 예) 1월 31일이 선택된 상태에서 다음 월(2월)로 이동 시 3월로 넘어감
new Date(2021, 1, 31)
===Mar 03 2021
수정
- 월 이동 시 포커스를 무조건
1일
로 설정
해결 방법으로 생각 중
- 이동할 달의 마지막 날을 알아낸 뒤,
- 현재 포커스된 날과 비교하여 제어
문제
2021-1-1
와 같은 형태는input type=date
에 값으로 넣을 수 없음
해결
2021-01-01
과 같은 형태로 변형month < 10 ?
0${month}: month
문제
- 시간 시간과 종료 시간이 같을 때 일정 컴포넌트 생성 시 높이가 생기지 않음
- 높이 :
(end.hour - start.hour) * (한 칸 높이)
해결
if (h < 20) h = 20
추가- 높이가 20보다 작을 경우 무조건 20의 높이 지정
문제
- 일정 컴포넌트의 2/3 지점을 삭제 모달 위치로 지정
- 높이가 길어 스크롤을 해야하는 일정의 경우 가려져서 모달이 안보임
해결
- 클릭했을 때 마우스 값을 가져와서 위치로 지정
- 유틸리티 퍼스트(Utility-first)를 지향하는 CSS 프레임워크
- 유틸리티 퍼스트?
- 스타일을 미리 정의해두고 조합하는 식의 효용성을 가진다
- 유틸리티 퍼스트?
flex, pt-4, text-center
등 유틸리티 클래스 사용- 일관된 스타일을 구현하기 쉬움
- 작은 Element를 만들 때에도 Component를 생성해야하는 Styled에 비해 편하다.