[Project] Air BnB clone

예흠·2020년 9월 27일
5

Project

목록 보기
1/3
post-thumbnail

Beer BnB


프로젝트 소개 📃

  • 숙박 공유 서비스 에어비앤비 클론 프로젝트

기간 📆

  • 2020.8.31 ~ 2020.9.11(2 Weeks)

Table of contents 💼

General info 🛠

  • 숙박 공유 서비스 에어비앤비 클론 프로젝트
  • 팀원 : Front-end(황연욱, 이조은, 최예흠) Back-end(김해준, 고지원)
  • Front-end Github
  • Back-end Github

Demo 🖥

Technologies 👨🏻‍🔬

- Tools 🦾

  • Git(Control Commit history by Squash and Rebase)
  • Trello
  • AWS
  • Docker
  • PostMan(Share API documentation)

- Front-End

  • JavaScript(+ ES6 syntax)
  • React.js(setting with CRA)
  • Styled-Component
  • react-router-dom
  • Redux
  • Google Social Login
  • react-google-maps
  • react-dates

- Back-End

  • Python
  • Django Web Framework
  • CORS headers
  • Selenium
  • MySQL
  • Bcrypt, JWT
  • Google Social Login
  • RESTful API
  • AWS RDS 연동 후 Docker container를 EC2 Server를 통한 배포
  • 각 엔드포인트 Unit Test 구현

Features 🎬

직접 구현한 기능은 ✅, 팀원이 구현한 기능은 ✔️ 표시

1) 숙소 리스트 페이지 ✅

  • ✅ Redux를 통한 체크인 - 체크아웃 날짜 연동 기능을 통해 리스트 상단 여행 일정을 알맞게 보여주는 기능
  • ✅ 상단 필터 옵션 각각 모달창 생성 및 Redux를 통해 State관리하여 알맞게 리스트가 필터링 되는 기능
  • ✅ 각 숙소 정보들의 이미지들에게 setTimeout과 transition을 State로 관리하는 것을 통한 Infinity Image Slider 기능
  • ✅ Custom Hook을 통해 Redux 에서 State를 관리하는 로직과 실제 UI부분의 분리
  • ✅ async, await를 통해 리스트를 fetch함수로 받아오는 시간동안 로딩중 애니메이션 구현
  • ✅ 페이지에 알맞게 offset 값을 부여해 숙소 데이터를 받아오는 Pagination 기능
  • ✅ react-google-maps 를 이용해 각 숙소별 위도 경도를 넣어 지도상에 가격표를 알맞은 위치에 띄워서 보여주는 기능
  • ✅ 숙소리스트의 각 숙소 마우스 hover시 지도에서 hover 된 숙소의 가격표만 스타일이 바뀌어 보여주는 기능
  • ✅ 지도상의 각 숙소마다 가격표 클릭시 숙소정보 모달창으로 띄워지는 기능
  • ✅ 지도 왼쪽 상단의 close 버튼 클릭시 지도가 사라지고 숙소 리스트의 스타일과 레이아웃이 바뀌는 기능
  • ✅ 페이지 크기가 일정이상 줄어들면 지도가 없어지고 리스트만 남는 반응형 웹 기능

2) 회원가입 / 로그인 페이지 ✔️

  • ✔️ 모달창의 요소 모두 컴포넌트화 이후 재활용
  • ✔️ Fetch()의 GET, POST 방식을 통해 서버와의 통신
  • ✔️ 이메일 로그인 및 회원가입 구글 로그인 및 회원가입 모달 창 구현
  • ✔️ 로그인 및 회원가입 유효성 검사 및 그에 맞는 경고창 구현
  • ✔️ Redux 통해 로그인 후 상태 관리
  • ✔️ Oauth2.0로 Google API 호출 소셜 로그인 구현

3) 메인 페이지 ✔️

  • ✔️ grid를 통해 레이아웃
  • ✔️ Map 함수를 통해 불필요한 중복 제거
  • ✔️ AirBnB/react-dates 를 이용한 체크인, 체크아웃 날짜 선택 기능
  • ✔️ Redux를 통한 체크인 - 체크아웃 날짜 연동 기능(Nav bar의 달력 및 상세페이지에 존재하는 2개의 달력 총 3개의 달력 연동)

4) 숙소 상세 페이지 ✔️

  • ✔️ Url 정보를 이용한 동적 라우팅
  • ✔️ 침대, 침구 유형이 4개 이상일 경우 슬라이더 형태로 레이아웃 변경되는 기능
  • ✔️ 리뷰의 평균 점수 Progress bar로 표현
  • ✔️ AirBnB/react-dates 를 이용한 체크인, 체크아웃 날짜 선택 기능
  • ✔️ Redux를 통한 체크인 - 체크아웃 날짜 연동 기능(Nav bar의 달력 및 상세페이지에 존재하는 2개의 달력 총 3개의 달력 연동)
  • ✔️ Custom Hook을 통해 Redux 에서 State를 관리하는 로직과 실제 UI부분의 분리
  • ✔️ 리뷰 모두보기 모달 창 구현 및 Observation API & Query String을 통한 Infinity Scroll 기능

Contact 🙋‍♂️

Front-end

Back-end


주요 구현 과정 🎥

- 현란한 branch들

  • 가장먼저 1차 프로젝트와 달리 2차에서 중요시 했던 것은 컴포넌트의 세부적인 분리와 branch를 좀더 세세하게 나누어서 부분적으로 merge를 빠르게 시키려 했던 것이다.

  • 브랜치 28개, 1차때는 10개 뿐이었던 브랜치가 이렇게나 많이 늘어났다.
    => 이렇게 브랜치를 좀더 나누고 컴포넌트를 세분화 하여서 PR을 날리니 merge도 더욱 빠르게 할 수 있었고, 코드리뷰하시기도 훨씬 수월하셨다고 하신다.

- filtering 기능 구현

  • 이 기능을 하면서 조금 시간을 많이 잡아먹었던 것 같다.
    redux를 사용하지 않고 처음 구현을 할때는 필터들의 가장 상위 component에 state들을 만들고 함수들도 상위 컴포넌트에 몰아서 만들고 props로 하위 컴포넌트 들에게 전달시켜주는 방식으로 구현했다.

  • 이렇게 되면 상위에서 각각의 관리를 해주는 state들을 만들고 그것을 변환시켜주는 함수도 각각 만들어 주어야 해서 상당히 한 눈에 들어오기가 어려웠다.

  • 또한 state를 계속 props로 깊은 곳까지 전달해 주어야 했고 함수가 이벤트를 통해 실행됐을때 위에서 부터 순차적으로 바뀌기 때문에 바꿔주고 싶었다.
    => 바로 redux를 적용해서 만들어 보니 굉장히 코드 가독성도 좋아지고 store하나에서 state를 관리해주고 깊은 곳에 있는 component에도 필요할때 provider 덕분에 store에 접근할 수 있어서 매우 편리했다.

  • 위의 코드는 useSelector를 자주 사용하여 커스텀 훅을 하나 만들어서 사용하여 원하는 곳에서 store의 state를 가져와 useDispatch를 사용해서 액션을 주어 state를 바꿔주는 코드이다.

  • 커스텀 훅에 대해서는 아래에서 설명한다.

아쉬운점 😢

  • redux의 store 하나에 모든 것들을 몰아 넣다보니까 그 reducer의 코드들이 굉장히 복잡해 진 것 같다.
    payload라는 변수 하나로 통일 하고 반복되는 코드들을 Util파일 하나를 만들어 함수 호출 방법으로 바꾼다면 코드가 좀더 단순화 될 것 같다.

  • 기능별로 reducer를 나누어 주어 코드 가독성과 하나의 리듀서에 하나에 관한 것만 있을 수 있도록 리팩토링 해야겠다.


- custom Hook

  • 위에서 언급한 것처럼 useSelector가 굉장히 많은 곳에서 사용되기 때문에 반복되는 코드들과 상황에 맞게 item을 가져올 수 있도록 커스텀 훅을 하나 만들어 보았다.

  • 이렇게 커스텀 훅을 사용하니 굉장히 편리하게 상황에 맞는 state를 가져올 수 있어서 편리했다.

  • 처음에는 라이브러리를 사용해서 이 기능을 만들려고 했으나 혼자서도 충분히 만들수 있을거라 생각하여서 만들어 보다가 생각보다 시간이 걸려버렸다.

Issue ⚠️

  • 가장 먼저 생각한 것은 오른쪽으로 이동할때마다 이미지의 배열들에 기존 이미지들을 더 붙이다보면 무한대로 할 수 있으리라고 생각했다.
    그러나 그렇게 되면 이미지가 계속 늘어나게 되어서 굉장히 비효율적이라고 생각했고 또한 왼쪽으로 넘어가는 이미지는 늘리게 되면 transition때문에 동적으로 보여져서 이미지가 휘리릭 돌아가게 되는 현상이 발생해 버린다.

해결 과정

  • 그래서 먼저 생각한 것은 특정 지점에서의 인덱스를 통한 위치 이동과 transition의 컨트롤 이었다.
    이미지가 특정 위치에 도달 하면 transition이 작동하지 않게한다.
    => 그 사이에 현재 있는 위치를 옮긴다.
    => 옮기는 것이 끝나면 transition이 다시 작동하게 한다.
    이런식으로 해결 방법을 구상하였다.

  • 먼저 transition을 switch시키는 toggle state를 하나 만들고 특정 위치에 도달하면 애니메이션 시간만큼 setTimeout()을 걸고, toggle state를 false로 만들어서 transition이 작동하지 않도록 만들었다.(조건을 이용해)
    => 그 사이에 이미지 위치 인덱스를 원하는 곳으로 옮기고 옮기는 것이 끝난다면 toggle state가 true가 돼서 transition이 다시 작동하도록 만들었다.

  • 이미지의 하단부에 나오는 현재 이미지의 위치를 표시해주는 5개의 원은 이미지와는 별개로 circle이라는 슬라이더를 만들어서 움직이도록 만들었다.

아쉬운점 😢

  • 하다보니까 시간이 부족해 저렇게 까지만 만들고 마무리 지었지만 이러한 무한 이미지 슬라이더를 더 쉽고 좋은 방법으로 만들 수 있을 것 같았다. 시간이 될때 이 코드보다 더 좋은 방법을 생각하여 리팩토링 할 생각이다.

  • 이동 하는 버튼을 빠르게 누르면 애니메이션에 오류가 발생하여서 애니메이션이 보여지지 않는 버그가 있다.
    애니메이션이 끝날때까지 버튼을 눌러도 작동하지 않는 로직도 추가해서 좀 더 완벽하게 만들도록 리팩토링 해야겠다.


- Loading중 animation

  • 만들다 보니 문득 fetch를 받아오는 동안 로딩 시간이 생각보다 길었다.
    그래서 그 시간동안 보는 사람들이 이게 렉걸린 것인지 무슨 상황인지 알아야 한다고 생각하여서 즐거움도 줄겸 피자를 돌려 보았다.

  • 이렇게 async await를 사용해서 fetch를 받아오는 동안 피자가 돌아가는 것을 활성화 시켰다.

- Google Map 으로 지도 구현

  • 이 기능을 구현하기 위해서 Google Cloud PlatForm 가입후 API키 생성하였다.
    그리고 코드에서 api Key 부분에 생성한 키를 넣어 주었다.

  • 처음에 react-google-maps라는 라이브러리를 사용하여서 만들었더니 굉장히 쉽게 지도가 생성되고 마커도 찍히길래 금방 할 줄 알았다.
    그것은 나의 오산이었고 수많은 시도를 해봤지만 커스텀한 태그를 만들기 위해서 infowindow라는 것을 사용하고 찾아봤지만 실패했다.
    => 그래서 google-map-react 라는 라이브러리를 싹 갈아엎고 다시 install해서 만들어서 매우 기뻤다..

  • 이렇게 데이터를 map돌려서 각각 라벨마다 알맞은 위도와 경도의 자리로 생성되도록 만들었다.

  • redux를 사용해서 mouseEnter 이벤트가 됐을때 그 대상으로 state를 바꿔주면서 hover 된 리스트의 아이템의 지도상의 태그의 배경색은 검은색으로, 폰트는 흰색으로 바뀌게 만들었다.

  • 태그를 클릭하면 클릭된 태그의 위에 miniContent가 나오도록 코드를 구현했다.
    ContentWrapper에 position을 relative로 주고 ContentModal에 position을 absolute로 주어서 태그의 자리 바로 위에 모달이 뜨도록 만들었다.

아쉬운점 😢

  • 아직은 google map 라이브러리의 완전 기초 단계만 사용한 것 같아서 좀 더 깊은 부분은 적용하지 않았기 때문에 공부해서 많은 기능들을 사용해보고 싶다. 뭔가 억지로 끼워넣은 것 같은 느낌이기에 맞게 짠 코드인지 잘 모르겠다.
    이 부분이 상당히 아쉬운 것 같다.

  • 태그를 클릭했을때 모달창이 생성 되는데 지도의 크기에 알맞게 가려지지 않도록 모달의 위치가 정해지도록 로직을 짜고 싶었지만 그 부분은 아직은 구현하지 못하였다. 그렇기 때문에 태그를 눌렀을때 모달이 일부 가려지는 현상이 발생했다.
    다음 리팩토링 때는 하나의 로직을 만들어 놓아서 부모 크기의 안에서 알맞은 위치에 생성 되도록 하는 코드를 구현해 봐야겠다.


2차 프로젝트를 마치며

- 팀워크란 이런것이 아닐까?

1차 프로젝트때 가장 아쉬웠던 것이 팀원들과의 소통이었다.
그렇기에 이번에는 팀원들과 소통을 가장 중요시 하여 매일 매일 각자의 할 일들과 한 일들을 얘기했다.

이번 프로젝트때 어떻게 딱 코로나 2.5단계 격상 때문에 온라인으로 수업을 진행해서 처음에는 굉장히 걱정했다. 이러다가 혼자하다보면 시너지도 그렇고 의욕도 없을 수도 있고 게을러 질 수 있다고 생각했다.

그래서 우리 팀원들은 매일 개인 카페를 가서 함께 만나서 코드를 짜고 회의를 했다. 그렇게 하다 보니 소통도 원활하게 잘 되고 trello를 사용하여 각자의 파트 분배와 목표치도 계획적으로 세우고 진행할 수가 있었다.

Air BnB를 직접 사용

1주차를 온라인과 카페에서 만나다 보니 문득 함께 합숙을 하면 어떨까 생각이 들었다.
마침 Air BnB를 클론하다보니 직접 사용하여서 경험해보면서 Clone Coding을 하면 재미있고 기억에 많이 남고 좋은 경험이 될 것 같았다.
그래서 당장 숙소를 대여해서 팀원들과 함께 모여서 일주일을 보냈다.

정말 재미있고 너무나 힘이 되는 일주일 이었던 것 같다.
덕분에 서로 모르는 것을 배우고 아는 것들을 서로에게 알려주며 함께 성장하고 함께 소통할 수 있는 기회가 되었다.

앞으로 얼마나 더 이런 기회가 있을진 모르겠지만 한번 더 함께 우리 팀원들과 프로젝트를 하고 싶다. 그만큼 너무나 즐겁고 좋은 시간 이었다.

- 스스로 터득하는 지혜

구글은 블루 오션이다.
항상 모르는 것이 생기면 혼자 해결해 보다가 조금 검색해보다가 물어보는 것이 어느순간 부터 습관이 된 것 같았다.
그리고 어느정도 해결이 되면 바로 넘어가 버리는 것도 너무나 좋지 않은 것 같다.

그래서 이번에는 검색으로 모든 것을 해결해 보고 싶었다.
처음하는 라이브러리 사용과 새로운 개념들은 굉장히 어렵고 시간이 걸렸지만 검색을 직접 해서 모르는 것들을 스스로 공부하여 알아가다 보니 이제는 새로운 것들에 대한 두려움이 조금씩 없어진 것 같다.

어떠한 모르는 것이 와도 세상 모든 사람들이 함께 고민하고 해결해 놓은 많은 것들이 인터넷에 이미 있다.

두렵고 귀찮기 전에 인터넷을 켜고 검색부터 하자.


오늘의 한 줄이 내일의 힘이다.

어제가 후회되지 않는 하루를 보내자.

profile
노래하는 개발자입니다.

0개의 댓글