MONAWE 페이지 소개 및 선정 이유
소개
국내 문구 Commerce 사이트 [모나미](https://www.monamimall.com/w/main.do) 클론 프로젝트
선정 이유
문구 Commerce 사이트로 디자인 요소가 적절히 들어가 있으면서 쇼핑몰의 기본기능에 충실하여 선정하게 되었습니다.
- 이 프로젝트는 모나미 사이트를 참조하여 학습목적으로 만들었습니다.
- 실무수준의 프로젝트이지만 학습용으로 만들었기 때문에 이 코드를 활용하여 이득을 취하거나 무단 배포할 경우 법적으로 문제될 수 있습니다.
- 이 프로젝트에서 사용하고 있는 사진 대부분은 위코드에서 구매한 것이므로 해당 프로젝트 외부인이 사용할 수 없습니다.
- 클론 프로젝트는 전적으로 개발에 집중하기 위하여, 기획이나 디자인 시간 절약을 위해 타 사이트를 참고하되 로직은 직접짜고, 레이아웃을 참고하는 정도로만 했습니다.
개발 기간 및 인원
- 개발 기간: 2020/10/19 ~ 2020/10/30 (2주)
- 개발 인원
. Fontend: 김수연(🦸♀️PM), 김한나, 백경민, 이지영 (+ 쩜오론트 민경민님👍)
. Backend: 민경민, 황채영
적용 기술
- Frontend: React.js(Class), React-router, React-slick, Sass
- Backend: Django, MySQL, bycrypt, PyJWT, cors-headers
- 공통: git / github, Postman, Trello
구현 기능
- 회원가입, 로그인/로그아웃
- 메인페이지(MyCurator, 상품 검색기능, 디자인 요소)
- 리스트페이지 (신상품/가격순 필터기능 및 페이지네이션)
- 상세페이지 (장바구니추가, 찜목록추가, 상품댓글)
- 마이페이지(최근본상품/장바구니/배송지관리)
프로젝트 영상
개인별 담당 기능
김수연
- NavBar MenuTab 및 Transition 구현
- Login User 정보 활용(localStorage), Navbar User Icon 생성
- 유저 툴 박스 구현 (최근 본 상품: fetch get 사용)
- 사이트 검색 기능 구현
- 메인페이지 모나위 스토리 Slick-slider 구현
- 마이페이지 구현
김한나
- 상품리스트페이지 SubNav 기능 구현
- fetch를 사용하여 Back-End에 호출하하고 응답받은 데이터를 구현함.
- 상품 filter 기능구현.
- Pagenation.
- qurey string과 path로 동적 라우팅 구현.
- map을 사용해서 jsx 리턴하여 목록 구현.
백경민
- 회원가입 입력 값 validation check 기능구현
- 로그인 기능 구현
- 메인페이지 배너 슬라이드 구현
- 장바구니 추가/삭제/수량변경 기능구현
✔️ 이지영
- 상품 디테일 페이지
- fetch (GET, POST)를 사용하여 백엔드와 통신
- 댓글 기능 구현 (map을 사용하여 jsx return)
- query string 사용하여, 상품리스트에서 상세 페이지로 이동
- 메인페이지의 추천 상품 component 제작 (hover를 이용한 transition 기능 구현)
민경민
- 회원가입 / 로그인 엔드포인트 작성
- JWT 발행, 데코레이터로 검증
- 주소지 CRUD 엔드포인트 작성
- 주소지 CRUD React component 작성
- 상품 리스팅 / 검색 / 필터링 / 페이지네이션
- 상품 상세 정보 엔드포인트 작성
황채영
- 장바구니 CRUD 엔드포인트 작성
- 최근 본 상품 CRUD 엔드포인트 작성
- 찜리스트 CRUD 엔드포인트 작성
주의사항
Team Rules✨
어?
하지말기
- 최종발표 날 모나미룩 입고오기!
- PM님을 마음 속에 품고살기
진행방식
github를 이용해 Team으로 개발하는 방법을 학습하고자 했습니다.
협업툴로 Trello를 사용하였고, 1일 1회의 스탠딩 미팅을 진행하였습니다
10.19~10.30(11일 간) 1주에 한 스프린트로 진행하는 scrum 방식으로 프로젝트를 진행하였습니다.
내가 구현한 부분
- 상품 디테일 페이지
- 메인 페이지의 추천제품 component
기억하고 싶은 코드
componentDidMount() {
fetch(`${API_KM}/product/${this.props.match.params.id}`, {
method: "GET"
})
.then(res => res.json())
.then(res => {
console.log("productinfo", res);
this.setState({ productInfo: res.data.product_info }, () => {
fetch(`${API_KM}/order/recent`, {
method: "POST",
headers: {
Authorization:
localStorage.getItem("token")
},
body: JSON.stringify({ product_id: this.state.productInfo.id })
});
});
});
fetch를 이용하여, 상세페이지의 api를 전달받고, post method로 최근본상품에 데이터를 추가하는 로직이다.
- config.js 를 통해 반복되는 api 주소를 import 해서 간편하게 사용했다.
- this.props.match.params.id 를 통해, product number를 가져와, 해당 api를 fetch 했다.
- fetch 가 비동기적으로 일어났기 때문에 call back 함수를 사용하여, productInfo 를 setState 하고 난 뒤, post로 '최근본 리스트'에 product id 정보를 넘겨줄 수 있도록 했다.
handleIncreament(pr) {
const { price } = this.props.productInfo;
pr.price = price;
const chosenProduct = [...this.state.chosenProduct];
pr.amount++;
pr.price = Number(pr.price) * pr.amount;
this.setState({ chosenProduct });
}
handleDecreament(pr) {
pr.price = this.props.productInfo.price;
const chosenProduct = [...this.state.chosenProduct];
const amount = pr.amount - 1;
pr.amount = amount < 0 ? 0 : amount;
pr.price = Number(pr.price) * pr.amount;
this.setState({ chosenProduct });
}
handleDelete(pr) {
const chosenProduct = this.state.chosenProduct.filter(
item => item.idx !== pr.idx
);
this.setState({ chosenProduct });
}
상품의 갯수를 더하고, 빼고, 삭제하는 함수이다.
- 변수를 pr로 받고, 이벤트가 발생할때마다 pr의 amount를 1 증가시키거나 감소시킨다. price 가 string으로 들어오기 때문에 number로 형변환을 해주어 amount 와 곱한 값을 새로운 가격으로 설정해주었다.
- amount 가 음수가 되지 않도록, 0보다 작을 경우에는 0으로 세팅하는 로직을 추가해주었다.
- delete의 경우, product의 idx를 비교하여 이벤트가 일어나는 아이템이 아닌것만을 filter 하는 로직을 사용했다. idx 값을 넘겨주는 방법을 배웠다.
크게 이 두가지의 기능을 구현하면서 처음으로 백엔드와의 통신을 시도해보고, routes 에 대한 이해를 높힐 수 있었다.
&:hover {
background-color: rgba(196, 15, 57, 1);
}
&:hover .plus {
opacity: 1;
transform: rotateZ(180deg);
}
&:hover .cate {
opacity: 1;
}
&:hover .name {
opacity: 1;
}
- transition을 활용하여, hover 되었을 때 색깔이 점차적으로 변하고, rotate 되는 등 다양한 css 효과를 줄 수 있었다. 처음엔 조금 헤맸지만, 한번 구현하고 나니 간단하게, 그럴듯한 표현을 할 수 있게되어 뿌듯했다. 나도 이제 transition master! XD
Great!!