(TIL 36일차) 1차 프로젝트 스타일쉐어 후기

빡기·2020년 3월 8일
1

TIL(Today I Learned)

목록 보기
32/43

프로젝트 소개

스타일쉐어 공식사이트

  • 10대 ~ 20대 여성 고객들을 주요 고객으로 삼고 있으며 SNS & 커머스가 섞인 사이트입니다.
  • 패션 정보에 특화된 인스타그램으로 설명할 수 있다. 대부분의 기능이 인스타그램과 비슷한데, 마음에 드는 코디에 좋아요를 누르거나, 팔로워해서 팔로한 사람들의 코디를 따로 볼 수 있으며 해쉬태그 기능 코디 Q/A, STORE 기능 여러가지 기능들을 집합시킨 사이트라고 보면 된다.
  • 처음에는 다른 프로젝트를 맡은 팀들에 비해 기능들이 너무 많아 걱정이 많았지만 의지를 가지고 시작을 했고 백엔드 및 팀장을 맡으신 종민님 덕분에 기능을 전부 구현은 못했지만 최선을 다해 할 수 있는 데까지 구현했습니다

기술적 목표

  • 웹기반의 프로젝트 관리 소프트웨어인 Trello를 이용하여 프로젝트 백로그를 관리했다.
  • 애자일 방법론을 이용하여 매일 스크럼을 통해 수정 사항이나 보완 사항을 수정해 나갔다.
  • 하루하루 각자 개발한 기능에 대해서 stand up meeting을 통해 팀원들과 공유를 하면서 프로젝트를 진행하였다

개발 인원

개발 인원은 프론트엔드 4명, 백엔드 2명


프로젝트 데모 영상

원본

추가기능 수정 자료(팔로잉 리스트)

적용 기술

  • Front-End : React.js, sass, slick, react-modal
  • Back-End : Python, Django web framework, Beautifulsoup, Selenium, Bcrypt, My SQL
  • Common : KAKAO social login, AWS(EC2,RDS), RESTful API

프로젝트에서 내가 맡은 역할

  • 스타일쉐어는 크게 2가지(SNS와 STORE)로 나뉘는데 SNS페이지인 OOTD를 담당했다.
  • OOTD를 담당하기 전 내심 STORE 안에 장바구니 기능 상세페이지 등 이런 부분을 개발해보고 싶었지만 나중에 기회가 분명히 생길 것이라 생각이 들어서 OOTD 페이지에 집중하기로 했다

담당역할

  • CRA 초기 셋팅설정(jsconfig.json, 폰트설정, reset.css, 디렉터리 구조 설정, sass 설정, Router 설정)
  • 소셜 로그인 페이지 및 소셜 회원가입(카카오 로그인 API)
  • 무한스크롤 기능을 이용한 데이터 불러오기
  • 스타일 업로드, 컬렉션 업로드 기능(사진 및 스타일 설명 포함)
  • SNS 안 댓글 등록 및 좋아요, 회원 팔로우 기능
  • Modal 기능 구현(총 3가지로 버전으로 구성)

잘한점

  • 백엔드를 담당하시는 종민님이 OOTD API를 빨리 만들어 주시고 아마존 서버에 올려주셔서 테스트 하기 굉장히 편해 구현속도에 긍정적인 영향을 줬음
  • 같은 팀원들에게 git 사용법이라던지 폴더명 구조 및 BEM 관련 부분을 차분히 설명해준게 도움이 됐다
  • 생각보다 기능이 많았지만 업로드 카드 뿌리기 기능 등 OOTD 관련해서 만들 수 있는 부분을 90%이상 구현했다.

아쉬운 점

  • 나름 Git을 알고 있다고 했는데 알고보니 제대로 알고 있지 않아 작성해놓은 코드를 계속 잃어버리는 경우가 발생했다.
  • 나 뿐만 아니라 팀원들도 git 관련해서 confilct를 해결하는데 있어 익숙하지 않아 코드를 버리는 경우가 발생했다.
  • 처음에 너무 혼자 많은 걸 감당해야 된다는 부담감이 있어 코드 작성하는데 있어 깔끔하게 정리를 못한 점이 너무 아쉽다.
  • 시간을 효율적으로 사용하지 못해 폴더 및 코드 정리하는데 시간투자를 못했다.

해결 및 개선 방법

  • 이번 프로젝트를 계기로 git의 흐름에 대해 정확히 알게 되었고 앞으로는 실수를 줄일 수 있을 것 같다.
  • 백엔드와 소통하는 시간을 좀 더 만들어 정확하고 확실하게 기능을 구현할 필요가 있다.
  • 프로젝트 시작 전 기능에 대해 포기할 기능과 확실하게 구현해야 하는 기능을 팀원들 끼리 상의를 확실하게 하고 개발하는데 집중할 수 있도록 해야겠다.

기록하고 싶은 코드

프로젝트를 하면서 기억에 남는 그리고 절대 잊을 수 없는 코드를 나열해보도록 하자

1. 무한스크롤 기능

  • 처음에 이 기능을 직접 구현해본적이 없어서 막막했지만 생각보다 손쉽게 구현할 수 있어서 너무 기분이 좋았고 재밌는 기능이라 잊을 수가 없었다.
  • 맨위(scrolltop)과 사용자가 스크롤 한 길이(clientHeight) 값 그리고 scrollHeight(총 길이) 값을 이용해서 구현할 수 있었다.
 // 무한 스크롤 구현
  infiniteScroll = () => {
    let scroolHeight = Math.max(
      document.documentElement.scrollHeight,
      document.body.scrollHeight
    );
    let scrollTop = Math.max(
      document.documentElement.scrollTop,
      document.body.scrollTop
    );
    let clientHeight = document.documentElement.clientHeight;
    if (scrollTop + clientHeight + 1 > scroolHeight) {
      this.setState({
        scrolling: !this.state.scrolling,
        preItems: this.state.items,
        items: this.state.items + 25
      });
      this.getCardList();
    }
  };

2. fetch

  • 너무나도 당연한 기능이지만 백엔드랑 통신하는데 있어 중요한 역할을 하는 놈이였다.
  • 이번 기회로 fetch에 익숙해졌고 앞으로도 계속 사용할 함수라 애정이 간다.
getCardList = () => {
    fetch(`${SERVER_URL}/card/dailylook`)
      .then(res => res.json())
      .then(res => {
        this.setState({
          cardList: this.state.cardList.concat(
            res.card_list.slice(this.state.preItems, this.state.items)
          ),
          scrolling: !this.state.scrolling
        });
      });
  };

3. 소셜 API 기능

  • 프로젝트 시작하기 전 소셜 API 기능에 대해 호기심이 너무 많아 따로 공부를 했기에 적용하기 수월 했다.
  • 이 부분은 어느 회사나 어느 프로젝트를 하든 꼭 필수라는 생각이 들어 가장 먼저 공부를 하게 됐다.
  • 카카오 말고도 페이스북 구글도 구현했지만 페이스북,구글은 적용하지 못했다.
 <script src="//developers.kakao.com/sdk/js/kakao.min.js"></script>
// SDK 로드
!window.Kakao.Auth && window.Kakao.init("키");
// 초기설정

// 회원가입 부분 코드
signinWithKakao = () => {
    window.Kakao.Auth.login({
      success: authObj => {
        this.setState(
          {
            kakaoToken: authObj.access_token
          },
          () => {
            fetch(`${SERVER_URL}/user/kakao/sign-in`, {
              method: "GET",
              headers: {
                Authorization: this.state.kakaoToken
              }
            })
              .then(res => res.json())
              .then(res => {
                if (res.user_info) {
                  localStorage.setItem("kakao_id", res.user_info.kakao_id);
                  localStorage.setItem("kakao_email", res.user_info.email);
                  this.props.history.push("/signupinfo");
                }
              });
          }
        );
      },
      fail: function(err) {
        console.log("에러", err);
      }
    });
  };

4. 사진 업로드 기능

  • 이 기능은 구현 하느라 꽤 애먹긴 했지만 생각보다 재밌게 풀어 나갔었던 부분이다
  • 처음에는 구글링하면서 검색을하는데 이해를 잘 못했지만 멘토님들에게 질문한 결과 금방 이해해서 쉽게 풀어나갈 수 있었다.
// 사진을 선택하면 url 경로 따로 파일객체 따로 저장하는 부분
 handleChangeFile = e => {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.readAsDataURL(file);

    this.setState(
      {
        url: e.target.files[0]
      },
      () => {
        this.handlePost();
      }
    );

    reader.onloadend = e => {
      this.setState(
        {
          imgUrl: e.target.result
        },
        () => {
          this.setState({
            visiList: this.state.visiList.concat(this.state.imgUrl)
          });
        }
      );
    };
  };

//  사진을 직접적으로 백엔드와 통신해서 formData 규격에 맞게 전송하는 코드
  handlePost = () => {
    const formData = new FormData();
    formData.append("filename", this.state.url);

    fetch(`${SERVER_URL}/card/upload/image`, {
      method: "POST",
      headers: {
        Authorization:
          "토큰"
      },
      body: formData
    })
      .then(res => res.json())
      .then(res =>
        this.setState({
          resultList: this.state.resultList.concat(res.image_url_list)
        })
      )
      .then(res => console.log(this.state.resultList));
  };

<label for="upload_file" onChange={this.handleChangeFile}>
                    <div className="plus_icon" />
                    <input
                      type="file"
                      id="upload_file"
                      name="myFile"
                      accept=".png, .jpg, .jpeg"
                    /></label>
// 사진이 여러장 업로드 되는데 X버튼을 이용해 하나하나 삭제하는 기능
onClick={() => {
              delete this.state.visiList[idx];
              delete this.state.resultList[idx];
            }}

5. 모달 기능

  • 이거하는데 진짜 2일은 걸린 것 같다.
  • 처음에는 라이브러리를 사용하려고 react-modal을 알아 봤는데 설명를 봐도 따라하지 못해서 포기하고 직접 모달을 구현했지만 z-index와 여러가지 문제로 인해 다시 부트스트랩 모달을 이용해서 구현했지만 예리님에게 참교육을 당한 후에(CSS 문제 때문에 포기했어야함) 결국 react-modal을 열심히 공부하고 다시 재구현 할 수 있었다.
  • 모달때문에 스트레스를 제일 많이 받았지만 스타일쉐어에 있어 중요한 기능이였기 때문에 기분은 굉장히 좋았다.
import Modal from "react-modal";
Modal.setAppElement("#root");

class CardModal extends Component {}
ReactDOM.render(<CardModal />, document.querySelector("#root"));
export default withRouter(CardModal);

6. map 함수 안에서 해당 요소안에서만 기능 활성화 시키기

  • 이것은 옛날에 한 번 해본 기억이 있어 금방했지만 분명히 꼭 다시 사용해야만 할 것 같은 코드이기에 여기에 추가하게 됐다.
 {this.state.select === `${idx} img_hover` ? (
            <div className={`${idx} img_hover`}>
              <div className="like"></div>
              <div className="comment"></div>
              <div className="share"></div>
              <div className="more"></div>
            </div>
         ) : (
          ""
)}

마지막으로

  • 내 인생에 첫 프로젝트이기에 절대로 잊을 수 없는 프로젝트이며 너무 좋은 팀원들과 함께 해서 재밌는 추억이였다.
  • 다음 2차 프로젝트 때도 열심히 하겠지만 이번 1차를 계기로 차근차근 성장한 개발자 내 모습을 볼 수 있었기에 뿌듯했다.
  • 2주라는 시간안에 하기에는 버겁긴 했지만 제한적인 시간 안에서 구현해야 한다는 것도 나름 개발의 연습 중 하나라고 생각이 들었다.
  • 문제가 발생하면 그 순간순간 협의 및 판단을 잘해 옳은 방향으로 잘 나아갈 수 있도록 해야 한다.
  • 그리고 좋은 멘토님들 덕에 문제를 금방금방 해결 할 수 있어서 너무나도 좋았다
profile
Front End. Dev

0개의 댓글