20260114 #128 장바구니 메뉴 수량 조절 컴포넌트 개발#130
Conversation
|
@CodeRabbit full review |
✅ Actions performedFull review triggered. |
|
Caution Review failedThe pull request is closed. WalkthroughQuantityStepper 컴포넌트와 스타일을 추가하고, useCart 훅에 removeFromCart를 도입했으며 아이콘 수출명 변경 및 CartButton/숫자 컴포넌트 스타일·마크업을 조정하고, next.config.ts의 원격 이미지 호스트명을 수정했습니다. Changes
Sequence DiagramsequenceDiagram
actor User
participant QS as QuantityStepper
participant CH as useCart Hook
participant API as Cart API
participant Toast as Toast Handler
User->>QS: 증가 클릭 (add)
QS->>CH: addToCart(menuId)
CH->>CH: 중복 요청 확인
CH->>API: 수량 업데이트 요청
API-->>CH: 응답
alt 성공 & 새 수량 > 9
CH->>Toast: onError("최대 수량(9) 도달")
Toast-->>User: 토스트 표시
else 성공
CH-->>QS: 성공 콜백
QS-->>User: UI 갱신
else 오류
CH->>Toast: onError(오류 메시지)
Toast-->>User: 토스트 표시
end
User->>QS: 감소 클릭 (remove)
QS->>CH: removeFromCart(menuId)
CH->>CH: 중복 요청 확인
CH->>API: 수량 감소 요청 (quantity-1)
API-->>CH: 응답
alt 성공
CH-->>QS: 성공 콜백
QS-->>User: UI 갱신 (0이면 아이템 제거/TrashIcon)
else 오류
CH->>Toast: onError(오류 메시지)
Toast-->>User: 토스트 표시
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/assets/icons/index.ts`:
- Around line 13-19: Rename the inconsistent export ShoppingBag to
ShoppingBagIcon to match the Icon suffix convention used by other exports (e.g.,
MinusIcon, PlusIcon, TrashIcon); update the export line to export { default as
ShoppingBagIcon } from "./shopping-bag.svg" and then update any imports/usages
referencing ShoppingBag throughout the codebase to use ShoppingBagIcon instead
so names remain consistent.
In `@src/features/cart/components/button/QuantityStepper.tsx`:
- Line 42: In QuantityStepper, add the missing semicolon to the const
declaration isPlusDisabled (change "const isPlusDisabled = quantity >= 9" to
terminate with a semicolon) to match the project's consistent code style; update
the line where isPlusDisabled is defined so the statement ends with a semicolon.
🧹 Nitpick comments (4)
src/features/cart/components/button/QuantityStepper.module.css (1)
1-12:align-content대신align-items사용을 권장합니다.
align-content는 여러 줄의 flex 아이템이 있을 때 사용됩니다. 단일 줄 flex 컨테이너에서는align-items가 더 적절합니다.♻️ 수정 제안
.container { display: flex; justify-content: center; - align-content: center; + align-items: center; padding-block: 0.44rem; padding-inline: 0.5rem; border-radius: 0.25rem; border: 1px solid var(--color-gray-200); background-color: var(--color-white); }src/features/cart/hooks/useCart.ts (1)
105-151:removeFromCart구현이 잘 되었습니다.
addToCart와 동일한 패턴을 따르고 있어 코드 일관성이 좋습니다:
- 중복 요청 방지 로직
- 수량 검증 (0일 때 조기 반환)
- 콜백 처리
참고:
requestPromise가 생성되지만 반환되거나 await되지 않아reject(error)호출 시 unhandled promise rejection이 발생할 수 있습니다. 이는addToCart에도 동일하게 존재하는 패턴이므로, 향후 리팩토링 시 함께 개선하면 좋겠습니다.♻️ Promise 반환 또는 void 처리 제안 (선택사항)
- const requestPromise = new Promise<void>((resolve, reject) => { + const requestPromise = new Promise<void>((resolve) => { upsertCartMutation.mutate( { menuId, quantity: newMenuQuantity }, { onSuccess: () => { pendingRequests.current.delete(menuId); callbacks?.onSuccess?.(); resolve(); }, onError: (error) => { pendingRequests.current.delete(menuId); callbacks?.onError?.("장바구니 수정에 실패했어요. 잠시 후 다시 시도해주세요."); - reject(error); + resolve(); // 에러는 콜백으로 처리되므로 resolve로 종료 }, } ); });src/features/cart/components/button/QuantityStepper.tsx (2)
17-18:isAddingToCart는 전역 mutation 상태입니다.
useCart에서 반환되는isAddingToCart는upsertCartMutation.isPending으로, 특정menuId가 아닌 전체 mutation의 pending 상태를 나타냅니다. 따라서 다른 메뉴 아이템의 수량 변경 중에도 이 컴포넌트의 버튼이 비활성화될 수 있습니다.현재 구현에서는 감소 버튼만
isAddingToCart로 비활성화하고 있어 동작에 불일치가 있을 수 있습니다. 필요하다면useCart에서 메뉴별 pending 상태를 노출하는 것을 고려해 주세요.
47-61: 버튼 비활성화 상태 불일치.감소 버튼은
isAddingToCart로 비활성화되지만, 증가 버튼은isPlusDisabled(수량 >= 9)로만 비활성화됩니다. 장바구니 작업 진행 중에도 증가 버튼을 클릭할 수 있습니다.
useCart.addToCart내부에서pendingRequests로 중복 요청을 방지하므로 기능적으로는 문제가 없지만, 일관된 UX를 위해 두 버튼 모두 동일하게 비활성화하는 것이 좋습니다.♻️ 수정 제안
<button onClick={handleIncrement} - disabled={isPlusDisabled} + disabled={isPlusDisabled || isAddingToCart} > {incrementIcon} </button>
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
src/assets/icons/minus.svgis excluded by!**/*.svgsrc/assets/icons/plus-disable.svgis excluded by!**/*.svgsrc/assets/icons/plus.svgis excluded by!**/*.svgsrc/assets/icons/trash.svgis excluded by!**/*.svg
📒 Files selected for processing (8)
next.config.tssrc/assets/icons/index.tssrc/features/cart/components/button/QuantityStepper.module.csssrc/features/cart/components/button/QuantityStepper.tsxsrc/features/cart/hooks/useCart.tssrc/features/menu/components/button/CartButton.module.csssrc/features/menu/components/button/CartButton.tsxsrc/shared/components/number/RoundedNumber.module.css
💤 Files with no reviewable changes (2)
- src/features/menu/components/button/CartButton.module.css
- src/features/menu/components/button/CartButton.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/features/cart/components/button/QuantityStepper.tsx (2)
src/features/cart/hooks/useCart.ts (1)
useCart(24-162)src/shared/hooks/useToast.ts (1)
useToast(16-83)
🔇 Additional comments (7)
next.config.ts (1)
39-39: LGTM!S3 버킷 호스트명 변경이 올바르게 적용되었습니다. 기존
campustable-s3에서campus-table-s3로 변경되었으며, 나머지 설정은 그대로 유지됩니다.배포 전 새로운 S3 버킷에서 이미지가 정상적으로 로드되는지 확인해 주세요.
src/features/cart/components/button/QuantityStepper.module.css (1)
14-27: LGTM!
.wrapper와.label스타일이 프로젝트의 CSS 변수를 일관되게 사용하고 있습니다.src/features/cart/hooks/useCart.ts (1)
17-21: LGTM!
removeFromCart메서드의 인터페이스가addToCart와 일관된 패턴으로 정의되었습니다.src/shared/components/number/RoundedNumber.module.css (1)
6-8: LGTM!최소 크기 설정(
min-width,min-height: 1.25rem)이 추가되어 컨테이너가 내용물 크기에 관계없이 일관된 최소 크기를 유지합니다. 장바구니 수량 표시의 시각적 안정성을 보장하는 좋은 변경입니다.src/features/cart/components/button/QuantityStepper.tsx (3)
1-11: LGTM!클라이언트 컴포넌트 선언과 필요한 의존성 import가 적절하게 구성되어 있습니다.
QuantityStepperProps인터페이스도 명확합니다.
20-28: LGTM!최대 수량(9개) 체크와 에러 처리가 적절하게 구현되어 있습니다.
useCart의 내부 검증과 별개로 UI 레벨에서의 방어적 체크는 즉각적인 피드백을 위해 좋은 패턴입니다.
30-38: LGTM!수량이 0 이하일 때의 방어 로직과
removeFromCart에러 처리가 적절합니다.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
✨ 변경 사항
✅ 테스트
Summary by CodeRabbit
릴리스 노트
새로운 기능
UI 개선
기타
✏️ Tip: You can customize this high-level summary in your review settings.