로고 | 설명 |
---|---|
AROOM은 호텔, 펜션, 모텔을 비롯한 전국의 숙소에 대한 정보를 제공하는 서비스입니다. 사용자의 숙소 조회/장바구니/예약 등의 기능을 지원합니다. 🔗 서비스 바로가기 Click ! 👈 |
- 깃허브 레포
- 테스트 계정
- 아이디 : test@test.com
- 비밀번호 : test123
기능 | 내용 |
---|---|
로그인/회원가입 | 회원가입 및 로그인한 유저의 정보를 통해 필요한 페이지 및 기능에 접근이 가능합니다. |
메인 페이지 | 지역/검색 페이지 연결이 가능하고, 판매량/찜 많은 순 숙소를 캐러셀 형태로 볼 수 있습니다. 전체 숙소를 무한스크롤로 조회 가능합니다. |
지역 페이지 | 기본 필터링(날짜/인원수/가격)과 더불어 지역 필터링과 정렬(가격/판매량)을 할 수 있으며, 무한스크롤로 해당 숙소 조회 가능합니다. 해당 지역의 호텔 위치/정보를 지도에서 조회 가능합니다. |
검색 페이지 | 기본 필터링(날짜/인원수/가격)과 더불어 검색 필터링과 정렬(가격/판매량)을 할 수 있으며, 무한스크롤로 해당 숙소 조회 가능합니다. |
상세 페이지 | 로그인한 유저가 숙소의 상세 정보를 확인할 수 있습니다. 해당 숙소의 위치를 지도에서 조회 가능하며, 해당 숙소의 객실 정보 조회/찜/예약/장바구니 기능을 지원합니다. 인원수와 날짜로 필터링되어 해당되는 객실 조회가 가능합니다. |
장바구니 | 로그인한 유저가 장바구니에 담은 객실들의 정보 조회가 가능하며, 삭제 및 예약 기능을 지원합니다. |
예약 | 로그인한 유저가 예약하고자 하는 객실들의 예약(결제)가 가능합니다. |
예약확인 | 결제까지 완료하게 되면 주문 번호와 예약번호를 확인 할 수 있습니다. |
회원가입/로그인 | 메인 페이지 | 검색/지역 페이지 |
---|---|---|
상세/장바구니/예약 페이지 | 상세/찜/장바구니/예약 페이지 |
---|---|
어승준 팀장 (FE) |
김민서 팀원 (FE) |
진종수 팀원 (FE) |
채민석 팀원 (FE) |
이름 | 역할 | 개발 내용 |
---|---|---|
- | 공통 | - 피그마 디자인 - 레이아웃 구현 - msw로 mock 데이터 테스트 |
어승준 | FE 팀장 |
- 검색/지역 페이지 - 필터링 (검색/지역/날짜/인원수/가격) - 정렬 (가격/판매량) - 지도 (지역별 중심좌표 적용 + 숙소 마커/오버레이 표시) - 무한스크롤 - 지역 뒤로가기 (선택지역 기록 세션스토리지 배열) - 기타 - craco로 path alias 설정 - 프로젝트 폴더 구조 세팅 - 로딩 lottie - README 작성 |
김민서 | FE 팀원 |
- 상세 페이지 - 숙소, 객실 정보 조회/ 필터링 (인원수/날짜/재고), 지도(숙소 위치 중심좌표/ 마커) - 예약/장바구니/찜 요청 - 예약/예약확인 페이지 - 예약/결제/예약확인 기능 - 장바구니 페이지 - 마크업 - 기타 - 로딩/404/needLogin/카드 컴포넌트 - theme/globalStyle 설정 - README |
진종수 | FE 팀원 |
- 메인 페이지 - 캐러셀 - 무한스크롤 - 판매량/찜 많은 순/모든 숙소 - 검색/지역 페이지 연결 - 예약 페이지 - 마크업 - 장바구니 페이지 - 조회, 데이터 예약페이지로 전달 - 삭제 |
채민석 | FE 팀원 |
- 회원가입/로그인/로그아웃 - JWT (AccessToken/RefreshToken) - 유저 정보 유효성검사 - 유저 정보 및 토큰 전역 관리 - 헤더/푸터 - 로고, 기능구현 |
폴더 구조 보기
📦SO2ZY_FE
┣─ src
┃ ┣─ App.css
┃ ┣─ App.tsx
┃ ┣─ assets
┃ ┃ ┣─ fonts
┃ ┃ ┃ ┗─ GmarketSansTTFLight.ttf
┃ ┃ ┗─ images
┃ ┃ ┣─ check.svg
┃ ┃ ┣─ chevron-down.svg
┃ ┃ ┣─ footer_github_black_icon.png
┃ ┃ ┣─ home.png
┃ ┃ ┣─ hotelDefaultImg.png
┃ ┃ ┣─ hotelDefaultImg2.png
┃ ┃ ┣─ house.svg
┃ ┃ ┣─ mainLogo.svg
┃ ┃ ┣─ mainLogoThree.png
┃ ┃ ┣─ mainLogoTwo.svg
┃ ┃ ┣─ map.svg
┃ ┃ ┣─ shoppingBag.png
┃ ┃ ┣─ sort-down.svg
┃ ┃ ┗─ sort-up.svg
┃ ┣─ components
┃ ┃ ┣─ Calendar
┃ ┃ ┃ ┣─ Calendar.tsx
┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┣─ common
┃ ┃ ┃ ┣─ Card
┃ ┃ ┃ ┃ ┣─ Card.tsx
┃ ┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┃ ┣─ Footer
┃ ┃ ┃ ┃ ┣─ Footer.tsx
┃ ┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┃ ┣─ Header
┃ ┃ ┃ ┃ ┣─ Header.tsx
┃ ┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┃ ┣─ Item
┃ ┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┃ ┗─ Item.tsx
┃ ┃ ┃ ┣─ Loading
┃ ┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┃ ┗─ Loading.tsx
┃ ┃ ┃ ┣─ NotFound
┃ ┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┃ ┗─ NotFound.tsx
┃ ┃ ┃ ┗─ ScrollToTop
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ ScrollToTop.tsx
┃ ┃ ┣─ Modal
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ Modal.tsx
┃ ┃ ┣─ PriceSlider
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ PriceSlider.tsx
┃ ┃ ┣─ SelectPeople
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ SelectPeople.tsx
┃ ┃ ┗─ SelectRegion
┃ ┃ ┣─ index.ts
┃ ┃ ┗─ SelectRegion.tsx
┃ ┣─ hooks
┃ ┃ ┗─ a.ts
┃ ┣─ index.css
┃ ┣─ index.tsx
┃ ┣─ jsonwebtoken-promisified.d.ts
┃ ┣─ pages
┃ ┃ ┣─ cart
┃ ┃ ┃ ┣─ Cart.page.tsx
┃ ┃ ┃ ┣─ components
┃ ┃ ┃ ┃ ┗─ getCart.ts
┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┣─ confirm
┃ ┃ ┃ ┣─ Confirm.page.tsx
┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┣─ main
┃ ┃ ┃ ┣─ components
┃ ┃ ┃ ┃ ┣─ getPlaces.ts
┃ ┃ ┃ ┃ ┣─ mainAllListContainer.tsx
┃ ┃ ┃ ┃ ┣─ mainAllListItem.tsx
┃ ┃ ┃ ┃ ┣─ mainListContainer.tsx
┃ ┃ ┃ ┃ ┣─ mainListItem.tsx
┃ ┃ ┃ ┃ ┣─ modalData.ts
┃ ┃ ┃ ┃ ┣─ regionModal.tsx
┃ ┃ ┃ ┃ ┗─ regionSelectBtn.tsx
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ Main.page.tsx
┃ ┃ ┣─ placeDetail
┃ ┃ ┃ ┣─ components
┃ ┃ ┃ ┃ ┗─ MapModal.tsx
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ PlaceDetail.page.tsx
┃ ┃ ┣─ regionList
┃ ┃ ┃ ┣─ components
┃ ┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┃ ┗─ Map.tsx
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ RegionList.page.tsx
┃ ┃ ┣─ reservation
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ Reservation.page.tsx
┃ ┃ ┣─ searchList
┃ ┃ ┃ ┣─ index.ts
┃ ┃ ┃ ┗─ SearchList.page.tsx
┃ ┃ ┣─ signIn
┃ ┃ ┃ ┣─ components
┃ ┃ ┃ ┃ ┗─ SignIn.tsx
┃ ┃ ┃ ┗─ index.ts
┃ ┃ ┗─ signUp
┃ ┃ ┣─ components
┃ ┃ ┃ ┗─ SignUp.tsx
┃ ┃ ┗─ index.ts
┃ ┣─ react-app-env.d.ts
┃ ┣─ recoil
┃ ┃ ┣─ atom.ts
┃ ┃ ┣─ regionList.ts
┃ ┃ ┣─ regionModal.ts
┃ ┃ ┗─ searchList.ts
┃ ┣─ reportWebVitals.ts
┃ ┣─ styles
┃ ┃ ┣─ globalStyles.ts
┃ ┃ ┗─ theme.ts
┃ ┗─ utils
┃ ┣─ getData.ts
┃ ┣─ registerFunction.ts
┃ ┣─ textLength.ts
┃ ┣─ useFormatDate.ts
┃ ┗─ useIntersectionObserver.ts
┣─ tsconfig.json
┗─ tsconfig.paths.json
이름 | 내용 |
---|---|
어승준 | 풀스택 팀프로젝트를 진행하면서 힘들었던 것을 다음 3가지였다. 1. API 명세 소통 방식, 2. 계속 바뀌는 BE 데이터 및 로직 구조, 3. BE 인원들의 아쉬운 커뮤니케이션. 우선, 노션에 API 명세를 하다보니, 오탈자 및 누락이 존재했었고, 최신 업데이트가 느렸고, BE 작업시간이 추가적으로 소요되는 단점이 있었다. 따라서 Swagger 또는 REST Docs를 권장했고, 이를 BE 측에서 받아들였으나, 적극적으로 사용하지 않은 것 같아 아쉬웠다. 다음으로, MSW를 도입하여 BE가 서버 배포하지 않아도 목 데이터를 통해 API 로직을 미리 짤 수 있었으나, 계속 BE 데이터 및 로직 구조가 바뀌어서 response가 어떤식으로 올 지 장담할 수 없었다. 따라서 FE 측에서 자의적으로 추측하여 MSW 틀을 고려했어야고, 나중에 실제로 받은 response와 차이가 있어서 수정을 거듭해야 했었다. 마지막으로는 BE 인원들의 아쉬운 커뮤니케이션이다. BE 인원들 중 서로 겹치는 DB 및 로직을 담당한 인원끼리 상이한 데이터 구조를 만들어 작업했었고, 이를 하나로 통합하느라 전체적인 작업시간이 증가했다. 또한, BE 측에서 데이터 구조 및 로직을 미리 FE에 공유하지 않았다. 미리 소통했다면 이에 맞춰 MSW를 더 디테일하게 구성할 수 있었을 텐데 그러지 못해, 추후 대처가 어려워졌다는 점에서도 아쉬웠다. 한편, 이번 풀스택 프로젝트를 통해 MSW, 커뮤니케이션, 이슈트래킹, react-query 등의 기술스택 및 능력을 얻을 수 있어서 좋았다. 그리고 위에 언급한 아쉬웠던 점들을 통해, 앞으로의 협업에서는 미리 잘 대처할 수 있으리라는 점에서도 만족한다. |
김민서 | 이번 프로젝트로 세 가지에 대해 생각해보게 되었습니다. 1) 역할 분배 역할 분배 당시에 인원이 적다는 이유로 경중을 따져 중요하지 않다고 느낀 부분은 자율로 두었는데, 후반으로 갈 수록 각자 이슈에 몰입하다보니 자율로 두었던 부분들에 상대적으로 소홀했던 것 같아 아쉽습니다. 상세한 논의가 장기적으로 보면 디테일에 큰 영향을 미친다는 것을 더 깨닫게 되었습니다. 2) 소통의 중요성 백엔드 내에서 같은 로직을 맡는 부분들에서도 각자 다른 구조를 주었고, 이로 인해 끊임없이 데이터 구조가 바뀌어 마감날까지도 api가 계속 수정되어서 아쉬웠습니다. 또, 백엔드와 프론트엔드가 회의를 진행했음에도 불구하고, 이를 고려 하지 않은 데이터 구조를 주어서 데이터 구조가 계속 변경되었습니다. 이를 통해, 소통의 중요성을 더욱더 깨닫게 되었습니다. 3) 리렌더링과 최적화에 대한 중요성 비동기와 리렌더링으로 인해 백엔드에서 여러가지 문제가 발생할 수 있다는 것을 깨닫게 되었습니다. 이로 인해 최적화에 대해 더 생각하게 되었습니다. 이번 프로젝트를 통해 위 세 가지에 대해 생각할 계기가 되었고, msw를 활용할 수 있어 좋았습니다. react-query와 jest를 제대로 활용하지 못한거 같아서, 공부하여 다음에 좀 더 활용하면 좋을거 같단 생각이 들었습니다. |
진종수 | 이번 팀 프로젝트를 진행하면서 힘들었던 점은 첫 번째로 4명이 진행하다보니 우선순위를 나누어 몇 가지 페이지를 후순위로 빼고 그 뒤 먼저 끝나는 사람이 가져가기로 했는데 생각보다 지체되어 급하게 가져가다보니 조급함에 기능을 좀 더 짜임새있게 구성하지 못했던 것 같다. 결국 리팩토링때 거의 갈아 엎었는데 초반에 조금 더 역할 분배를 확실하게 했더라면 좀 더 짜임새 있게 구성할 수 있었을 것 같단 생각이 들었다. 또한 백엔드와의 협업이 생각보다 쉬운 일이 아님을 깨달았다. 각자 생각했던 바가 달랐고 이를 소통을 통해 조율해 나갔어야 했는데 서로 익숙치 않다보니 미흡한 점이 있었던 것 같다. 동일한 기능을 담당하는 백엔드에서 상이하게 데이터를 주는데 어떻게 목업 데이터를 만들어야 할 지에 대한 고민을 많이 했던 것 같다. 결국 이를 다시 수정하는데 작업 시간이 늘어났고 마감 전 날에 api를 받아서 작업 하다 보니 디테일한 측면에서 아쉬움을 남겼다. 이 부분 또한 소통이 원활했더라면 좀 더 수월하게 할 수 있었을 부분이란 생각이 들었고 다음 프로젝트에서는 소통을 더 자주 하고 이를 문서화를 통해 서로의 이해가 일치함을 계속 확인해야한다는 것을 느꼈다. 이번 프로젝트를 통해 소통의 중요성과 그리고 무한 스크롤 등과 같은 리액트 쿼리에 대해 좀 더 이해하는 계기가 되어서 좋았으며 팀원분의 도움을 받아 MSW도 많이 배워갈 수 있던 좋은 프로젝트였다. 한 편으로 스스로가 아직 더 공부해야함을 느꼈고 다음 프로젝트에서는 테스트 코드와 디테일한 부분을 놓치지 않기 위해 남은 기간동안 열심히 공부해야함을 느꼈다. |
채민석 | 이번 프로젝트를 진행하면서 힘들었던 점은 우선 백엔드와의 소통이였다. 처음 API 명세를 노션에 적어서 진행했었는데 최신 업데이트가 느렸고, 그동안의 시간동안 기다려야만하는 상황들이 생겼다. 따라서 SWAGGER를 활용하여 API의 명세를 문서화하기로 하였는데 내 파트에 API 일부분은 수정될 부분이 있어 SWAGGER에 올리지 않고 노션을 통해서만 API 명세를 확인하니 백엔드 분이랑 커뮤니케이션이 많이 필요했다. response.status 등이 노션 명세에 누락되있었고 그에 따라 약간 개발시간이 지연되는 일이 생겼다. 다음부터는 API 명세에 누락되있거나 필요한 부분을 백엔드와 미리 소통을 좋을 것 같다. 이번프로젝트에서 jwt로그인, MSW 등을 처음으로 해봤는데 이것들의 장점을 알 수 있는 좋은 경험이였다. 원래는 Jest를 활용한 test까지 해보고 싶었는데 진행하지 못해 아쉬웠고 더 공부해서 다음 프로젝트부터는 jest도 활용해보고 싶다. |
이름 | 내용 |
---|---|
어승준 | 1) 무한 스크롤 첫 렌더링 시 스크롤이 자동으로 가장 아래로 내려감으로서 1페이지가 아닌 2페이지를 반환하는 현상 react-infinite-scroller 라이브러리의 initialLoad 프로퍼티를 false로 설정함으로서, 초기 렌더링 시 loadMore 함수를 트리거하지 않도록 하여 해결 2) 뒤로가기 시, 해당 지역의 데이터가 refetching 되지 않는 이슈 선택 지역을 세션스토리지로 배열 및 스트링 형태로 저장 후 react-query의 queryKey에 갱신 하지만, useLocation을 통해 개선하는 것이 더욱 간편하고 효율적! |
김민서 | 1) 비동기 코드로 인해 리렌더링이 되었고, 이 리렌더링으로 인해서 요청 스레드가 db에 저장되기 전에 두번째 요청에서 유일성을 검증하는 로직을 통과해버리는 문제와, db에 락이 걸릴 수 있단 문제가 발생 post가 된 이후에 클릭된 값의 상태가 변경 가능하게 async/await를 사용하여 코드를 수정하였더니, 리렌더링 문제가 해결 2) 리팩토링때 상세페이지에서 날짜/인원수 선택 조회 가능하게 하는 로직을 추가하는 과정에서 데이터 처리에 대해 고민 기존에 메인에서 넘어올때 location.state로 받아왔고, 상세에서는 recoil값으로 관리했음. location.state은 뒤로가거나 앞으로 가면 데이터가 날라가므로 이 모든 것을 고려해야함 |
진종수 | 1) 장바구니 체크박스로 필터링을 해줄 때 각각의 아이템들이 걸러지게 해야 했는데 같은 숙소에서 동일한 룸을 두 번 장바구니에 추가 했을 때 필터링이 안되는 현상 roomCartId라는 고유의 값을 백엔드에게 받아와서 이를 필터링 해주었다. 2) 체크박스 선택/해제 기능 구현과 이를 예약 페이지로 데이터를 넘겨줘야 하는 부분 체크박스 선택/해제를 어렵지 않게 생각했지만 막상 백에서 데이터를 받아와서 이를 체크해서 데이터로 넘겨줘야 하는 과정에서 정말 많이 힘들었다. 이 과정에서 자바스크립트의 기본적인 문법들의 중요성을 깨달았고 map 함수부터 .find, .reduce, .forEach 등 기본기의 중요성을 깨달았다. |
채민석 | 1) 토큰을 decode 하기위해 jsonwebtoken-promisified library를 설치해서 사용해야 했는데 error가 떠서 reference들을 참조하여 craco.config.js를 수정했는데도 error가 해결되지 않았다. config.js 그냥 변수값을 적어야하는데 객체안에 변수 넣어서 생긴 간단한 이슈였지만 평소에 webpack 세팅에 대해 무지했기 때문에 해결하는데 많은 시간을 소비했다. 이번 이슈를 통해 webpack 세팅에 대해 자세히 공부해서 알게되었다. |
이름 | 내용 |
---|---|
어승준 | 무한 스크롤 첫 렌더링 시 스크롤 가장 아래로 내려가는 현상 해결 함수 모듈화, 컴포넌트화, 불필요한 코드 삭제를 통해 가독성, 유지보수 용이 |
김민서 | 상세페이지에서 달력 모달과 인원수 모달 추가해서, 날짜/인원수 선택 조회 가능하게 추가 리렌더링 최소화를 위한 코드 최적화(useCallback), 불필요한 코드 중복은 묶어주기 |
진종수 | post , delete 관련 api 호출 useMutation으로 코드 개선 장바구니에서 아이템 클릭 시 삭제 기능 추가 |
채민석 | 리프레쉬토큰 재발급 에러 핸들링 코드 리팩토링 ,일부 스타일수정 |