왓챠피디아 클론 프로젝트 🎬

dudgus5766·2021년 9월 19일
3

Projects

목록 보기
1/3
post-thumbnail

✔ 1차 클론 프로젝트가 끝이 났다. 정신 없이 모든 것을 쏟아 부은 2주라고 해도 과언이 아니었다. 특히 개발자가 되는 과정속에서 경험한 첫 프로젝트였기에, 느낀점이 정말 많다.
프로젝트 소개와 더불어 느낀 많은 점들에 대해 자세히 써본다!

앗차피디아(ATCHA PEDIA) 프로젝트


프로젝트 소개


왓챠피디아(WATCHAPEDIA) 는 영화 평가를 기반으로 사용자의 취향을 분석해주고, 이에 따라 추천까지 해주는 서비스이다. 사용자가 영화를 별점으로 평가하고 댓글을 등록하는 서비스를 제공한다.

팀원

  • FE: 김영현, 김영호, 김태수
  • BE: 성우진, 손명희, 이무현

제작 기간

  • 21.08.30 ~ 09.10

기술 스택

개발 도구

  • JavaScript (ES6)
  • React.js
  • React-Router
  • Scss
  • AWS EC2

협업 도구

  • Git/ Github
  • Trello : 전체적인 일정 관리 및 팀원들의 작업 상황 파악
  • Postman : 프론트와 백 간의 소통

주요 구현 기능

✅ 가 되어있는 내용은 직접 구현한 부분

회원가입, 로그인

✔️ JWT 토큰을 이용한 회원가입, 로그인, 로그아웃 기능
✔️ 로그아웃 시 저장된 토큰 삭제하여 메인페이지로 이동

내비게이션 바

✔️ 인기검색어가 포함되어 있는 검색 기능

메인 페이지

✔️ 국가, 장르, 별점 순으로 필터링된 데이터를 통해 레이아웃 구현(캐러셀)
✔️ 동적 라우팅을 통한 상세 페이지 이동
✔️ 조건부 렌더링을 통해 별점 4.0 이상인 영화에 앗차픽 로고 구현

상세 페이지

✅ 모달창을 이용한 코멘트 남기기를 클릭하여 fetch로 서버에 넘기고 불러내 새로고침 시 코멘트에 추가
✅ onMouseEnter, onClick 등의 이벤트를 통해 별점 기능 구현
✅ 유튜브 영상 ID를 통한 URL 연결

마이 프로필

✔️ 로그인한 회원이 마이 프로필 클릭 시, 별점 평가한 영화 개수 구현
✔️ 사용자가 별점 평가를 진행한 목록을 map 메소드를 통해 구현하여 포스터, 타이틀, 본인의 별점 확인 가능

별책 부록

✅ 앗차피디아 로고 및 파비콘 제작


구현 이미지

👉 별점 평가

프로젝트를 진행하면서 가장 많은 시간을 쏟은 컴포넌트가 아닐까 싶다. 처음 왓챠피디아의 상세 페이지를 볼때부터 '저건 꼭 해야지' 했던 기능이었다.
로그인이 안된 상태에서 평점을 매기기를 시도하면 알람 모달창을 통해 회원가입 / 로그인으로 사용자를 이끌었다.


별점은 onMouseEnter,onMouseLeave,onClick 이벤트를 사용해 구현했다. 반으로 자른 별모양의 svg를 일러스트레이터로 직접 만들어 1~5번의 index를 갖는 컴포넌트를 map함수로 별을 만들었다. 이벤트가 적용되면 svg파일의 특성을 활용해 fill로 각 svg를 노란색으로 채워 별점을 평가하게 했다.

반쪽짜리 왼쪽 별에는 onClick={() => onClick(index - 0.5)} 으로 기존 index 값에서 -0.5 한 값을 입력해 0.5단위의 평점을 완성할 수 있었다.

👉 영화별 코멘트

사용자가 로그인을 했을 때 각 영화별로 별점과 코멘트를 저장하여 새로고침이나 다른 페이지에서 다시 해당 페이지로 돌아왔을 때 별점과 코멘트가 남아있는 상태를 구현하고 싶었다.
fetch POST메소드를 통해 저장된 로그인한 사용자의 코멘트를 데이터 쪽으로 넘겨주었다. 그리고 저장된 데이터를 다시 불러와 코멘트를 보여주었다.


  //코멘트 작성 버튼 클릭 이벤트
  addComment = mycomment => {
    fetch(
      `${MOVIES_LIST}/${this.props.match.params.id}/comments`,
      {
        method: 'POST',
        headers: {
          authorization: localStorage.getItem('login-token'),
        },
        body: JSON.stringify({ comment: mycomment }),
      }
    )
      .then(response => response.json())
      .then(this.setState({ modalOpen: false, isComment: true }));
  };

👉 예고편 유튜브 썸네일 이미지화

예고편 컴포넌트는 어떻게 하면 예고편 이미지 URL을 데이터에 넣지 않고 진행할 수 있을까 고민했다. 그러다 갑자기 예전 직장에서 유튜브 썸네일을 제작할 때 각 유튜브마다의 ID가 있다는 사실이 생각났다. ID를 통해 썸네일을 추출하여 레퍼런스로 이용했던 경험이 생각나 검색을 해보니 해당 유튜브의 각 시간 대별 썸네일을 이미지화 할 수 있는 코드가 있었다! (세상에 도움이 되지않는 경험은 없다..)

const thumnail = `https://img.youtube.com/vi/${trailer}/0.jpg`;
const linkVideo = `https://www.youtube.com/watch?v=${trailer}`;

👉 번외(앗차피디아 디자인)

새로운 프로젝트를 시작하면서 로고와 파비콘을 통해 퀄리티를 높이고 싶었다.(어쩔 수 없는 디자이너 출신이랄까..) 내 능력을 조금은 발휘할 수 있었던 앗차피디아 로고와 파비콘!


기억하고 싶은 코드

✍️ 별점에 따른 코멘트

사용자가 영화 상세 페이지에서 별점을 매길 수 있는데 0.5점 단위로 사용자의 평가에 대한 코멘트를 보여줬다.

// 사용자 평가 코멘트
 ratingComment = setRating => {
    const rating = {
      0: '평가하기',
      0.5: '최악이에요',
      1: '싫어요',
      1.5: '별로예요',
      2: '재미없어요',
      2.5: '부족해요',
      3: '보통이에요',
      3.5: '볼만해요',
      4: '재밌어요',
      4.5: '훌륭해요!',
      5: '최고예요!',
    };
    return rating[setRating];
  };

원래의 조건문(if, switch...)을 썼다면 길어졌을 코드를 객체를 통해 간단하게 줄일 수 있었다. 살짝 뒤틀어 생각해보면 객체도 여러가지 방법으로 재밌게 쓸 수 있겠다는 생각이 든다.

✍️ 동적 라우팅을 사용한 페이지 이동

상세 페이지 가장 하단에 있는 비슷한 작품들 리스트에 모두 각 영화 상세 페이지로 이동하는 클릭 이벤트가 설정되어 있었다. 그래서 처음에 시도한 것은 window.location.replace 메소드였다. 어차피 영화에 대한 별점과 코멘트가 초기화되어야 했기 때문에 페이지를 모두 새로고침하는 것이 낫다고 생각했지만 효율성을 생각하지 못했다.

// SimilarThings 컴포넌트
  goToDetail = genre => {
    this.props.history.push(`/details/${genre.movie_id}`);

    /* 화면 전체를 새로고침하는 메소드window.location.replace(`/details/${genre.movie_id}`);
    */
    
//Contents 컴포넌트
     componentDidUpdate(prevProps) {
    if (prevProps.match.params.id !== this.props.match.params.id) {
      window.scrollTo(0, 0);
      this.getData();
      this.setState({
        mycomment: this.state.mycomment,
        clickBtn: false,
        isComment: false,
      }); 
      
      ...중략

window.location.replace 메소드를 사용하게 되면 페이지 자체가 새로고침 되기 때문에 효율적이지 않다. 영화 정보와 포스터, 배경 이미지까지 모든 파일들이 새로고침되기 때문에 동적 라우팅을 사용하여 다시 코드를 작성했다.


배운점 🍿

👏 백엔드와의 소통

이번 프로젝트를 진행하면서 가장 중요하다고 느낀 세가지가 있다.

  • 백엔드가 진행하는 구조 설계에 같이 참여할 것.
  • 컴포넌트 제작 시에 Mock Data를 활용하여 미리 세팅을 해놓을 것.
  • 해당 엔드포인트에 대한 소통을 확실히 할 것.

정확하게 무엇을 하는 지 모른다는 이유로 백엔드에서 구조 설계를 진행할 때 귀 기울이지 않았다가 나중에 프로필 이미지를 넣는 테이블을 놓쳐버렸다. 프론트에서 필요한 데이터가 무엇인지를 처음 설계부터 정확하게 말할 수 있어야 한다.

여러 컴포넌트에서 map함수를 사용하여 데이터를 뿌리는 작업을 진행할 때 무턱대고 하드코딩으로 진행했다. 미리 구조화 된 Mock Data를 통해 진행했다면 작업 시간이 2배는 더 빨라졌을 것이다. 그래도 우진님과의 API 작업을 화면에 입혔을 때의 짜릿함은 잊을 수 없다 🙂

👏 백과 프론트의 경계

이게 프론트 일인가? 백 일인가?

처음 프로젝트를 진행하다 보니 어디까지가 프론트의 영역인지 어디까지가 백의 영역인지 헷갈리는 경우가 허다했다.

하지만 서로가 하는 일을 조금씩 알아가면서 영화에서의 비슷한 장르를 필터링해서 보여주는 데이터같이 무거운 데이터는 백엔드 쪽에서! 검색어에서의 영화 제목 필터링 같은 가벼운 데이터는 프론트 쪽에서! 라는 결론에 도달했다.

결국, 둘 다의 일인 것은 확실하다.

👏 Trello를 통한 일정 관리

프로젝트를 진행함에 있어 가장 어색한 부분이었다. 내가 하고 있는 일 그리고 해야 할 일들을 우리 팀 누구나 볼 수 있다는 사실이 조금은 부끄럽기도 했다. 하지만 시간이 지날수록 Trello는 프론트는 프론트끼리 서로의 진행 상황을 체크하고 막히는 부분에 있어서 도움을 줘서 결국 티켓을 Done으로 보내고, 프론트와 백 사이에서 티켓의 진행 상황 + 구현 이미지를 통해 간극을 조금은 줄일 수 있는 소통의 힘을 가졌다는 것을 알게됐다.

앗차피디아 팀 Trello

profile
RN App Developer

0개의 댓글