- 일정 관리 서비스
- 개발 기간: 12/18 ~ 1/5
- 배포링크 https://taskify-sand-two.vercel.app/
- 데모계정
id: guest@email.com
pw: guest112
강현지 | 김다은 | 남민섭 | 안윤진 | 임건우 |
---|---|---|---|---|
‘>’ 클릭 시 해당 특징 설명을 보실 수 있습니다.
페이지
- react-hook-form 라이브러리를 사용하였습니다. useForm의 controller를 사용하여 각 폼의 역할을 구분해서 유효성 검사를 통과하지 못하면 에러메세지 전달하고 모든 유효성 검사를 통과하면 회원가입/로그인 버튼이 활성화됩니다. 이후 useRequest 커스텀 훅을 사용하여 데이터를 요청합니다.
- 회원가입 기능에서는 이메일, 닉네임, 비밀번호, 비밀번호 확인 그리고 이용약관 동의를 사용하여 회원가입 할 수 있게 하고 로그인 기능에서는 이메일, 비밀번호를 사용하여 로그인할 수 있도록 합니다
- 참여중인 대시보드
- onClick 이벤트 함수로 현재 페이지를 변경하고, 각 페이지에 해당하는 데이터를 useRequest 커스텀 훅으로 요청합니다.
- 페이지네이션 UI를 구축하였습니다, 각 대시보드 클릭 시 해당 대시보드로 이동합니다.
- 새로운 대시보드 생성
- 모달을 통해 폼 제출 시 커스텀훅 useRequest를 사용해 post 요청하게 했습니다.
- 대시보드 생성 시 참여중인 대시보드와 사이드메뉴에 새로운 대시보드 추가하도록 했습니다.
- 초대받은 대시보드
- 초대 거절 / 수락
- 초대 거절 / 수락 시 커스텀 훅 useRequest 을 사용해 put요청하도록 했습니다.
- 초대 거절 / 수락 시 즉시 초대목록에서 삭제, 참여중인 대시보드와 사이드메뉴에 반영하도록 했습니다.
- 초대 목록 검색
- useInfiniteScroll 커스텀 훅을 사용하여 무한스크롤을 구현했습니다.
- 스크롤이 브라우저 최하단에 도달하면 초대목록을 더 불러옵니다.
- 무한스크롤
- useInfiniteScroll 커스텀 훅을 사용하여 무한스크롤을 구현했습니다.
- 스크롤이 브라우저 최하단에 도달하면 초대목록을 더 불러옵니다.
- 초대 거절 / 수락
- DnD
- react-beautiful-dnd 라이브러리를 활용하여 핸들, 드래그, 드롭이 가능한 영역을 각각 지정하고, 드래그 전 후에 이벤트 함수를 통해 동작을 제어합니다.
- 칼럼 간, 카드 간, 서로 다른 칼럼의 카드 간의 이동이 가능합니다.
- 더보기 버튼
- useState 훅을 통해 이벤트 함수 작동 시 기존 데이터와 새로 불러온 데이터를 병합한 새 리스트를 저장합니다.
- 세로스크롤 기반의 Mobile, Tablet 사이즈에서 더보기 버튼을 통해 카드리스트가 확장됩니다.
- 무한 스크롤
- useInfiniteScroll 커스텀 훅을 사용하여 스크롤이 브라우저 최하단 요소에 도달했을 시 작동할 함수를 넘겨줍니다.
- 가로 스크롤 기반의 PC 사이즈에서, 스크롤이 브라우저 최하단 요소에 도달했을 때 카드리스트가 확장됩니다.
- 컬럼 관리
- useRequest 커스텀 훅을 사용하여 데이터를 요청하였고 응답을 받으면 데이터를 jotai로 전역 상태 관리하였습니다.
- 대시보드 내에서 새로운 컬럼 생성, 이미 존재하는 컬럼 이름 변경 그리고 컬럼 삭제할 수 있습니다.
- 할 일 생성, 수정
- 커스텀한 이미지 업로드 기능은 사용자가 선택한 이미지를 formData 객체에 추가하고, 이벤트 핸들러를 통해 useRequest 커스텀 훅으로 서버에 업로드 됩니다. 응답으로는 새 이미지 데이터를 받습니다.
- jotai 전역 상태관리를 사용해 페이지와 모달간에 전달하는 props를 줄였습니다.
회원가입 & 로그인
나의 대시보드
대시보드
Hook
- useRequest
- axios 라이브러리를 사용하여 instance를 생성해 data를 fetch 합니다.
- url과 params 등을 파라미터로 받아 fetch 해온 데이터 또는 오류, 그리고 isLoading 변수를 리턴합니다.
- axios interceptor
- axios 라이브러리의 instance interceptor를 활용했습니다.
- 매번 요청을 보낼 때 access token을 넣어주지 않아도 access token을 갖고 있다면 자동으로 요청의 헤더에 추가되도록 하였습니다.
- useInfiniteScroll
- Intersection Observer API를 사용하여 실행 될 함수를 보내고 containerRef 를 리턴받아 스크롤이 일어날 구역에 ref로 추가합니다.
- 서비스 내 다수의 페이지에서 무한스크롤 기능을 활용하고 있어 커스텀 훅을 통해 observe와 unobserve 상태를 관리하도록 하였습니다.
api 연결
무한스크롤
공통 컴포넌트
- Compound Pattern을 적용해 모달과 관련된 데이터를 context, jotai로 관리하며, 기능의 관심사를 분리하여 구현했습니다.
- 모달 위에서 모달을 또 여는 경우, 두번째 모달이 열릴 때 첫번째 모달이 닫히도록 구현했습니다.
- 무한 스크롤
- useInfiniteScroll훅을 사용하고, react query 라이브러리 useInfiniteQuery를 통해 데이터 fetch합니다.
- 스크롤이 브라우저 최하단 요소에 도달했을 때 자동으로 다음 대시보드들을 불러옵니다.
- 스켈레톤 UI
- Material UI 라이브러리를 사용해 스켈레톤 UI를 만들고, useRequest 훅을 통해 표시 여부를 확인합니다.
- 다음 대시보드가 로딩될 동안 스켈레톤 UI를 보여줍니다. 로딩 시간이 짧을 시 스켈레톤 UI가 짧게 나타났다가 사라지는 현상을 방지하기 위해 로딩 시간이 300ms 이상일 때만 스켈레톤 UI가 나타나도록 구현했습니다.
모달
사이드메뉴
기타
- 폰트
- 프로젝트에서 사용되는 폰트 크기를 총 6가지, 폰트 굵기를 총 3가지로 한정지어 heading1-normal 과 같은 방식으로 폰트 스타일을 하나의 클래스로 줄 수 있도록 했습니다.
- tailwind.config.ts 파일에서 폰트 크기 및 굵기에 대한 custom theme을 설정하고 global.css에서 utility layer로 폰트 클래스를 선언하여 사용했습니다.
- heading1 (24px)
- heading2 (20px)
- subheading (18px)
- body1 (16px)
- body2 (14px)
- caption (12px)
- light (400)
- normal (500)
- bold (700)
- 컬러 팔레트
- 프로젝트에서 사용되는 색상들을 custom theme으로 설정하여 사용했습니다.
- global.css에서 base layer에 지정해둔 컬러 값들이 data-theme에 따라 다르게 들어가도록 설정하여 추가적인 스타일 코드 없이 다크 모드를 구현했습니다.
- 컴포넌트
- 프로젝트에서 주로 사용되는 컴포넌트들의 스타일을 global.css에서 component layer에 선언해두어 사용하였습니다.
- _app.tsx에서 공통 레이아웃을 주어 레이아웃 적용했습니다.