Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/web/e2e/mocks/wish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const MOCK_WISHLIST_ENTRIES: GetWishlistResponseT[] = MOCK_TOURNAMENT_ITE
},
reused: null,
refreshNeeded: null,
winnerTournamentIds: [],
})
);

Expand Down
5 changes: 4 additions & 1 deletion apps/web/e2e/specs/archive/wishAddByLink.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ test('링크를 입력해 담으면 다이얼로그가 닫히고 목록에 추
await page.getByLabel('링크 URL').fill(ADDED_URL);

api.post(ENDPOINTS.WISHLISTS, MOCK_WISH_ADDED_BY_LINK);
api.getPage(ENDPOINTS.WISHLISTS, [...MOCK_WISHLIST_ENTRIES, MOCK_WISH_ADDED_BY_LINK]);
api.getPage(ENDPOINTS.WISHLISTS, [
...MOCK_WISHLIST_ENTRIES,
{ ...MOCK_WISH_ADDED_BY_LINK, winnerTournamentIds: [] },
]);

const postRequest = page.waitForRequest(
request => request.method() === 'POST' && request.url().includes(ENDPOINTS.WISHLISTS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ function WishGrid({ items, isDeleteMode = false, selectedIds, onToggleSelect }:

return (
<div className="grid grid-cols-2">
{items.map(({ wish, item }, index) => {
{items.map(({ wish, item, winnerTournamentIds }, index) => {
const card = (
<WishCard
status={item.status}
name={item.name}
price={item.price}
imageUrl={item.imageUrl}
sourcePlatform={item.sourcePlatform}
isWinner={winnerTournamentIds.length > 0}
preload={index < 4}
/>
);
Expand Down
16 changes: 15 additions & 1 deletion apps/web/src/app/wish/_common/_components/WishCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { BadgeIconFill } from '@/assets/icons';
import ImageIconOutline from '@/assets/icons/outline/image.svg';
import BaseImage from '@/components/base-image';
import Skeleton from '@/components/skeleton';
import { Z_INDEX } from '@/consts/zIndex';
import formatPrice from '@/utils/formatPrice';

type WishCardProps = {
Expand All @@ -9,6 +11,8 @@ type WishCardProps = {
imageUrl: string | null;
sourcePlatform: string | null;
discountRate: number | null;
/** 내가 플레이한 토너먼트에서 우승한 적 있는지 */
isWinner?: boolean;
preload?: boolean;
};

Expand All @@ -18,13 +22,14 @@ const imageFallback = (
</div>
);

/** 3열 그리드용 위시 카드 — 이미지·상품명·할인율·가격·커머스 칩 */
/** 3열 그리드용 위시 카드 */
function WishCard({
name,
price,
imageUrl,
sourcePlatform,
discountRate,
isWinner = false,
preload = false,
}: WishCardProps) {
return (
Expand All @@ -43,6 +48,15 @@ function WishCard({
) : (
imageFallback
)}
{isWinner && (
<span
style={{ zIndex: Z_INDEX.BASE_IMAGE + 1 }}
className="absolute bottom-0 left-0 flex items-center gap-0.5 bg-bg-neutral-primary py-0.5 pr-1.5 pl-1 caption-2-medium text-text-neutral-inverse"
>
<BadgeIconFill className="size-3" />
1위
</span>
)}
</div>

<div className="flex h-[120px] flex-col items-start gap-2 p-3">
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/app/wish/_common/_components/WishGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ const PRELOAD_COUNT = 6;
function WishGrid({ wishes, selectedWishIds, onToggleSelect }: WishGridProps) {
return (
<ul className="grid grid-cols-3 gap-x-[1.5px] gap-y-6">
{wishes.map(({ wish, item }, index) => {
{wishes.map(({ wish, item, winnerTournamentIds }, index) => {
const card = (
<WishCard
name={item.name}
price={item.price}
imageUrl={item.imageUrl}
sourcePlatform={item.sourcePlatform}
discountRate={item.discountRate}
isWinner={winnerTournamentIds.length > 0}
preload={index < PRELOAD_COUNT}
/>
);
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/app/wish/_common/_consts/wishMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const MOCK_WISHES: WishListItemT[] = Array.from({ length: 12 }, (_, index
},
refreshNeeded: null,
reused: null,
winnerTournamentIds: index % 4 === 0 ? [index + 100] : [],
}));

export const MOCK_FOLDERS: WishFolderT[] = [
Expand Down
14 changes: 13 additions & 1 deletion apps/web/src/components/common/wish-card/WishReadyCard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import ImageIconOutline from '@/assets/icons/outline/image.svg';
import BaseImage from '@/components/base-image';
import Skeleton from '@/components/skeleton';
import { Z_INDEX } from '@/consts/zIndex';
import formatPrice from '@/utils/formatPrice';

/** READY 위시 카드 — 이미지·상품명·가격·커머스 칩 */
/** READY 위시 카드 — 이미지·우승 칩·상품명·가격·커머스 칩 */
type WishReadyCardProps = {
name: string | null;
price: number | null;
imageUrl: string | null;
sourcePlatform?: string | null;
/** 내가 플레이한 토너먼트에서 우승한 적 있는지 */
isWinner?: boolean;
preload?: boolean;
};

Expand All @@ -17,6 +20,7 @@ function WishReadyCard({
price,
imageUrl,
sourcePlatform,
isWinner = false,
preload = false,
}: WishReadyCardProps) {
return (
Expand All @@ -42,6 +46,14 @@ function WishReadyCard({
<ImageIconOutline width={40} height={40} />
</div>
)}
{isWinner && (
<span
style={{ zIndex: Z_INDEX.BASE_IMAGE + 1 }}
className="absolute bottom-[9px] left-[7px] flex items-center rounded-[4px] bg-[#404040] px-1.5 py-px caption-1-medium text-text-neutral-inverse"
>
우승템
</span>
)}
</div>

{/* 상품명 + 가격 + 커머스칩 */}
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/common/wish-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type WishCardProps = {
price: number | null;
imageUrl: string | null;
sourcePlatform?: string | null;
isWinner?: boolean;
preload?: boolean;
};

Expand Down
14 changes: 14 additions & 0 deletions apps/web/src/styles/typography.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,23 @@
font-weight: 600;
}

@utility caption-1-medium {
font-size: 12px;
line-height: 18px;
letter-spacing: -0.4px;
font-weight: 500;
}

@utility caption-1-regular {
font-size: 12px;
line-height: 18px;
letter-spacing: -0.4px;
font-weight: 400;
}

@utility caption-2-medium {
font-size: 10px;
line-height: 18px;
letter-spacing: -0.4px;
font-weight: 500;
}
4 changes: 4 additions & 0 deletions apps/web/src/types/wish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export type GetWishlistResponseT = {
* - 링크로 등록한 경우: boolean
*/
reused: boolean | null;
/**
* 내가 플레이한 토너먼트 중 이 위시가 우승한 토너먼트 id 목록
*/
winnerTournamentIds: number[];
};

export type PostWishLinkResponseT = {
Expand Down
Loading