From 82604793c15e433964e630e0b07114216fd46fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sat, 15 Aug 2026 23:40:23 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=EC=9C=84=EC=8B=9C=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=ED=85=9C=20INCOMPLETE=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 서버가 추출 결과를 일부만 채웠을 때 INCOMPLETE 를 내려준다 (TeamPiKi/core#945). 기존 코드는 FAILED·PENDING·PROCESSING 이 아니면 전부 정상 카드로 그려, 이름·가격이 빈 칸인 카드가 보이고 채우라는 유도가 없었다 - 위시 그리드에서 INCOMPLETE 를 FAILED 와 같은 편집 유도 카드로 보내되 문구만 "일부만 가져왔어요" 로 가른다 - name·price 를 nullable 로 바꾸면서 카드 컴포넌트도 nullable 을 받게 했다. INCOMPLETE 를 앞에서 걸러 실제로 빈 값이 정상 카드에 들어가지는 않는다 - 토너먼트: 담기 후보에서 INCOMPLETE 를 제외하고(서버가 출전을 막는다), 바스켓에서는 클릭 가능하게 둔다(값을 채워야 하므로) --- .../web/e2e/specs/tournament/tournamentItemAdd.spec.ts | 2 +- apps/web/src/app/archive/wish/[id]/_types/wish.ts | 8 ++++++++ .../wish/_components/wish-grid/WishFailedCard.tsx | 4 ++-- .../app/archive/wish/_components/wish-grid/index.tsx | 8 ++++++-- .../tournament-item-basket/TournamentBasketItem.tsx | 3 ++- .../[id]/create/by-wish/_components/ByWishContent.tsx | 6 +++++- .../[id]/create/by-wish/_components/WishSelectCard.tsx | 4 ++-- apps/web/src/components/common/wish-card/index.tsx | 10 ++++++---- apps/web/src/consts/item.ts | 2 ++ apps/web/src/types/item.ts | 5 +++-- 10 files changed, 37 insertions(+), 15 deletions(-) diff --git a/apps/web/e2e/specs/tournament/tournamentItemAdd.spec.ts b/apps/web/e2e/specs/tournament/tournamentItemAdd.spec.ts index 2ada2a41..4d4593a2 100644 --- a/apps/web/e2e/specs/tournament/tournamentItemAdd.spec.ts +++ b/apps/web/e2e/specs/tournament/tournamentItemAdd.spec.ts @@ -64,7 +64,7 @@ test('위시에서 상품 4개를 가져오면 장바구니에 담긴다', async await expect(nextButton).toBeDisabled(); for (const { item } of MOCK_WISHLIST_ENTRIES) { - await page.getByRole('button', { name: item.name }).click(); + await page.getByRole('button', { name: item.name ?? '' }).click(); } /** 담기 성공 후 재조회부터는 4개 담긴 응답 (뒤에 등록한 목이 우선 매칭) */ diff --git a/apps/web/src/app/archive/wish/[id]/_types/wish.ts b/apps/web/src/app/archive/wish/[id]/_types/wish.ts index 5bb37c68..392a7b00 100644 --- a/apps/web/src/app/archive/wish/[id]/_types/wish.ts +++ b/apps/web/src/app/archive/wish/[id]/_types/wish.ts @@ -19,6 +19,14 @@ type ItemT = { price: null; currency: null; } + | { + /** 추출이 일부만 채운 상태 — 채운 필드만 값이 있다 */ + status: (typeof ITEM_STATUS)['INCOMPLETE']; + name: string | null; + imageUrl: string | null; + price: number | null; + currency: string | null; + } | { status: (typeof ITEM_STATUS)['READY']; name: string; diff --git a/apps/web/src/app/archive/wish/_components/wish-grid/WishFailedCard.tsx b/apps/web/src/app/archive/wish/_components/wish-grid/WishFailedCard.tsx index 053504c2..abdf32ea 100644 --- a/apps/web/src/app/archive/wish/_components/wish-grid/WishFailedCard.tsx +++ b/apps/web/src/app/archive/wish/_components/wish-grid/WishFailedCard.tsx @@ -1,13 +1,13 @@ import { WarningIconFill } from '@/assets/icons'; -function WishFailedCard() { +function WishFailedCard({ message }: { message: string }) { return (
가져오는데 실패했어요
+{message}
직접 입력하기
diff --git a/apps/web/src/app/archive/wish/_components/wish-grid/index.tsx b/apps/web/src/app/archive/wish/_components/wish-grid/index.tsx index 19fdc43b..00ef63a7 100644 --- a/apps/web/src/app/archive/wish/_components/wish-grid/index.tsx +++ b/apps/web/src/app/archive/wish/_components/wish-grid/index.tsx @@ -29,7 +29,7 @@ function WishGrid({ items, isDeleteMode = false, selectedIds, onToggleSelect }: return ({name}
++ {name} +
{formatPrice(String(price))}