-
[쇼핑몰 웹 만들기] 프로젝트 2주차IT/엘리스SW 2022. 6. 5. 22:31728x90
2주짜리 짧다면 짧고 길다면 긴 프로젝트가 끝났다..
토요일 발표까지 마치고나니 4시,, 시원섭섭하게 프로젝트는 끝이 났다.
진심어린 소감은 회고 이후 맨 아래 적어보려 한다.
월요일 220530
상품 카테고리 페이지를 만들었다.
사실상 내가 작성하는 페이지에서 가장 중요한 메소드였던 건 insertAdjacentHTML 이었다.
html의 요소들을 클릭하거나 화면에 보여줄 때 insertAdjacentHTML 을 사용하여 보여주는걸 자주 사용했는데,
예를 들면 이런 거다.
//query String value값 선언 const [_, query] = location.href.split('?'); const [queryKey, queryValue] = query.split('='); //데이터 받아오기 async function productsdata() { const productSection = document.getElementById('productSection'); const data = await Api.get('/api/productlist'); const productLists = await data.forEach((elem) => { const category = elem.category; const title = elem.title; const imageURL = elem.image; const maker = elem.maker; const price = addCommas(Number(elem.price)); const productId = elem._id; if (elem.category === queryValue) { productSection.insertAdjacentHTML( 'beforeend', ` <a href="/products/?categoryId=${category}&productId=${productId}"> <div class="box"> <div id="product"> <img src="${imageURL}" id="productImage" alt=""> </div> <div> <p class="title">${title}</p> <p class="description">${maker}</p> <p class="price">${price}원</p> </div> </div> </a> ` ); } }); } productsdata();
홈 화면에서 클릭 시 처음에는 쿼리스트링, 패스 파라미터에 대해 정확한 구분이 없어 헤맸다.
처음에는 아래처럼 패스 파라미터 형식으로 작성했다가, 정확한 차이를 알고 싶어 오피스아워 시간에 코치님께 물어봤다.
//홈.js 에서 상품 카테고리 페이지로 넘어갈 때 <a href="/products/${categoryId}" class="slidesAtag">
아래 예시처럼, 필터형식으로 20대의 부천에사는 누구 ! 를 찾는것처럼 할 때는 쿼리스트링을, 그 외 유니크한 값을 사용해야 하는 것에는 패스 파라미터처럼 쓴다고 한다. 더 쉽게 이해하는 예로 무신사 사이트를 보면서 설명해줬는데 금방 이해가 됐다.
이렇게 상의 탭에 들어갔을 때 주소를 보면 category/001 과 같이 패스 파라미터 형식으로 나온다.
그런데 만약에 인기 제품 중 스톤아일랜드를 누르면?
001 뒤에 ? 보이나? 그 물음표 뒤에 촤르르륵 많은 것들이 붙어있다. 정확히 어떻게 필터가 걸리는지는 모르겠으나, 스톤아일랜드 하나만 눌러도 필터에 필터에 필터가 걸리는 느낌의 쿼리스트링을 볼 수 있다.
아래의 블로그 글에는 이렇게 말해주었다.
3) Query string과 Path variable은 각각 언제 쓰면 좋은가?
일반적으로 우리가 어떤 자원(데이터)의 위치를 특정해서 보여줘야 할 경우 Path variable을 쓰고, 정렬하거나 필터해서 보여줘야 할 경우에 Query parameter를 쓴다. 아래가 바로 그렇게 적용한 사례이다.
-- 출처 : https://velog.io/@jcinsh/Query-string-path-variable
이를 참고하긴 했지만 우리 웹사이트는 작고 귀여운 느낌의 기능만 있기 때문에, 통일감을 위해 쿼리스트링을 사용해주었다.
그리고 상품페이지는 기존 데모 페이지와 유사하게 작성하였다. 이 페이지 하나 구성하는데도 하루가 걸려버렸다 ..
오늘 상품상세도 할 수 있을거라 생각했는데 ㅠㅠ
화요일 220531
화요일에 상품 상세 카테고리를 작성했다.
역시나 데모페이지를 기준으로 구현을 진행했다. 데모페이지 하나하나 까보며 어떻게 마진을 주고 flex를 썼는지 등등..을 살펴보면서 구현했다.
그리고 어제 작성했던 쿼리스트링을 불러오는 함수를 URLSearchParams를 사용하는 것으로 다시 변경했다.
//기존 const [_, query] = location.href.split('?'); const [queryKey, queryValue] = query.split('='); //수정 const params = new URLSearchParams(document.location.search); const categoryId = params.get('categoryId');
기존에 불러오는건 뭔가 수작업의 느낌이라면 수정된건 기능을 써서 바꾼 느낌이라해야되나.. 그랬다.
지난주 로그인, 로그아웃 함수 만들었을 때 기뻐했었는데, 이번에는 관리자로 로그인 됐을 때 관리자라면 회원가입 문구가 관리페이지로 바뀌며 클릭 시 링크도 해당 관리페이지로 넘어가게 작성했다.
//로그인 시 관리자면 회원가입 텍스트 페이지 관리로 변경 export const changetoAdmin = async () => { const register = document.getElementById('registerId'); const userInfo = await Api.get('/api/userInfo'); const role = userInfo.role; if (role === 'admin') { register.innerText = '페이지 관리'; register.href = '/admin'; } };
백엔드에서 만들어 둔 userInfo api를 활용하면 로그인한 유저에 대한 정보를 받아오는데,
그 중 role이 admin으로 저장된 관리자라면, 회원가입 문구를 바꿔주고, 링크를 /admin으로 변경했다.
그 외에도 몇 몇가지 버그와 주석 부분을 처리해주었다.
수요일 220601
코드 리팩토링 비슷하게 작업했다.
상품 상세 페이지에서 api 받아오는 함수를 이미지를 불러오는 곳에도 사용하고, 장바구니 담을때도 활용해야 하는데
하나의 함수에 하나의 함수만 쓰게 되면 api 받아오는 부분을 두 번 이상 써야하는 게 마음에 안들었다.
다행히 수요일은 오프라인에서 만나서 했던 날이라, 팀원들에게 바로 물어보았다.
//기존 코드 //개별 상품 렌더링 async function renderProduct() { const brandSection = await document.getElementById('brandSection'); const data = await Api.get(`/api/productInfo/${productId}`); const title = data.title; const imageURL = data.image; const maker = data.maker; const price = addCommas(Number(data.price)); const description = data.description; brandSection.insertAdjacentHTML( 'beforeend', ` <section id="productContent"> <div id="imgBox"> <img id="productImage" src="${imageURL}" alt=""> </div> <div id="contents"> <div id="innercontents"> <ul> <li id="brand">${maker}</li> </ul> <p id="title">${title}</p> <p id="price">${price}원</p> <p id="description">${description}</p>
기존 코드는 data 변수에 api 정보를 담아 이미지를 그려주는데, 이 data를 장바구니 버튼 클릭 시에도 활용해주어야 하는데 그걸 못했던거다. 팀원 한 분이 방법을 알려주었다!
//변경 const data = await productData(); await renderProduct(data); await buttonEvents(data); } // query String 값 가져오기 async function productData() { const params = new URLSearchParams(document.location.search); const productId = params.get('productId'); const data = await Api.get(`/api/productInfo/${productId}`); data.id = productId; return data; } //개별 상품 렌더링 async function renderProduct(data) { const brandSection = await document.getElementById('brandSection'); brandSection.insertAdjacentHTML( 'beforeend', ` <section id="productContent"> <div id="imgBox"> <img id="productImage" src="${data.image}" alt=""> </div> <div id="contents"> <div id="innercontents"> <ul> <li id="brand">${data.maker}</li> </ul> <p id="title">${data.title}</p> <p id="price">${addCommas(Number(data.price))}원</p> <p id="description">${data.description}</p>
이 방법으로 api 를 다른 곳에서도 똑같이 활용할 수 있게, 재사용성이 높아지며 훨씬 가독성 좋은 코드가 되었다 !
그래서 장바구니 버튼을 눌렀을 때 해당 데이터가 넘어가며 필요한 정보를 프론트의 로컬스토리지에 저장될 수 있도록 함수가 구현했다.
//장바구니 버튼, 바로구매 버튼 클릭 시 이벤트 function buttonEvents(data) { const inputCartbutton = document.getElementById('inputCart'); const buyNowbutton = document.getElementById('buyNow'); inputCartbutton.addEventListener('click', inputcartbuttondata(data)); buyNowbutton.addEventListener('click', buyNow); } //장바구니 버튼 클릭 시 로컬스토리지에 해당 상품 정보 저장 function inputcartbuttondata(data) { return function () { inputCart(data.id, data); }; }
* data를 함수에서 받고, inputCart는 외부에서 가져온 함수다.
또 새롭게 배워가는 것들이 많아 기뻤다.
목요일 220602
팀에서 구분했던, 내가 구현할 페이지는 모두 완성을 했어서 뭘 할까요 했는데, 주문 완료 시 완료페이지를 만들어줬으면 좋겠다 하여
금방 만들었다. 사실 완료페이지에서는 크게 구현할 부분이 없어 금방 했는데, 그러고 나니 저녁에도 시간이 남아
카테고리를 볼 수 있는 기능을 만들어보기로 하였다.
또 허전하고 조금은 많이 심플한 웹사이트에 공통 디자인을 적용하기로 했다. 쇼핑몰 이름을 정해주고, 색상을 주황색으로 하였다.
우리는 운동용품을 파는 웹사이트로 탈바꿈시키기로 정했다.
홈 화면에 덩그러니 남아있던 슬라이드 옆 카테고리를 추가하고, 상품카테고리 페이지에 넘어갔을 때도 카테고리를 보이게 만들었다.
마지막으로, 기존 상품 카테고리 페이지를 데모페이지 형식의 긴 형태의 박스에서 카드 형식으로 바꾸는 큰 변화를 주었다..!
완성하고나니 새벽 4시.. 시간이 빛과 같다. 시간가는 줄 모르게 재밌다고 만들었다 ㅋㅋ
다른 팀원분들에게도 내가 이렇게 바꿨어요..! 하는, 와 애쓰셨네요 하는 말도 듣고 싶어서였을까, 엄청 열심히 수정했다..ㅋㅋ
그리고 다행히? 모두가 와 왜 갑자기 이렇게 탈바꿈했냐고 깜짝 놀랐다고 다들 칭찬해줘서 너무 행복했다 ..><
금요일 220603
어제 , 아니 오늘이라할까 금요일 새벽4시까지하고 잤더니 10시에 스크럼하는 것에 20분정도나 지각하고 말았다 ㅠㅠ
토요일 ppt와 발표자 등을 정해야하는데 모두 딱히 하고 싶지 않아서.. (ㅋㅋㅋㅋ) 사다리를 탔는데
와우 .. 나였다 ^^^^^
금요일엔 어떤거 추가기능을 해볼까 고민했는데, 고민이 사라졌다.. ppt와 발표준비를 해야했기에..
팀원 한 분이 ppt 그거 크게 힘들이지 않아도 될거같다고, 대충 하시고 추가기능이나 하나 개발하시죠~ 했어서 뭐할까요 ?!
했더니 검색 기능 하는게 어떠냐고, 그래서 아 좋네요! 그거 이렇게 저렇게 하시면 될걸요? 하기에 들어보니 금방 하겠다 싶어 오케이 했는데, 시간이 차츰 지날수록 발표에 대한 압박과 ppt 작성에 힘을 쓰다보니 검색기능 죄송한데 못할거 같다 ㅠㅠ 했더니 괜찮다고 자기가 하겠다고 .. (그리고 1시간도 안돼서 만드신 능력자 팀원 ..리스펙입니다 )
나는 ppt 작성에 집중했다.
그렇게 또 이런저런 얘기하면서 버그 계속 수정하고 테스트하고 추가기능 넣는 팀원들과 이야기하다보니 어느새 새벽3시..
대망의 발표날이 다가왔다.
토요일 220605
나는 사실 발표를 진짜 못한다. 주목받는 것을 병적으로? 싫어하고, 온라인임에도 누가 나한테 모두 집중하고 있으면 얼굴빨개지고 땀이 나는, 거의 병이라 생각된다. 근데 어떡하나? 내가 발표자가 됐으니 최선을 다할 수 밖에.
이 아래에도 스크립트 길게.. 있다.
ppt를 보여주는 것보다 사실 실제 구현한 웹사이트가 어떻게 동작하는지를 보여주는 게 더 중요해서, 그것을 어떤 순서로 어떻게 보여줄까를 고민했다.
그리고 발표의 시작..
대망의 발표는 혹시나였지만 역시나 망했고, 코치님의 질문에도 얼타다 모른다고 답해버렸다 ㅠ
그래도 시간은 흘러갔고, 그렇게 2주간의 프로젝트는 끝이 났다.
발표는 다른 조의 발표도 같이 참관하여 들었는데, 솔직히 잘한 조 많았다. 프론트도 이쁘게 잘 처리했고, 백엔드는 어떻게 구성했는지 보이지는 않았지만.
아주 살짝은 아쉬운감도 있다. 내가 좀 더 잘했더라면, 더 잘해서 빨리 맡은 부분 끝내고 프론트 동료들 업무를 더 가져와 열심히 만들었으면 더 이쁘게 만들었을텐데! 하는 아쉬움?
우리는 평가 기준에 맞게 만들자는 목표를 갖고 2주를 달렸다.
그럼에도 내 스스로의 욕심에 카테고리 페이지를 더 낫다고 생각하는 디자인으로 바꾸고, 카테고리를 클릭할 수 있는 부분도 추가하는 등
여러 부분에 신경썼다는 점이 내 스스로 대견했다.
당연한 소리지만, 여전히 모르는 게 산더미다.
이전 스터디원들과 모두 고생했다며 카톡하는데 그랬다.
장점 : 배울게 한 가득
단점 : 배울게 한 가득
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
매번, 매 일을 성장하는 내가 중간중간 한숨나오지만 , 그래도 좋다.
발전하는 내가 좋다.
다음 2차 프로젝트는 더, 더 나은 나로
충분히 이해하고 활용하는 내가 되길 바란다.
그리고 그 때 다시 지금의 1차 프로젝트를 살펴보고 싶다.
그때는 또 이 프로젝트가 다르게 보이겠지?
우리 고생한 팀원들 모두, 너무 고맙고, 다들 원하는 미래 꼭 이뤘음 좋겠다.
진심으로 🙏🙏🙏🙏🙏🙏🙏🙏
'IT > 엘리스SW' 카테고리의 다른 글
[쇼핑몰 웹 만들기] 프로젝트 1주차 (0) 2022.05.29 자바스크립트 this 이해하기 (0) 2022.04.25 [TIL] 엘리스 SW 엔지니어트랙 2기 - (Week2,Day14) (0) 2022.04.22 [TIL] 엘리스 SW 엔지니어트랙 2기 - (Week2,Day13) (0) 2022.04.21 [TIL] 엘리스 SW 엔지니어트랙 2기 - Javascript (Week2,Day11) (0) 2022.04.19