1차 Project - Life Friends

안준현·2021년 5월 24일
0

project

목록 보기
4/4

const lifeFriends = ["유리님",  "가람님", "세용님", "영건님", "승호님"]
console.log( `${lifeFriends}  여러분들과 함께해서 즐거웠으며 행복한 2주였습니다. 팀 이름처럼 평생친구로 함께 하길~.` )

1차 프로젝트 Overview


  • Clone Site:  라인프렌즈 스토어(Line Friends Store)
  • Project Name: 라이프 프렌즈 (Life Friends)
  • Project Period: 2021.05.10 - 2021.05.20
  • 짧은 프로젝트 기간동안 개발에 집중해야하므로 디자인/기획 부분만 클론하였습니다. (이미지는 무료이미지 사용)
  • 아래의 데모 영상은 모두 backend와 연결하여 최대한 서비스 수준에 맞도록 개발 하였습니다.

데모 영상

Line Friends 데모영상

1차 프로젝트 목표

  1. 배운 기본기 및 react state, props 익숙해지기!
  2. 재활용 가능한 componet 활용하기
  3. 팀원간 커뮤니케이션 능력 향상시키기 (Front & Front , Front & Back )

Front-end/Back-end 소개


개발 인원 및 기간

  • 개발기간 : 2021.05.10 - 2021.05.20
  • 개발 인원 : 프론트엔드 3명, 백엔드 2명
  • 팀원:
    👉 Front End: 유림님(PM), 세용님, 가람님, 나
    👉 Front End: 영건님, 승호님

유림님: 메인 페이지, 상세 페이지 리뷰
세용님: 카테고리 페이지, 상세페이지 제품 상세설명
가람님: 로그인 페이지, 회원가입 페이지, 제품 상세페이지 제품 결제 및 제품 장바구니
나: Nav Bar ,footer,제품 상세페이지 제품 사진 미리보기


적용 기술 및 구현 기능


적용 기술 & 사용한 툴

구현 기능

  • 회원가입 / 로그인
  • 메인페이지
  • Nav bar / Footer
  • 카테고리 페이지
  • 제품 상세 페이지 (프론트 엔드 각자가 하나의 컴퍼넌트 담당)

프로젝트 진행방식


Agile Scrum Methodology

  • Sprint를 활용한 Agile-Scrum work frame 방식으로 프로젝트 진행하였다.
  • 매일 오전에 standup meeting을 하면서 각각의 진행 상황 check, 오늘의 작업 일정 공유 그리고 blocker 공유 하였다. 또한 백엔드와 필요한 정보 및 상황 공유 하였다.

Git & GitHub

  •  Git(VCS)을 활용하여 프로젝트 변경사항 기록 등 버전관리 하였다. 특히 자기만의 branch를 만들어 main(master)에는 영향이 가지 않으면서 프로젝트를 진행 시킬 수 있었다. 이번 프로젝트를 통해서 기본적인 Flow에 따라 Git을 사용할 수 있으며, 올바른 이름의 branch를 생성하고 작업 내용에 대한 commit message를 작성할 수 있다.

  • Github를 이용하여 Git을 사용하는 프로젝트를 진행 할 수 있었으며, code review, reiview 수정 등을 통하여 Github 에서의 기본 workflow 사용하였고 이해 할 수 있었다.

Slack & Trello

  • 실시간으로 정보 공유가 필요한 사항들은 Slack을 활용 하였고, 프로젝트 overall schedule, 각 담당의 진행현황, 체크리스트, blocker, Minutes of Meeting 등은 Trello를 활용 하였다.

Trello

Slack

내가 구현한 페이지 및 기능


  • CRA 초기 세팅 (팀원 다 같이)
  • Nav bar 포함한 Header, Footer
  • map 함수 및 backend와 통신하여 카테고리 메뉴 기능 구현
  • 카테고리 메뉴바 더보기 기능 구현
  • 검색기능 구현 (이번 프로젝트에서는 메뉴이름 검색하여 해당 메뉴로 이동)
  • 로그인 시 저장된 (localStorage) token 사용하여 backend에서 로그인 정보(이름, 이메일) 받아 상태표시 기능 구현
  • 로그아웃 시 token 정보 삭제 및 비로그인 상태표시기능 구현
  • top으로 바로 이동하는 탑버튼 컴퍼넌트화
  • 제품 상세페이지에서 제품 preview 사진기능 구현 (사진 넘기기 / mini사진 mouseover 시 큰화면으로 보여주기)
  • query String을 이용한 카테고리 메뉴와 상품 리스트 페이지 Routing
  • fetch를 사용한 제품 리스트, 카테고리 메뉴, 제품 Previw API 호출, 응답데이터 화면 구현

결과 화면 💝


1) Nav bar(카테고리 메뉴 - 더 보기 및 메뉴호버)

2) Nav bar(검색)

3) Nav bar(로그인 로그아웃)

4) Top button (재사용되는 Component 화)

5) 제품 상세페이지 - 제품 preview 사진

기억하고 싶은 코드 🧠


foundation기간에 검색기능에 대해 시도해보았으나 실제 프로젝트에 적용하면서 더 익숙해지는 계기가 될 수 있었다. 코드는 아래와 같이 작성 하였다.

  • handleSearchValue 함수 선언하여 input에 입력되는 값을 state값으로 변경
  handleSearchValue = e => {
    this.setState({
      searchValue: e.target.value,
    });
  };
  • render 이후에 filter ,include,toLowerCase 메서드를 활용하여 검색필터사용 하였다.
  render() {
    const filteredList =
      this.state.categoryListData &&
      this.state.categoryListData.filter(category => {
        return (
          category.menuName
            .toLowerCase()
            .includes(this.state.searchValue.toLowerCase()) && category
        );
      });
    const filterLength = filteredList && filteredList.length;
  • onChange 에 위에서 선언해준 this.handleSearchValue 를 실행시켜주고 map 을 활용하여 searchbox에 나열되도록 하였다.
              <div className="searchBox">
                <input
                  className="search"
                  type="text"
                  placeholder="검색어를 입력해보세요"
                  onChange={this.handleSearchValue}
                />
                <button className="searchButton">
                  <i className="fas fa-search"></i>
                </button>
                <ul
                  className={`searchListContainer ${
                    this.state.searchValue && filterLength && 'open'
                  }`}
                >
                  {filterLength > 0 &&
                    filteredList.map(category => {
                      return (
                        <li key={category.menuId}>
                          <div>
                            <Link
                              to={`/categories?menu=${category.menuName}`}
                              className="categoryName"
                            >
                              {category.menuName}
                            </Link>

2) Nav Bar - Category bar(feat. 더 보기 버튼)

Nav bar 가 쉬울거 같다고 생각했다. 그런데 생각보다 nav에는 다양한 기능과 특히 메뉴 더 보기, 닫기 버튼과 메뉴 더 보여주기 기능 구현에 애를 먹었다. 구글링을 통하여 방법을 찾았고 해냈을때 1주차때 희열은 아직도 생생하다.

  • 처음 보여줄 메뉴리스트 숫자 지정해주고 ,expanded는 boolean값으로 초기값은 false로 지정
export class CategoryList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      itemsToShow: 10,
      expanded: false,
    };
  }
  • 다음 showMore 함수 선언을 해준다. 여기서 삼항연산자를 사용하여 true 일때 false일때 값을 지정해준다.
  showMore = () => {
    const { eachCategoryList } = this.props;
    this.state.itemsToShow === 10
      ? this.setState({ itemsToShow: eachCategoryList.length, expanded: true })
      : this.setState({ itemsToShow: 10, expanded: false });
  };
  • onClickshowMore 함수 실행 해준다. 그리고 11번째 부터 카테고리 메뉴들을 보여주는 code 입력해준다 (slice, map 사용)
<button
            className="showMoreButton"
            onClick={() => {
              this.showMore();
            }}
          >
            <span className="ShowMoreLess">
              {this.state.expanded ? (
                <span>
                   닫기<i className="fas fa-angle-up"></i>
                </span>
              ) : (
                <span>
                  더 보기<i className="fas fa-angle-down"></i>
                </span>
              )}
            </span>
          </button>
        </div>
        <div className="categoryListNextLine">
          {eachCategoryList &&
            eachCategoryList.slice(11, this.state.itemsToShow).map(menuObj => {
              return (
                <div key={menuObj.menuId} className="categoryMenuNextLine">

3) Nav Bar - Login / Logout(feat. JWT)

이번 프로젝트하면서 가장 기분 좋았던 순간은 바로 백에서 유저 정보를 받아왔을때였다. 로그인을 성공하면 localstorage에 토큰을 저장하고 이를 바탕으로 fetch 를 통하여 user name과 email 정보를 받아 왔다. 그리고 로그아웃버튼 클릭시 localStorage.clear();  하여 로그아웃 기능 구현 하였다.

export class LoginAndLogout extends React.Component {
  isAllInputValid = () => {
    const tokenValue = localStorage.getItem('AUTHORIZATION');
    // fetch('http://10.58.7.181:8000/users/user'
    fetch(`${GET_AUTHORIZATION_API}`, {
      method: 'GET',
      headers: { AUTHORIZATION: tokenValue },
    })
      .then(res => res.json())
      .then(res => {
        if (res.message === 'SUCCESS') {
          localStorage.setItem('user_name', res.user_info.user_name);
          localStorage.setItem('user_email', res.user_info.user_email);
        }
        if (res.result === 'INVALID_USER') {
          return alert('비밀번호 또는 이메일이 잘 못 되었습니다.');
        }
      });
  };

  changeLogout = () => {
    localStorage.clear();
  };

4) 제품 상세페이지 - 제품 미리보기 기능

제품 사진 다음보기, 뒤로가기 버튼 구현, 작은 이미지 마우스 오버시 제품 미리보기 사진 변경 기능 구현

  • goToPreview , goToNext, changePicMouseOver 함수 선언하였다.
  • 뒤로가기, 앞으로 가기 버튼은 마지막 사진이 나오면 (index===4가 되면) 처음 사진(index ===0 )으로 가게만드는게 키였던거 같다.
  • changePicMouseOver 는 마찬가지로 마우스 오버가 되면 index 값을 조정하여 사진을 보여주었다.
  constructor() {
    super();
    this.state = {
      imgIndex: 0,
    };
  }

  goToPreview = e => {
    const { imgIndex } = this.state;
    const {
      PreviewData: { images },
    } = this.props;
    const { className } = e.target;
    const buttonName = className;
    this.setState({
      imgIndex:
        buttonName === 'previousButton'
          ? imgIndex === images.length - 1
            ? 0
            : imgIndex - 1
          : imgIndex === 0
          ? images.length - 1
          : imgIndex - 1,
    });
  };

  goToNext = e => {
    const { imgIndex } = this.state;
    const {
      PreviewData: { images },
    } = this.props;
    const { className } = e.target;
    const buttonName = className;
    this.setState({
      imgIndex:
        buttonName === 'nextButton'
          ? imgIndex === 0
            ? imgIndex + 1
            : 0
          : imgIndex === images.length - 1
          ? 0
          : imgIndex + 1,
    });
  };

  changePicMouseOver = (e, index) => {
    this.setState({
      imgIndex: index,
    });
  };

기쁜 끝맺음 😁


👍 잘된 점 / 좋았던 점 👍

  • 기능 구현/ 결과물 보단 프로젝트를 하면서 소통하고 협업하느 방법을 배우고 프로젝트의 전체적인 흐름을 파악하는 것을 알게 되었다.
  • 팀분위기가 좋았던점 프론트가 힘들어하면 백에서도 나서서 도와주고 백에서 잘 풀리지 않으면 끝까지 믿어주고 부담가지 않게 했던점
  • 에러 중간중간 나타난 lifecycle 문제를 해결하면서 lifecycle 에 대한 이해를 한점
  • 상황에 맞춰서 프로젝트 계획과 방향을 잘 설정한 점 (이것도 결국은 소통)
  • git / github 와 조금 가까워진거 같다. (조금은 친구가 된 거 같은 ^^ 앞으로 더 잘 지내보자.)

🙏 조금 아쉬웠던 점 / 고쳐할 부분 🙏

  • mini project이고 해서 Trello 를 통하여 프로젝트 status 상황 공유가 좀 미흡 했던점. 이번 프로젝트에서는 무리 없었지만 현업 업무를 위해서는 필요하다고 꼭 써야 하겠다.
  • 백엔드와 통신할때 key 값 혹은 대소문자로 한번에 통신이 되지 않았다. 초기부터 세팅을 하고 가는 것을 목표로 해야겠다.
  • 프로젝트 막판에는 merge를 git/ github  가 아닌 직접 하였다.(PM님의 노력으로 문제가 없었다 대박!!짱!) 그래도 오류 혹은 꼬일 수 있는 risk 가 있으므로 꼭 git add . -> git commmit -> git push -> git pull -> git merge master 를 사용해서 하도록 노력 해야겠다.

Afeter Project!

  • 팀프로젝트 시작전에는 내가 진짜 1인분을 할 수 있을까?라는 걱정과 두려움이 있었다. 2주가 지난 지금 그래도 만들어냈다라는 뿌듯함과 함께하는 사람들이 있다는 든든함을 느낄 수 있는 시간 이었다.
  • 내 개발자 인생의 첫 Sprint 였으며 앞으로 나갈수 있는 밑거름이 되었다.
  • 신입 개발자 안준현으로 소개할 수 있도록 도움되어준 우리 life friends team 2주간 정말 행복하고 함께 할 수 있어서 감사했습니다. 🙌🙌🙌🙌🙌

쿠키 사진 ^^



special Thanks 도현 맨토님 (저 자리 들어오면 못나감 질문공세로)

Reference

  • 이 프로젝트는 라인프렌즈 사이트를 참조하여 학습목적으로 만들었습니다.
  • 실무수준의 프로젝트이지만 학습용으로 만들었기 때문에 이 코드를 활용하여 이득을 취하거나 무단 배포할 경우 법적으로 문제될 수 있습니다.

1개의 댓글

comment-user-thumbnail
2021년 7월 12일

평생 친구, 위코드 절친 준현님! 1차 프로젝트 정말 고생 많으셨어요! 준현님과 함께해서 더 즐거웠던 것 같아요!!

답글 달기