#MEGABOXU : 2차 프로젝트 회고록

harry·2022년 11월 11일
2


🍿 프로젝트 소개

  • 영화 예매 사이트인 메가박스(MEGABOX)를 참고
  • 팀 이름 : 메가박수(MEGABOXU)
    처음엔 cgv를 참고하려 했지만 메가박스의 UI가 훨씬 마음에 와닿아 메가박스로 참고 사이트를 변경하고
    팀 이름도 마침 내 손에 들려있던 박수 장난감 덕분에(?) 메가'박수'로 결정되었다ㅎ
    가끔 동기들이 장난으로 메가'보수'라고 놀렸지만.. 우리가 '박수'를 강조하면 그만인 것!

👥 개발 인원 및 기간

  • 개발 기간 : 2022년 06월 07일 ~ 2022년 06월 17일
  • 개발 인원 : Frontend 4명, Backend 2명

🛠 기술 스택

  • Front-End : HTML/CSS, React (React-Router, React-Router-DOM), Styled-component
  • Back-End : Python, Django

🗣 협업 도구

  • Trello
  • Slack

1차때와 같이 협업 도구로 Trello와 Slack을 사용했다.
1차 프로젝트때 사용했던 도구들을 2차때도 사용하니 전에 부족했던 점들을 보완하며 훨씬 유용하게 툴들을 사용했던 것 같다.


🎬 프로젝트 시연 영상


🏗 구현 항목

필수 구현

메인페이지, 소셜로그인 / 회원가입, 무비 리스트, 무비 상세, 예매페이지, Nav / Footer

+)
2차 프로젝트때는 1차 때보다 시간이 (하루..) 부족하기도 했고 다가오는 기업협업으로 인해 어수선한 분위기이다 보니 필수 기능도 간신히 구현할 수 있어 추가 기능 구현은 상상도 할 수 없었다..


👩🏻‍💻 내가 구현한 부분

2차 프로젝트에선 1차 때 해보지 않았던 기능과 페이지들을 맡았다.

1차 프로젝트때 같은 팀원이 Nav바 때문에 골머리 썩는 모습을 옆에서 보며 그래도 많은 성장을 할 수 있는 기능이 많은 것 같아 나도 한 번 해보고 싶다는 생각을 했는데 운 좋게 Nav바를 맡게 되었다.

드롭박스

메가박스의 드롭박스는 두 가지 스타일이 있었다.
hover를 했을 때 밑에 나오는 드롭박스와 아이콘을 클릭 했을 때 나오는 드롭박스
아이콘을 클릭 했을 때 나오는 드롭박스를 구현하는 데에는 큰 어려움은 없었다.
드롭박스마다 컴포넌트를 만든 후 onClick을 했을 때 해당 컴포넌트를 제외한 나머지 컴포넌트에 false 값을 주어 해당 컴포넌트만 보여지도록 구현하였다.

const activeSiteMap = () => {
    setSiteMapActive(prev => !prev);
};

const activeSearchBox = () => {
    setSearchActive(prev => !prev);
};

const activeLoginBox = () => {
    setLoginActive(prev => !prev);
};

const modalOpen = () => {
    setIsModalOpen(true);
};

<GiHamburgerMenu
   className="menu"
   onClick={() => {
     activeSiteMap();
     setSearchActive(false);
     setLoginActive(false);
   }}
/>

두 번째는 hover했을 때 나오는 드롭박스, 이거는 구현하면서 1차 프로젝트 때 Nav 담당했던 동기들 코드를 많이 참고했지만 역시 어려웠다. 대부분 동기들을 ul과 li 태그를 이용하여 드롭박스를 구현했는데 나는 ul과 li가 왜 이렇게 어렵게 느껴지는지 모르겠다..
먼저 드롭박스를 보여주는 함수와 숨기는 함수 두 가지를 만들었다

const activeDropBox = () => {
    setNavActive(true);
  };

  const hideDropBox = () => {
    setNavActive(false);
  };

이후 ul 태그에 onMouseOver일 때 activeDropBox함수가, onMouseOut일 때 hideDropBox 함수가 실행되도록 코드를 작성했다.

<ul onMouseOver={activeDropBox} onMouseOut={hideDropBox}>
  {NAV_TITLE_LEFT.map(navLeftTitle => (
    <NavLeftMenu navLeftTitle={navLeftTitle}
                 key={navLeftTitle.id}
                 navId={navId}
                 hoverOn={hoverOn}
                 logoChange={navi === location.pathname} />
   ))}
</ul>

맞다.. 딱 봐도 깔끔하고 가독성 좋은 코드는 저어어언혀 아니다..
Nav는 시간에 쫓겨 아쉬움이 정말 많이 남는 코드여서.. 시간될 때 꼭! 리팩토링할 예정이다..!

무비차트

fetch api의 GET 방식으로 백엔드 DB로부터 데이터를 받아와 state에 넣어준 뒤 slice 메서드를 사용해 1위부터 5위까지의 영화만 보여지도록 구현하였다.

const [listValue, setListValue] = useState([]);

useEffect(() => {
    fetch(`http://10.58.1.162:8000/movie`, {
      method: 'GET',
    })
      .then(res => res.json())
      .then(result => {
        setListValue(result.result);
      });
    //result.result <- 객체 안의 배열로 들어가는 어쩌구
  }, [location.search]);

listValue.map(
              id =>
                id.movie_id === posterValue && (
                  <img src={id.poster_url} key={id.id} alt="포스터" />
                )
            )

메인에서 페이지 넘어갈 때 Nav바 색상 변경

이 기능은 CSS 부분에서 삼항연산자를 사용하여 페이지에 따라 Nav바 색상이 바뀌도록 구현해주었다.

background-color: ${({ logoChange }) =>
    logoChange ? 'rgba(0, 0, 0, 0.3)' : 'white'};
  border-bottom: 1px solid
    ${({ logoChange }) => (logoChange ? 'rgba(255, 255, 255, 0.2)' : '#342461')};

Movie List

1차 프로젝트 때 상품 리스트 페이지가 제일 어려운 페이지로 동기들 사이에서 소문(?) 아닌 소문이 있었는데 2차 때는 내가 리스트 페이지를 맡게 되었다.
각자 담당 페이지가 정해지고 리스트 페이지가 됐다는 걸 알게 되었을 때 많이 두려웠지만 성장의 기회로 삼고.. 열심히 해보기로 했다..!

페이지네이션

페이지네이션 기능은 1차 때 같이 프로젝트를 진행했던 팀원의 코드를 거의 참고하였다.
처음 데이터를 리스트업 할 때 12개의 데이터만 보여지도록 state를 설정한 뒤 '더보기' 버튼을 클릭할 때마다 데이터가 4개씩 추가로 보여지도록 함수를 작성했다.

  const [query, setQuery] = useState(12);

  const seeMore = () => {
    setQuery(query => query + 4);
    const limit = query;
    const queryString = `&offset=0&limit=${limit}`;
    setStateValue(prev => {
      return { ...prev, offValue: queryString };
    });
    setStateValue(prev => {
      return { ...prev, searchValue: '' };
    });
  };

필터 기능

useEffect와 Query String을 활용하여 선택된 값들을 state에 보내 필터에 맞는 데이터가 보여지도록 구현하였다. query 작성 역시 1차 프로젝트 함께 진행했던 동기 코드를 참고하여 구현하였는데 너무 어려웠다.

  useEffect(() => {
    const queryString = `?${
      stateValue.filterValue ? `&released=${stateValue.filterValue}` : ''
    }${stateValue.searchValue ? `&search=${stateValue.searchValue}` : ''}${
      stateValue.offValue ? `${stateValue.offValue}` : ''
    }`;
    navigate(queryString);
  }, [stateValue, navigate]);

  const filterBtn = value => {
    setStateValue(prev => {
      return { ...prev, filterValue: value };
    });
    setStateValue(prev => {
      return { ...prev, searchValue: '' };
    });
  };

검색 기능

검색 기능은 위의 필터 기능과 거의 동일하게 진행되었다.
e.target으로 value을 가져와 Query String에 동적으로 값을 넣어 검색 기능 구현했다.

  const searchBtn = e => {
    e.preventDefault();
    const searchValue = e.target.search.value;
    setStateValue(prev => {
      return { ...prev, searchValue: searchValue };
    });
    e.target.search.value = '';
  };

👏🏻 프로젝트를 진행하며 느낀점

하.. 이번 프로젝트는.. 정말..
1차 프로젝트 때 같은 팀이었던 동기 둘과 사전스터디부터 같이 하던 동기가 같은 팀이라 마음은 편했지만.. 프로젝트 구현하는 과정이 너무 힘들었다.
styled-component를 처음 쓰다보니 어떻게 해야할지 적응도 막막했기에 코드가 너무 너무 너무 더러워졌다..
프로젝트를 진행하는 내내 나의 더럽고 끝도없이 긴 코드들이 꼴보기 싫어 뒤집어 엎고 싶은 심정이었지만..
기한 내에 어떻게든 프로젝트를 끝마쳐야했기 때문에 일단은 급한대로 계속 진행했다.
(아마 팀 프로젝트가 아닌 나 혼자 하는 프로젝트였으면 뒤집어 엎었을 수도..)
2차 프로젝트는 반드시 리팩토링을 하겠다고 다짐했다..!
그래도 기업협업 관련하여 정신 없던 와중에도 우당탕탕 프로젝트는 진행되었고 무사히(?) 끝마칠 수 있었다. 여러모로 아쉬움이 많이 남는 프로젝트였지만 그만큼 나름의 애정도 많이 가는 프로젝트였던 것 같다.

함께 고생한 우리 팀원들 그동안 너무 고생 많았어요..! 언제나 어디서나 제가 많이 응원합니다 화이팅!!💪

0개의 댓글