From 2920ec0b9241a7ec94c64508a9050db1a16c5168 Mon Sep 17 00:00:00 2001 From: joyeongchan Date: Thu, 13 Aug 2026 01:23:39 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EB=AA=A8=EB=8B=AC=EC=9D=98=20=EB=94=A4=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=C2=B7=EC=A1=B0=ED=9A=8C=20=EC=8B=A4=ED=8C=A8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MorePopover 의 stopPropagation 래퍼 안에 Dialog 가 있어 딤 클릭이 막혔다. Dialog 를 래퍼 밖으로 빼 카드 이동 차단은 유지하면서 모달은 정상적으로 닫히게 한다. - useGetGroupResult 의 isGroupResultError 를 쓰지 않아 조회 실패가 "참여한 친구가 없어요" 로 표시됐다. 실패 안내를 분리한다. --- .../tournament-card/FriendListDialog.tsx | 25 +++- .../tournament-card/MorePopover.tsx | 137 +++++++++--------- 2 files changed, 91 insertions(+), 71 deletions(-) diff --git a/apps/web/src/components/tournament-card/FriendListDialog.tsx b/apps/web/src/components/tournament-card/FriendListDialog.tsx index 26718962..e28ac099 100644 --- a/apps/web/src/components/tournament-card/FriendListDialog.tsx +++ b/apps/web/src/components/tournament-card/FriendListDialog.tsx @@ -41,9 +41,10 @@ const toUser = (friend: FriendListItemT): UserT => ({ function FriendListDialog({ open, onOpenChange, tournamentId }: FriendListDialogProps) { // 모달이 열렸을 때만 group-result fetch. - const { groupResultData, isGroupResultPending } = useGetGroupResult(tournamentId, { - enabled: open, - }); + const { groupResultData, isGroupResultPending, isGroupResultError } = useGetGroupResult( + tournamentId, + { enabled: open } + ); const { userData } = useGetMe(); const myUserId = userData.id; @@ -78,7 +79,11 @@ function FriendListDialog({ open, onOpenChange, tournamentId }: FriendListDialog 이 토너먼트에 참여한 친구 목록입니다. - + ); @@ -86,10 +91,11 @@ function FriendListDialog({ open, onOpenChange, tournamentId }: FriendListDialog type FriendListBodyProps = { isPending: boolean; + isError: boolean; friends: FriendListItemT[]; }; -function FriendListBody({ isPending, friends }: FriendListBodyProps) { +function FriendListBody({ isPending, isError, friends }: FriendListBodyProps) { if (isPending) { return (
@@ -98,6 +104,15 @@ function FriendListBody({ isPending, friends }: FriendListBodyProps) { ); } + /** 조회 실패를 빈 목록으로 뭉뚱그리면 "친구 없음" 으로 잘못 안내된다 */ + if (isError) { + return ( +

+ 친구 목록을 불러오지 못했어요. +

+ ); + } + if (friends.length === 0) { return (

diff --git a/apps/web/src/components/tournament-card/MorePopover.tsx b/apps/web/src/components/tournament-card/MorePopover.tsx index af5b986b..2efae3f0 100644 --- a/apps/web/src/components/tournament-card/MorePopover.tsx +++ b/apps/web/src/components/tournament-card/MorePopover.tsx @@ -1,7 +1,7 @@ 'use client'; import { useRouter } from 'next/navigation'; -import { type ComponentType, type SVGProps, useState } from 'react'; +import { type ComponentType, type MouseEvent, type SVGProps, useState } from 'react'; import { GroupIconFill, @@ -57,76 +57,81 @@ function MorePopover({ status, tournamentId, participantCount = 0 }: MorePopover router.push(ROUTES.TOURNAMENT_RESULT(tournamentId)); }; + /** 카드 전체가 Link 라 더보기 조작이 페이지 이동으로 이어지지 않게 막는다 */ + const handleStopCardNavigation = (event: MouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + }; + return ( -

{ - event.preventDefault(); - event.stopPropagation(); - }} - > - - - - - - 더보기 - - {status === TOURNAMENT_STATUS.PENDING && ( - <> - - - - )} - - {status === TOURNAMENT_STATUS.IN_PROGRESS && ( - <> - {/* + <> + {/* + Dialog 는 이 래퍼 밖에 둔다 — 안에 두면 딤 클릭이 stopPropagation 에 막혀 닫히지 않는다. + */} +
+ + + + + + 더보기 + + {status === TOURNAMENT_STATUS.PENDING && ( + <> + + + + )} + + {status === TOURNAMENT_STATUS.IN_PROGRESS && ( + <> + {/* TODO: IN_PROGRESS 참여자 API 가 추가되면 친구 목록 보기 노출. 현재는 group-result(COMPLETED 전용) 만 사용 가능해 데이터를 못 받으므로 미노출. */} - - - )} - - {status === TOURNAMENT_STATUS.COMPLETED && ( - <> - {hasInvitedFriends && ( + + )} + + {status === TOURNAMENT_STATUS.COMPLETED && ( + <> + {hasInvitedFriends && ( + + )} + + - )} - - - - )} - - + + )} + + +
-
+ ); }