Upoon Gallery 프로젝트

이종민·2021년 7월 31일
0

Project

목록 보기
2/2
post-thumbnail

2차 프로젝트 Github <= 클릭 시 'github' 로 이동

2차 프로젝트 시연 영상<= 클릭 시 'Youtube' 로 이동

Frontend
이종민 - 로그인, 제품 상세 페이지, Nav/Footer
이재현 - 메인 페이지, 작품 리스트 페이지

Backend
김예랑 - 카카오 소셜 로그인 구현 및 장바구니 기능 구현
최명준 - 제품리뷰 (S3 Storage) 구현
최현정 - 제품 상세페이지 (필터링 포함)

프로젝트 기간
2021년 7월 19일 ~ 7월 30일

적용 기술스택
Front-End : React Hook, Styled-Component
Back-End : Python, Django, MySQL, Bcrypt, pyJWT, Docker, s3
Common : AWS(EC2,RDS), RESTful API

오픈갤러리 를 기반으로 하는 그림렌탈 사이트를 만들는 프로젝트

사이트 기획의도

이번 프로젝트 사이트의 기획의도는 기본적인 토대는 기본이 되는 사이트의 구성과 디자인을 기준으로 하며 1차 프로젝트 보다 프론트엔드 인원이 적고 새로운 기술을 적용하여 개발하는만큼 새로운 시도 보다는 기존 사이트를 비슷하게 만들되 인원과 시간의 한계를 고려하여 일부 수정을 거쳐서 새로운 기술을 배워나가는 마음으로 만드는 것을 목표로 하였다.

- 기획 시 사이트 구성
회원가입 / 로그인 / 작품 리스트 / 작품 상세보기 / 카트

위와 같은 구성으로 사이트를 구성하였다. 그러나 이는 판단 미스 기획이었다.
우리 프론트엔드 쪽에서 이전에 사용해 보지 않은 React Hook 과 Styled-Component 에 익숙해지는 시간을 제대로 판단하지 못했으며 2명 밖에 되지않는 프론트 인원을 제대로 고려하지 못한 기획이었다.
지금 회고하면 너무 과신했다고 생각한다.

- 프로젝트 진행 중 구성 수정안
로그인 / 작품 리스트 / 작품 상세보기

회원가입은 소셜 로그인을 이용해 로그인을 함으로 회원가입 페이지는 시간 관계 상 과감히 삭제하였다.
장바구니를 삭제한 이유는

  • 프론트엔드 맴버인 저와 재현님은 모두 이전 프로젝트에서 장바구니 부분을 구현하였기 때문에 둘 다 이전에 해보지 않은 새로운 페이지를 우선적으로 하고 싶어함

  • 기업협업 및 새로운 기술을 설명하기 위한 세션 그리고 우리가 이해하기 위한 시간을 고려하여 장바구니까지 구현하기에 시간이 부족

위와 같은 이유로 장바구니 역시 삭제되며 상당히 심플한 페이지 구성이 되었다.

이번 프로젝트에서 시간과 개개인의 능력을 구성하여 처음부터 기획을 실현가능하게 해야한다는 것을 좀 느꼈다.

👍 프로젝트를 마친 느낌

내가 맡은 파트는 로그인(카카오API 사용), 제품 상세 페이지, Nav, Footer 이렇게 4가지부분을 맡았다.

1차 프로젝트를 성공적으로 마무리 하였고 2차 프로젝트 역시 상당히 자신감이 올라간 상태로 시작하였다. 조원 분들도 면식이 있는 좋은 분들이라 상당히 의욕적이었다. 그래서 1차보다 뭔가 더 많이 구현하고 싶고 1차 프로젝트에서 하지 않았던 것을 하고 싶다는 의욕이 앞서있었다.

프론트엔드가 다른팀보다 적은 2명이기에 상당히 부담은 있었지만 이전과 달리 2명이기에 더 좋았던 점도 많았다. 2명이기에 합의점을 찾는 것이 더 쉬웠고 둘 모두 1차 프로젝트에서 동일한 부분을 구현했었기 때문에 서로 최대한 1차와 다른 것을 함께 구현해보기 위해 기존 사이트에서 일부 변경하여 몇몇 부분만 다르고 최대한 같은 것을 구현해보았다.

백엔드 분들과의 협업 역시 1차 프로젝트 때처럼 상당히 편하고 좋았다. 백엔드 분들께서 둘 밖에 없는 저희 프론트를 위해 최대한 데이터 양식도 맞춰주셨고 필요한 상황에 서버도 켜주시면서 프로젝트가 원활히 진행될 수 있게 많이 배려해주셨다.

제가 조금만 시간을 더 썼어도 장바구니 부분과 리뷰에 대한 페이지를 만들 수 있었을텐데 이 부분에서 저 부분까지 이미 구현해주신 백엔드 분들에게 미안한 마음도 있었고 내 개인적으로도 아쉬운 부분이다.

그래도 큰 Blocker 없이 우리가 원하는 결과물을 어느정도 구현해낸 것에서 만족을 하며 이게 위코드에서의 마지막 프로젝트라고 생각하니 아쉬운 생각도 있었다. 좋은 팀원분들 덕분에 마지막까지 2주가 어떻게 간지 모르게 재미있게 프로젝트를 진행해서 너무 좋았다.

개인적으로 프로젝트를 거치면서 정말 많은 개인적 성장을 느꼈다. 이런 자세한 내용은 위코드에 대한 마지막 회고를 하면서 적어보겠다. 소감은 여기서 마무리하고 내가 구현한 기능에 대해서 적어보겠다. 여기서 Nav, Footer 는 별다른 기능이 없으니 설명을 넘기겠다.

✅ 로그인 페이지


로그인는 회원가입이 없으므로 외부 API를 사용해서 로그인하는 방식으로 하였다. 카카오API 를 사용하였으며 위의 gif 파일은 카카오 계정을 통해 로그인을 하는 것을 보여준 것이다.

로그인의 구현 방식을 설명하자면 카카오에서 받은 토큰을 백엔드 쪽으로 보내 다시 저희 사이트에 맞는 토큰으로 다시 받는 방식이다.

이전에는 사이트 자체에서 회원가입으로 정보를 받아서 서버에 등록한 뒤 로그인을 하는 방식을 구현했었지만 소셜 로그인은 카카오 Developer 페이지에서 자바스크립트 키를 받아서 그걸 이용한다. 코드는 아래와 같다.

//index.html
<head>
    <script src="//developers.kakao.com/sdk/js/kakao.min.js"></script>
    <script>
      window.Kakao.init('본인이 받은 js key');
    </script>
</head>

index.html 에 위의 코드를 넣어준다.

//Login.js

const { Kakao } = window;
const history = useHistory();

  const handleKakaoLogin = () => {
    Kakao.Auth.login({
      success: function (authObj) {
        fetch(LOGIN_API, {
          method: 'GET',
          headers: { Authorization: authObj.access_token },
        })
          .then(response => response.json())
          .then(result => {
            localStorage.setItem('access_token', result.access_token);
            alert('로그인 성공');
            history.push('/');
          });
      },
      fail: function (err) {
        alert(JSON.stringify(err));
      },
    });
  };

로그인에서 사용하는 함수는 위와 같다. 이 이후는 백엔드에서 맞춰주었기에 이번에 로그인 구현은 상당히 편하게 진행되었다.

✅ 제품 상세 페이지

개인적으로 제품 상세 페이지에는 상당히 많은 기능과 원본 사이트와 약간 다르게 하기 위해 신경을 썼다.

위의 gif는 리스트 페이지에서 제품 상세페이지에 들어왔을 때 그 제품 아이디의 이미지들을 서버에서 제품의 이미지 개수에 따라 width 가 자동계산되어 슬라이드가 구현된다.


작품 걸어보기 기능으로 클릭 시에 버튼색과 동일한 색으로 배경색이 변하며 어두운 버튼색으로 갈수록 하얀색 체크로 바뀌게 만들었다.

  const [colorIndex, setColorIndex] = useState('0');
  const [btnArr, setBtnArr] = useState([
    { id: 1, color: '#f5f5f5', src: '' },
    { id: 2, color: '#dbdbdb', src: '' },
    { id: 3, color: '#e3e0d7', src: '' },
    { id: 4, color: '#c8d0d4', src: '' },
    { id: 5, color: '#a5a5a5', src: '' },
    { id: 6, color: '#943130', src: '' },
    { id: 7, color: '#353535', src: '' },
  ]);

  const colorChange = id => {
    const newArr = btnArr.slice();

    for (let i = 0; i < newArr.length; i++) {
      if (i !== id) {
        newArr[i].src = 'none';
      } else if (id === 5 || id === 6) {
        newArr[id].src = '하얀 체크 이미지';
      } else if (i === id) {
        newArr[i].src = '검은 체크 이미지';
      }
    }
    setBtnArr(newArr);
    setColorIndex(id);
  };

          <SelectColor>
            {btnArr.length !== 0 && (
              <BackgroundBox color={btnArr[colorIndex].color}>
                <Paint>
                  <img src={imageId.image_urls[0]} alt="" />
                </Paint>
                <img src="거실 배경 이미지" alt="" />
              </BackgroundBox>
            )}
            <ColorPicker>
              <ColorPickerText>배경색</ColorPickerText>
              <BtnContainer>
                {btnArr.map((btn, idx) => (
                  <Btn
                    key={idx}
                    onClick={() => colorChange(idx)}
                    color={btn.color}
                    src={btn.src}
                  ></Btn>
                ))}
              </BtnContainer>
            </ColorPicker>
          </SelectColor>

버튼색을 구현하기 위한 코드는 위와 같다. 버튼에 대한 id와 색정보를 가진 state와 colorIndex 라는 state를 만들어주고 아이디 값을 비교하여 선택된 버튼의 색 정보를 div 의 배경색으로 전달하는 방식이다. 위의 슬라이드 width 계산에서도 유용했지만 이 부분에서 styled-component 에 props 를 전달하여 색변경을 하는 방식을 사용했는데 이 것이 1차에서 SASS를 사용할 때와 달리 굉장히 편했다.

리뷰 등록 기능은 Modal 창으로 구현하여 데스크탑 내 이미지와 코멘트를 FormData 형식으로 서버에 전달한다. 이 과정을 백엔드와 함께 확인해보니 이미지는 아마존의 서버로 업로드 되고 comment는 리뷰를 담당하시는 백엔드 분의 서버로 들어가는 것을 확인하였다.

다른 작품 보기 부분은 같은 작가의 작품들로 sorting 된 이미지들을 서버에서 받아서 표시하는 방식이다. 이 부분은 원본 사이트와 다르게 단순히 제가 벽돌형 레이아웃을 구현해보고 싶어서 변경을 하였다. 아래는 원본 사이트의 구성이다.

서버 내의 작품 수가 없는 우리 프로젝트의 특성 상 벽돌형 레이아웃이 좀 더 꽉 차게 느껴지는 경향이 있어서 변경을 하였다.

0개의 댓글