삼십 문방구 [ WoowaSiblings ]

younghyun·2022년 3월 12일
1

Project 소개

30기 동기들과 멘토들의 특징, 물건을 판매하는 사이트를 구현함.

1차 Planning Meeting

첫 프로젝트를 하며 설렘 반, 두려움 반으로 미팅을 시작 했다. 팀원들 모두 전부 실력과 경험이 없었지만, 욕심이 나서 겁 없이 많은 기능을 넣기로 했었다..

하지만 멘토님들과의 미팅 후 인원이 적고 시간이 짧기 때문에 여러가지를 만들기보다 한 가지를 제대로 하는 게 낫다는 피드백을 받고, 대폭 기능을 줄였고 기본적인 기능에 치중하기로 했다.

1차 Sprint 기간

내가 맡은 부분은 footer, main, Detail 페이지였는데, 프로젝트에서 중심에 해당하는 페이지들이라 부담이 많이 되었다.
중간에 Git(개별 브랜치 에서 다른 개별 브랜치 생성 등), VSC( 브랜치 전환이 안되는 문제 ) 등 개발 툴 문제가 발생해서, 팀원들과 멘토님들에게 도움을 구하고, 일정을 재 조율하였다.

아직까지도 가슴을 졸이며 에러를 해결 하던 날들은 잊혀지지 않는다.

멘토님과 팀원과의 미팅 후 메인 페이지에서 상세 페이지로 이동하는 동적 라우팅 기능과 카테고리 별 페이지 이동하는 기능을 핵심적인 부분으로 구현하면서

전체적인 커머스 플로우를 보여주는 것을 중심으로 두기로 했다.
주말에도 단 한순간도 쉬지 않고, 미리 동적 클래스, 동적 라우팅, useLocation등의 개념을 미리 학습해 구현해나갔다.

2차 Sprint Meeting

2차 스프린트 미팅 후, 공통적으로 들어가는 variables.scss, reset.scss파일, common.scss파일에 대해서 수정을 했다.
1차 스프린트 미팅 후 제대로 설정을 했다면 이후에 들어가는 노력을 줄일 수 있었을 것이라는 생각이 들었고,

2차 프로젝트에서는 같은 실수를 하기 싫어 따로 초기 세팅 및 리팩토링 가이드 파일을 만들었다.

또한, nav, main페이지를 한 사람이 맡아서 진행하는 것이 카테고리별 이동 구현 로직에 대해 더 빠르게 진행할 수 있을 것이라는 생각도 들었다.

2차 Sprint 기간

2차 스프린트 기간에서는 상세페이지 구현에 힘을 쏟았다. 특히 수량에 따른 가격을 계산할 때 자식 컴포넌트에서 함수를 통해 부모 컴포넌트 변화를 이끌어내는 부분이 가장 인상깊게 남았다.

자식 컴포넌트

부모 컴포넌트

프로젝트 최종 발표

프로젝트 최종 발표는 각자 역할, 홈페이지 소개, 공유하고 싶은 코드, 하고 싶은 말 등으로 구성해서 발표를 했다.
가장 크게 든 생각은 후련하면서도 더 잘할 수 있었는데 라는 아쉬움이 가장 컸다. 또한 같이 한 팀원들에게 정말로 감사했고, 다양한 문제 속에서 본질적인 기능 구현은 무사히 마쳤다는 점에서는 나름 만족할 만한 프로젝트 였다.

또, 다른 팀 발표 때도 반응이 좋았지만 고객이 었던 30기 들과 멘토님들의 반응은 정말 강의실이 뜨거웠고,

코드를 치는 것보다 고객관점에서 기획을 하는 것이 더 중요하다는 것을 배웠다.

절대 잊지 말자. Agile

2주간 프로젝트 진행일정에서 백엔드와의 용어가 다른데서 오는 어려움 등은 없었지만, 첫 sprint회의 때 어느 정도까지 구현할 수 있는지, 얼마나 시간이 걸리는지를 정확히 알기가 어려웠고, 아직 배우지 않은 부분에 대해서 100%구현 할 수 있다고 말하는 게 책임감이 없다고 느껴져서 애자일 방식으로 진행하지 못했다.

개발자로서 성장 하면서 자연스레 일정에 대해 구체적으로 기한과 결과물을 계산 해낼 수 있게 되면, 좀더 의견을 적극적이고 주도적으로 확신을 가지고 낼 수 있게 되고, 그에 따라 프로젝트 일정을 잘 조절 할 수 있게되고, 협업 능력 또한 실력에 따라 조금씩 늘어날 것이라 생각한다.

잘한 점

2주라는 기간, 적은 팀원, 초기 애자일 하지 못했던 프로젝트 진행, 중간에 Git문제로 2일 정도 시간이 소요된 상황 속에서 맡았던, 메인과 상세 페이지에는 배우지 않은 기능이 ( 동적 라우팅, pagination )있고, 기능이 많은 편에 속해서 포기하고 싶은 생각이 종종 들었고, 몇 번이고 정신적으로 힘들어지곤 했다.
그럴 때 도움이 되었던 것은 스스로 할 수 있다는 믿음, 주변 동료들의 격려였다.

스스로에 대한 확신, 격려 속에 주말에도 단 1시간도 쉬지 않고 배우지 않은 부분을 공부 해서 프로젝트에 적용했던 점에 대해서 잘했다고 말하고 싶다.

정확히 말하면, 무엇을 구현했는가에 대해 잘했다기 보단 앞으로도 끈기와 기개, 도전의식을 가진 태도를 견지한다면 개발자로서 성장할 수 있다는 확신이 들었기 때문에 잘했다고 말하고 싶다.

아쉬운 점

직접 프로젝트를 하는 게 처음 이다보니, 시행착오가 많았다. 백엔드 2명, 프론트엔드 2명으로 진행을 했고, 아주 고도화된 기능 보다는 페이징 이동, 카테고리 이동, 장바구니 구현 등 기본에 충실한 기능들만 넣으면서 프로젝트를 진행했다. 정렬, pagination 등의 좀 더 고도화 된 기능을 넣지 못한 점이 아쉽다.
1차 때 기본적인 기능을 구현했으니 2차 때는 좀 더 고도화에 집중할 것이다

개발철학

나라를 구하고 싶었다. 첫 회사를 나온 이유였고, 머리 속에 맴돌던 정주영 회장님의 말이었다. 나에게 적용한다면 먼저 회사에 도움이 되는 사람이 되자 정도로 해석할 수 있을 것 같다.

회사를 나오기 전에는 채용 연계형 인턴으로 1달 뒤 정규직 전환이 되는가 안되는가를 앞두고 있었다. 인턴 동료들 실적과 비교했을 때 실적이 나쁘지 않았고, 같이 일한 지점장님과 다른 지점장님, 그 위 팀장님도 평가가 좋았기에 전환이 될 것 같다는 생각이 들었다.

하지만, 만약 전환이 되고 나서 얼마 안가 나오게 된다면, 그건 나 뿐만 아니라 회사에도 해를 끼치는 일이라 생각해서 나오게 되었다.
주변에서는 편하게 높은 연봉과 좋은 복지를 받으면서 다니면 좋은데 왜 나오는가에 대해서 많은 질문을 했다.

개인의 삶을 놓고 보았을 때 연봉, 복지 같은 점들에 많은 초점을 두면 나오지 않았던 게 맞았을지도 모른다.
앞으로 평생 가고 싶은 길은 잘 닦인 포장도로가 아니라 진흙탕 속을 걸어야 하는 어려운 길을 택했다고 생각한다. 그 결정에 후회는 없다.
요즘은 공무원, 공기업 등 편하고 남이 보기에 좋아보이는 길을 찾는 것 같다. 그러한 삶의 기준을 비난하는 것은 아니다. 하지만 누군가 편하게 살려면 다른 누군가는 모든 것을 다 잃는다고 해도 최선을 다해 도전하고 성취하는 부분이 사회 전체적인 부분에서 필요한게 아닐까

개인적으로 성장이란 체계가 아닌 기회가 있는 곳에서 주도적이고 책임감있게 행동함으로써 이루어지는 것이라 생각한다.

개발자로서 기회가 있는 곳에서 후배, 동료, 상사, 고객을 섬기기 위한 태도로, 항상 주도적으로 배우려는 태도를 가지고 실력과 인성을 갖춘 리더쉽으로 성장할 것이다.

또한, 회사 전체의 비전과 목표에 초점을 맞추고 개발을 진행할 것이다. 그렇게 한다면 비록 주니어 때는 시니어 개발자 분들과 개발 실력과 생각의 깊이는 차이가 나도 생각의 방향은 같이 할 수 있는게 아닐까 생각한다.

단순히 코딩 실력만 화려한 개발자 보단, 주변 동료와 회사, 고객으로 부터 받은 것보다 더 많은 가치를 돌려주는 사람으로서, 회사와 사회에 공헌하는 한 명의 엔지니어로서 성장하고 싶다.
인내하고 적극적인 태도를 견지해 끝끝내 해내는 어려울 때 생각나는 믿음직스럽고 의지하고 싶고 함께 하고 싶은 사람이 되고 싶다.

생각나는 코드

variable.scss
반복되는 부분 스타일을 변수로 저장을 해놓을 경우 재사용성을 높일 수 있었다.

$saleFontColor: #ff6350;
$saleFontFamily: 'Montserrat';
$userMenuColor: #717171;
$userMenuHoverColor: #333;
//BaeminColor

$baeminPointColor: #30c1c3;
$grayBackgroundColor: #eaeaea;
$themeBorder: 1px solid #eaeaea;
//Position

config.js
매번 URL이 변동될때 마다 페이지 별로 바꿔야 하는 번거로움이 있었다. config.js 파일을 만들어 URL을 저장하는 변수를 만듦으로써 재사용성과 유지보수성을 높일 수 있었다. 너무 편해서 좋았다..

const BASE_URL = 'http://10.58.7.135:8000';

export const API = {
  MAIN: `${BASE_URL}/products`,
  SIGNUP: `${BASE_URL}/users/signup`,
  LOGIN: `${BASE_URL}/users/signin`,
  DETAIL_PAGE: `${BASE_URL}/products/`,
  CART: `${BASE_URL}/orders/carts`,
};

product.js
동적 클래스, 삼항연산자와 단항 평가 연산자를 통해서 정가와 할인가를 구분해서 나타냈다.
단항 편가 연산자는 단연코 너무 좋은 문법이다. if문, 삼항 연산자도 경우에 따라 쓰면 좋지만 코드의 간결성, 효율성 측면에서 배우는데 재미 있었던 문법이었다.

<div className="productPriceOne">정가</div>
              <span
                className={`productPriceTwo ${
                  item.discount_rate ? 'productPriceThree' : ''
                }`}
              >
                {Number(item.price).toLocaleString()}원
              </span>
            </div>
            {item.discount_rate && (
              <div className="disCountPrice">
                <div className="productDiscountPriceOne">할인가</div>
                <span className="productDiscountPriceTwo productDiscountPriceThree">
                  {Number(item.discount_price).toLocaleString()}원
                </span>
              </div>
            )}
            <div className="productDelivery">
              <div className="productDeliveryOne">배송정보</div>
              <span className="productDeliveryTwo">
                배송이 힘들어요... 찾으러 오세요
              </span>
            </div>
          </div>
          <SelectItem content={item} onChange={handleAmountValue} />
          <div className="totalAmount">
            <div className="totalAmountOne">총 합계금액</div>
            <div className="totalPrice">
              <strong>
                {item.discount_rate
                  ? `${(amount * item.discount_price).toLocaleString()}원`
                  : `${(amount * item.price).toLocaleString()}원`}
              </strong>
            </div>
          </div>

fetch함수
토큰이 없는 경우, 바로 로그인 페이지로 이동하도록 했다.
처음에는 else if문을 써서 뒤에 붙였지만, 고객 관점에서 본다면 바로 토큰이 없는 경우 로그인 페이지로 이동하는 게 맞다는 피드백을 받고, 수정했다.

const goToBasket = () => {
   if (!token) {
     alert('로그인이 필요합니다.');
     navigate('/login');
     return;
   }

   fetch(`${API.CART}`, {
     method: 'POST',
     headers: { Authorization: token },
     body: JSON.stringify({
       quantity: goToBack,
       product_id: `${params.id}`,
     }),
   })
     .then(response => response.json())
     .then(result => {
       if (
         result.message === 'CREATE_CART' ||
         'ADD_QUANTITY_TO_EXISTED_CART'
       ) {
         window.confirm(
           '상품이 장바구니에 담겼습니다. 장바구니로 이동하시겠습니까?'
         ) && navigate('/cart');
       } else {
         alert('다시 시도해주세요!');
       }
     });
 };

 const handleAmountValue = event => {
   setAmount(Number(event.target.value));
   setGoToBack(Number(event.target.value));
 };

메인 페이지

상세페이지

마무리

1차 프로젝트를 정리하면서 느낀 점은 오해가 생기지 않도록 그날 그날의 주제에 대해서 구체적으로 논의해야 하고, 논의한 내용을 번거로워도 체크리스트를 만들어 어디가 잘 안되는지 서로 공유해야 하며, 막히는 부분은 시간을 두고 스스로 console, 구글링, stackoverflow 등을 통해 해결하는 시간을 가진 후, 제한 시간이 지나면 바로 잘하는 주변 인에게 물어보며 일정을 조절하는게 중요하다는 점이다. 그리고 혼자 고민하던 문제를 팀이 같이 고민하면 고민이 아니거나, 어떻게든 해결 된다는 점이 신기했고, 즐거웠다. 2차 프로젝트에서는 시간을 정해두고 조금 더 긴밀한 소통속에 프로젝트를 진행해야겠다.

profile
선명한 기억보다 흐릿한 메모

0개의 댓글