위코드 부트캠프에서 클론코딩 프로젝트를 진행하였습니다.
프로젝트가 마무리 되고 느꼈던 것들에 대해 회고하기 위해 포스팅을 남기게 되었습니다.
2023.03.06 ~ 2023.03.17 약 2주간 위코드 1차 프로젝트를 진행하였습니다.
스파오, 닥터마닡, 와이즐리, 이솝 등의 쇼핑몰들 중 하나를 추첨해 클론코딩을 해보는 프로젝트였습니다.
저희가 진행하게된 쇼핑몰은 '와이즐리'였으며 타 쇼핑몰들에 비해 깔끔하고 간결해보였기 때문에 속으로는 나이스를 외치고 있었습니다. (그러나 이것도 쉽지 않음을 느끼고 곧 눈물을 흘림..)
프로젝트는 애자일 방식으로 진행되었습니다.
애자일 방식이란 하나의 완제품을 짧은 기간안에 만들어놓고 점점 살을 붙여가며 제품의 퀄리티를 높여가는 방식입니다.
저희는 이런저런 기능을 전부 제쳐두고 회원가입/로그인부터 결제까지 쇼핑몰에서 꼭 필요한 기능들을 구현하는데에 중점을 두고 프로젝트를 시작했습니다.
팀원은 front 3명, back 2명, 총 5명으로 구성되었으며
그 중 저는 project manager를 겸임하게 되었습니다.
프로젝트 매니저의 역할을 살펴보니 프로젝트의 전반적인 일정 관리 및 진척도에 따른 인원 배분 등 많은 역할을 소화해내야 했습니다.
과감한 결단과 판단이 없으면 팀 전체가 절벽으로 내던져진다는 부담감을 안고 시작하게 되었습니다.
저희가 제일 먼저 시작한 것은 와이즐리 쇼핑몰을 분석한 것이었습니다.
"와이즐리는 어떤 마인드로 서비스되고 있으며 판매 타깃은 누구이고 타 쇼핑몰에 비해 어떤 장점이 있을까?"
분석한 와이즐리는 포장비, 광고비, 사무실 임대료를 걷어낸 "저렴한 가격"이 가장 경쟁력 있는 장점이었습니다.
저렴한 상품 가격은 남녀노소 누구나 원하는 니즈이지만 사실 저희가 실제로 상품을 판매할 수 있는 상황이 아니라서 다른 장점을 찾기 시작했습니다.
그 중 생각한 것이 "웹 사이트를 구성함에 있어 보다 편리하게 바꿔보자" 였습니다.
저희는 쇼핑몰 명칭을 'Weekly'로 정하였으며, 저희 Weekly에서는 다양한 종류의 상품 대신 많은 현대인이 공통적으로 소비하는 '영양제'를 판매하는 사이트로 가정하고 프로젝트를 진행하였습니다.
판매 타깃은 영양제가 필요한 모든 사람. 즉, 신생아부터 남녀노소 전체가 대상이었습니다.
이쯤되니 클론코딩의 목적을 알게 되었습니다.
위코드에서 클론코딩을 시킨 것은 단순히 UI나 기능을 배껴서 구현하라는게 아니라,
어떤 소비자에게 어떤 서비스를 제공할지를 생각하고 그에 맞게 개발해라! 라는 취지가 숨어있었습니다.
저희가 프로젝트동안 구현하게된 기능은 아래와 같습니다.
1. nav/footer
2. 회원가입
3. 로그인
4. 성별/연령 카테고리별 영양제 리스팅
5. 상품 무한스크롤
6. 장바구니 페이지 구현
7. 모달창을 이용한 장바구니 담기
8. 모달창을 이용한 결제
그 중 제가 구현한건 1,4,5,7번이며 이를 중점적으로 포스팅하겠습니다!
wisely 홈화면
와이즐리의 홈화면은 네비게이션과 마우스 호버시 내려오는 카테고리 영역, 네비게이션 하단의 슬라이드로 구성된 배너 이미지가 존재합니다.
weekly 홈화면
우선 저희 페이지명은 weekly로 정했습니다. (wisely 로고나 이미지 등등은 갖다 쓰면 저작권에 걸릴 것 같아서.. 바꿨습니다.)
이제 어떤 부분을 구현했는지 말씀드리겠습니다!
먼저 nav/footer입니다.
네비게이션은 얼추 비슷한 형태로 만드려고 노력하였습니다.
네비게이션 내에 [회원가입/로그인] 버튼은 로그인시 백엔드에서 토큰을 전달받으며 해당 토큰이 로컬스토리지에 들어있는지의 여부에 따라 [마이페이지/로그아웃]으로 변경되도록 하였습니다.
저희 사이트는 위에서 언급했듯이 영양제를 전문으로 판매하는 쇼핑몰이며 성별/연령대에 따라 상품을 나누는 기준이 되므로 Man, Woman, Kids 세 가지 카테고리로만 구현하였습니다.
각각 버튼 클릭시 카테고리에 맞는 상품만 리스팅되게 하려는 목적으로 이렇게 구현하였습니다.
footer는 그저 UI만 참고해 그렸으며 별다른 기능이 없기 때문에 따로 기재하지는 않겠습니다.
두 번째로 성별/연령 카테고리별 영양제 리스팅입니다.
네비게이션에 설명드렸듯이 ALL, MAN, WOMAN, KIDS 버튼 클릭시 해당 카테고리에 맞는 상품이 리스팅됩니다.
각 상품에는 category_id라는 키 값이 있으며, react-router 쿼리스트링을 통해 백엔드 API 요청에 맞는 데이터를 구해 요청합니다.
쿼리스트링의 형태는 이렇습니다.
데이터베이스에 조회할 카테고리 ID(cateId), 조회할 상품의 순번(offset), 조회할 상품 갯수(limit)입니다.
/cateCode/{cateId}?offset={offset}&limit={limit}
세 번째로 무한스크롤을 적용하였습니다.
최초 메인페이지에 보여지는 상품 수는 10개 입니다.
이후 스크롤을 내려 페이지가 특정 위치까지 도달했을 때 상품 조회 API를 호출하여 불러온 상품을 계속해서 보여주는 방식입니다.
무한스크롤에 대한 자세한 방식은 별도로 포스팅하도록 하겠습니다.
마지막으로 모달창을 이용한 장바구니 담기입니다.
메인 페이지에서 카테고리별로 리스팅된 상품에 장바구니 아이콘이 같이 달려있습니다.
해당 아이콘을 클릭할 때 모달창이 노출되며, 장바구니에 담을 수량을 선택할 수 있습니다.
장바구니에 상품을 담을 경우 네비게이션 우측에 있는 장바구니 아이콘에 담겨있는 상품 숫자가 카운팅됩니다.
*짤막한 결과영상
어려웠던 점, 아쉬웠던 점, 잘했던 점
프로젝트를 진행하며 벽을 느꼈던 순간이 종종 있었습니다.
어려웠던 점
먼저, 무한스크롤을 구현할 때 너무나 힘들었습니다.
저는 Weekly는 페이지 이동 없이도 상품을 지속적으로 리스팅하기 위해 무한스크롤로 상품 리스팅을 구현해봐야겠다! 라고 당차게 결정하였지만 현실은 암담했습니다.
많은 무한스크롤 포스팅을 참고하며 구현하려고 노력했었는데,
[페이지 스크롤이 얼마나 내려왔다] 에 대한 값을 구하는 것이 정말 어려웠습니다.
엘리먼트의 위치를 파악하기 위한 Element.getBoundingClientRect()
react에서 dom을 조작하기 위한 useRef 등
위 두 가지를 섞어가며 스크롤 계산 값을 구하려했지만 쉽지 않았습니다.
이 때 위코드 멘토님께서
[document.body.scrollHeight, document.documentElement.scrollTop]
이 두 가지로 스크롤 계산값을 구하는 방법을 알려주셨습니다.
아마 도움을 받지 못했다면 일정상 포기하고 페이지네이션으로 상품 리스팅을 구현했을 것 같습니다.
그래도 getBoundingClientRect()나 useRef 등에 대해 많은 것을 알게되었습니다.
이는 별도로 포스팅하도록 하겠습니다^^
아쉬웠던 점
프론트 <-> 백 API 통신을 진행하는 동안 몇 번의 고비가 있었습니다.
엔드포인트가 변경되기도 하고 프론트를 구성하는데 필요한 데이터를 깊게 생각하지 않아 추후에 데이터 추가를 요청드린 일도 있었습니다.
이런 과정이 생각보다 시간이나 노력이 많이 들어가는 과정이었는데
초기에 명확하게 프론트에서 필요한 데이터와, 그에 따른 응답이 어떻게 생겼는지, 엔드포인트는 어떻게 되는지를 확실히 잡고 갔었어야 이런 상황을 피할 수 있을 것 같습니다.
이 부분은 프로젝트를 진행하며 조금 아쉬운 부분이 되었습니다.
또한 마크업 스킬이 약간 아쉬웠습니다.
욕심같아서는 페이지 리사이즈에 따라서 UI가 변경되거나 반응형 디자인이 추가되었으면 했지만, 생각보다 기능구현 하는데에 시간을 많이 쏟게 되어 이런 부분을 놓쳤던 것 같습니다.
마크업에 대한 욕심을 충족시키려면 스스로가 마크업 스킬을 더더더더더욱 갈고 닦아야 할 것 같습니다.
잘했던 점
위에서 기재했던 위기상황(?)들에 대해서 마크업을 제외하고 빠르게 대처가 된 것 같습니다.
프로젝트 매니저로써 프로젝트가 끝나기 전까지 세부적인 기간이나 플랜을 계속해서 생각해야 했습니다.
그런데 중간중간 커밋한 소스가 다른 영역을 침범해 충돌이 나거나, 아예 파일이 삭제되어버리는 일도 있었습니다.
다행히도 저는 타 영역에서 개발 경험이 있는 3년차 중고이기때문에 다른 팀원들보다 git, github를 다루는데 익숙해져있었고, 이런 경험을 살려 코드 충돌로 일어나는 어지간한 상황은 빠르게 대처했었던 것 같습니다.
마무리하며
이번 프로젝트경험을 기반으로 스스로의 부족함과 기대치를 동시에 느낀 것 같습니다.
부족하고 아쉬웠던점을 통해 "더 좋은 서비스를 구현하려면 어떻게 해야하는가?"에 대해 많은 고민을 하게 되었고 다음 프로젝트 때 이를 녹여 더 높은 품질의 서비스를 내놓을 수 있을 것 같다는 생각이 들었습니다.
긴 글 읽어주셔서 감사합니다.
이만 포스팅을 마치도록 하겠습니다 ^^