Skip to content

Commit 9410991

Browse files
committed
feat(#99) :: 챌린지 리스트에서도 북마크 가능하게 수정
1 parent a027e04 commit 9410991

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

src/app/(private)/challenge/page.tsx

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import ChallengeContent from '@/components/Challenge/ChallengeContent';
88
import Header from '@/components/shared/Header';
99
import { ChallengeType, ChallengeFilter } from '@/types/Challenge';
1010
import { useGetChallenge } from '@/service/Challenge/challenge.query';
11+
import { useGetBookmarkList } from '@/service/shared/shared.query';
12+
import { useBookmark } from '@/hooks/useBookmark';
1113
import Loading from '@/components/shared/Loading';
1214

1315
const challengeCategories = [
@@ -75,6 +77,43 @@ const Challenge = () => {
7577
};
7678

7779
const { data: ChallengeData, isPending } = useGetChallenge(filterParams);
80+
const { data: bookmarkData } = useGetBookmarkList();
81+
82+
// 북마크된 챌린지 ID들을 배열로 저장
83+
const bookmarkedChallengeIds =
84+
bookmarkData?.data?.map(
85+
(bookmark: { challengeId: number }) => bookmark.challengeId
86+
) || [];
87+
88+
// 개별 챌린지의 북마크 기능을 위한 컴포넌트
89+
const ChallengeWithBookmark = ({
90+
challenge,
91+
}: {
92+
challenge: ChallengeType;
93+
}) => {
94+
const isInitiallyBookmarked = bookmarkedChallengeIds.includes(challenge.id);
95+
const { isBookmarked, toggleBookmark, isLoading } = useBookmark({
96+
challengeId: challenge.id,
97+
initialBookmarkState: isInitiallyBookmarked,
98+
});
99+
100+
return (
101+
<ChallengeContent
102+
key={challenge.id}
103+
id={challenge.id}
104+
count={challenge.participantCount}
105+
title={challenge.title}
106+
imgUrl={challenge.imgURL}
107+
days={Number(challenge.day)}
108+
difficulty={challenge.difficulty}
109+
createrName={challenge.User.name}
110+
createrImgUrl={challenge.User.profileImg}
111+
isChecked={isBookmarked}
112+
onClickBookmark={toggleBookmark}
113+
isBookmarkLoading={isLoading}
114+
/>
115+
);
116+
};
78117

79118
const hasActiveFilters = Object.values(filters).some(
80119
(v) => v !== '전체' && v !== '인기순'
@@ -156,17 +195,7 @@ const Challenge = () => {
156195
<div className="flex-1 h-0 min-h-0 px-8 pb-16 mt-2 overflow-y-scroll scrollbar-hide -webkit-overflow-scrolling-touch overscroll-contain">
157196
<div className="grid grid-cols-2 gap-x-5 gap-y-5">
158197
{ChallengeData?.data?.challenges?.map((item: ChallengeType) => (
159-
<ChallengeContent
160-
key={item.id}
161-
id={item.id}
162-
count={item.participantCount}
163-
title={item.title}
164-
imgUrl={item.imgURL}
165-
days={Number(item.day)}
166-
difficulty={item.difficulty}
167-
createrName={item.User.name}
168-
createrImgUrl={item.User.profileImg}
169-
/>
198+
<ChallengeWithBookmark key={item.id} challenge={item} />
170199
))}
171200
</div>
172201
</div>

src/components/Challenge/ChallengeContent.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface OwnProps {
1414
days: number;
1515
isChecked?: boolean;
1616
onClickBookmark?: () => void;
17+
isBookmarkLoading?: boolean;
1718
link?: string;
1819
}
1920

@@ -28,6 +29,7 @@ const ChallengeContent = ({
2829
days,
2930
isChecked = false,
3031
onClickBookmark,
32+
isBookmarkLoading = false,
3133
link = `/challenge/${id}`,
3234
}: OwnProps) => {
3335
return (
@@ -43,14 +45,15 @@ const ChallengeContent = ({
4345
>
4446
<div className="flex flex-col justify-between h-full w-full px-[0.66rem] py-2">
4547
<button
46-
className="flex justify-end w-full"
48+
className={`flex justify-end w-full ${isBookmarkLoading ? 'opacity-50 pointer-events-none' : ''}`}
4749
onClick={(e) => {
4850
e.stopPropagation();
4951
e.preventDefault();
50-
if (onClickBookmark) {
52+
if (onClickBookmark && !isBookmarkLoading) {
5153
onClickBookmark();
5254
}
5355
}}
56+
disabled={isBookmarkLoading}
5457
>
5558
<BookmarkIcon isChecked={isChecked && isChecked} />
5659
</button>

0 commit comments

Comments
 (0)