-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[1단계 - 자판기] 병민(윤병인) 미션 제출합니다. #40
Conversation
commitlint + commitizen 을 사용해서 commit message를 정형화한다
single quote, EOL, trailingComma 적용
store, reducer, creaAction 생성
component scope를 추가한다
redirect rule을 적용한다
event decorator를 사용하면 컴포넌트가 사라졌을때 등록한 event가 사라지기 때문에, 사용하기에 적절치 않다.
충전 금액이 음수일 경우 에러를 체크하는 테스트를 추가한다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 😄
리뷰를 맡은 오스틴입니다.
flux 패턴을 활용하셔서 개발하신 부분이 인상적이었습니다.
관련해서 코멘트 남겨놨으니 확인 부탁드릴게요!
UX/UI 관련
- 상품 관리 - 상품 현황 리스트 수정을 누르게되면 input 태그크기 때문인지 리스트 높이와 버튼 위치가 변하는데 이 부분 보기/수정 상관없이 리스트와 버튼의 위치가 동일하도록 css를 수정해보시면 좋을 것 같습니다.
- 피그마와 다른 내용이긴 하지만 상품 관리탭에 추가할 상품정보를 입력하는 부분에 placeholder으로 어떤 값을 넣어야하는 설명해주고 있지만 처음 값을 작성할 땐 어떤 항목에 대한 값을 작성하고 있는지 헷갈리는 경우가 있어 라벨이 있으면 어떨까라는 생각을 했습니다.
return ` | ||
<nav class="d-flex justify-content-center"> | ||
<button class="btn btn-secondary mr-1 ${ | ||
activeTab === Tab.ProductManageTab ? 'active' : '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3항연산자 말고 &&을 활용하셔도 될것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
activeTab === Tab.ProductManageTab && 'active'
를 써보니, false가 class에 들어갑니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아고 제가 리엑트 문법에 너무 익숙해져서 간과했던 부분이네요 🙏
@@ -0,0 +1,10 @@ | |||
import { Action } from '../types'; | |||
|
|||
const createAction = (type: string, payload: any): Action => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
return coins; | ||
} | ||
|
||
const reducer = (state: AppState, { type, payload }: Action) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
if (type === ACTION.ADD_PRODUCT) { | ||
newState.productList = [...newState.productList, { ...payload, isEditing: false }]; | ||
} else if (type === ACTION.CHANGE_EDIT_MODE) { | ||
const { name, isEditing } = payload; | ||
const index = newState.productList.findIndex((item) => item.name === name); | ||
newState.productList[index].isEditing = isEditing; | ||
} else if (type === ACTION.EDIT_PRODUCT) { | ||
const { originalName, name, price, quantity } = payload; | ||
const index = newState.productList.findIndex((item) => item.name === originalName); | ||
newState.productList[index] = { name, price, quantity, isEditing: false }; | ||
} else if (type === ACTION.DELETE_PRODUCT) { | ||
newState.productList = newState.productList.filter((item) => item.name !== payload); | ||
} else if (type === ACTION.CHARGE_COINS) { | ||
newState.chargedCoins = mergeCoins(newState.chargedCoins, moneyToCoin(payload)); | ||
newState.chargedMoney += payload; | ||
} else if (type === ACTION.CHANGE_ACTIVE_TAB) { | ||
newState.activeTab = payload; | ||
} | ||
return newState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch 문으로 리페토링 가능하시면 swith 문 활용하시는걸 추천드려요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네, 그 편이 더 읽기 좋을것 같습니다. 감사합니다 :D
class PurchaseProductTab extends Component { | ||
template(activeTab: Tab): string { | ||
if (this.localName !== activeTab) return ''; | ||
return '<h3 class="text-center">🤖 페이지 건설중...</h3>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UX/UI를 고려한 부분 좋네요. 👍
@@ -0,0 +1,70 @@ | |||
import { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validators.ts 파일이 유독 가독성이 떨어져 보이네요. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞습니다. 다시보니 읽기가 힘드네요. 수정하겠습니다 :D
import { toInt } from '../utils'; | ||
import ValidationResult from './validation-result'; | ||
|
||
const isInteger = (str: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intger은 javascript에는 없는 타입이네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네, 맞습니다. 다만 정수인지를 판단하는 일을 하는 함수라서
Integer가 직관적이라 더 어울려 보이는데, 리뷰어님의 생각은 어떠신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toInt 함수와 동일한 의견입니다!
const productList = Store.instance.getState().productList; | ||
const errorList = validateProduct( | ||
{ name, price, quantity }, | ||
productList.filter((item) => !(item.name === originalName && item.name === name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적인 취향이지만 드모르간 법칙을 이용해 가독성좋게 바꿔보는건 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제안 감사합니다 :D
드모르간 법칙을 적용하면
const productList = Store.instance.getState().productList;
const errorList = validateProduct(
{ name, price, quantity },
productList.filter((item) => item.name !== originalName || item.name !== name)
이렇게 되서, 더 잘 읽히는것 같습니다.
다만, 그래도 역시 한번에 이해하기 어려운 코드여서 아래와 같이 바꿔보았습니다.
const productList = Store.instance.getState().productList;
const isEditingSameProduct = (item: ProductItem) => {
if (originalName === name && item.name === name) return true;
return false;
};
const errorList = validateProduct(
{ name, price, quantity },
productList.filter(!isEditingSameProduct)
).filter((result) => result.hasError);
이 코드는 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
export const MAX_LENGTH_OF_PRODUCT_NAME = 10; | ||
export const MIN_PRODUCT_PRICE = 100; | ||
export const MAX_PRODUCT_PRICE = 10000; | ||
export const MIN_COIN_UNIT = 10; | ||
export const MIN_PRODUCT_QUANTITY = 1; | ||
export const MAX_PRODUCT_QUANTITY = 20; | ||
export const MAX_CHARGABLE_MONEY = 100000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
관련있는 변수를 묶어서 관리해도 좋을 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네, 수정하겠습니다 :D
|
||
$color-primary: $color-cyan-900; | ||
$color-secondary: $color-gray-400; | ||
// $color-cancel: $color-cyan-900; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
불필요한 주석은 지워주시는게 좋을 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네, 지우겠습니다 :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요. 병민님.
아직 리뷰요청을 주시진 않았는데요. 피드백 반영해주신 것으로 확인됩니다.
2단계 진행 및 리뷰 일정 확보를위해 머지하도록 하겠습니다.
step1 구현하시느라 고생많으셨습니다 👍
import { toInt } from '../utils'; | ||
import ValidationResult from './validation-result'; | ||
|
||
const isInteger = (str: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toInt 함수와 동일한 의견입니다!
import { VALIDATION_ERROR_NAME } from './constants'; | ||
import { Indexable } from './types'; | ||
|
||
export const toInt = (str: string, defaultNum = 0) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
디테일하시군요 👍
저는 그냥 보편적으로 숫자라고 생각했는데 병민님 의견 주신 부분이 맞는것 같습니다 🙏
import Component from '../abstract/component'; | ||
import { ComponentConstructor } from '../types'; | ||
|
||
export function customElement(name: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그렇군요. 제가 궁금했던건 customElement자체의 사용 이유
였습니다.
본인의 생각이 명확하시네요 👍
return ` | ||
<nav class="d-flex justify-content-center"> | ||
<button class="btn btn-secondary mr-1 ${ | ||
activeTab === Tab.ProductManageTab ? 'active' : '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아고 제가 리엑트 문법에 너무 익숙해져서 간과했던 부분이네요 🙏
const productList = Store.instance.getState().productList; | ||
const errorList = validateProduct( | ||
{ name, price, quantity }, | ||
productList.filter((item) => !(item.name === originalName && item.name === name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
.map((unit) => { | ||
return ` | ||
<tr> | ||
<td>${unit.toLocaleString('ko-kr')}원</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prototype에 직접 추가하는 추천드리지 않습니다.. 어떤 사이드 이펙트가 생길지 모르기때문입니다.
store나 util로 따로 뺄순 있지않나 해서 말씀드렸습니다!
안녕하세요, 병민입니다 :D
이번 미션 피드백 잘 부탁드립니다 :D
데모 페이지
전체적인 구조
Routing
netlify의 redirect를 사용해 새로고침을 해도 404로 이동되지 않도록 했습니다.