-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: LikeButton 컴포넌트 작성 * feat: LikeButton 컴포넌트 작성 * refactor: LikeButton 컴포넌트 타입 지정부 수정 * refactor: 유저 책장 페이지 LikeButton 교체 * refactor: 책장 좋아요 Query 리팩터링 * chore: useMutateBookshelfLikeQuery 이름 변경 * fix: 빌드 에러 수정 * chore: useMutateBookshelfLikeQuery 파라미터 객체로 감싼 것 제거 * chore: 좋아요 버튼 스타일 수정 * fix: LikeButton 컴포넌트 onClick props 옵셔널로 수정
- Loading branch information
Showing
5 changed files
with
132 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { useMutation, useQueryClient } from '@tanstack/react-query'; | ||
import type { APIBookshelfInfo } from '@/types/bookshelf'; | ||
import bookshelfAPI from '@/apis/bookshelf'; | ||
import bookShelfKeys from './key'; | ||
|
||
const useMutateBookshelfLikeQuery = ( | ||
bookshelfId: APIBookshelfInfo['bookshelfId'] | ||
) => { | ||
const queryClient = useQueryClient(); | ||
|
||
return useMutation({ | ||
mutationFn: async (isLiked: APIBookshelfInfo['isLiked']) => | ||
!isLiked | ||
? bookshelfAPI.likeBookshelf(bookshelfId) | ||
: bookshelfAPI.unlikeBookshelf(bookshelfId), | ||
onMutate: async () => { | ||
await queryClient.cancelQueries(bookShelfKeys.info(bookshelfId)); | ||
|
||
const prevData = queryClient.getQueryData<APIBookshelfInfo>( | ||
bookShelfKeys.info(bookshelfId) | ||
); | ||
|
||
if (prevData) { | ||
const newData: APIBookshelfInfo = { | ||
...prevData, | ||
isLiked: !prevData.isLiked, | ||
likeCount: prevData.isLiked | ||
? prevData.likeCount - 1 | ||
: prevData.likeCount + 1, | ||
}; | ||
|
||
queryClient.setQueryData<APIBookshelfInfo>( | ||
bookShelfKeys.info(bookshelfId), | ||
newData | ||
); | ||
} | ||
|
||
return { prevData }; | ||
}, | ||
onError: (_error, _value, context) => { | ||
queryClient.setQueryData( | ||
bookShelfKeys.info(bookshelfId), | ||
context?.prevData | ||
); | ||
}, | ||
onSettled: () => { | ||
queryClient.invalidateQueries(bookShelfKeys.info(bookshelfId)); | ||
}, | ||
}); | ||
}; | ||
|
||
export default useMutateBookshelfLikeQuery; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import LikeButton from '@/v1/base/LikeButton'; | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
|
||
const meta: Meta<typeof LikeButton> = { | ||
title: 'Base/LikeButton', | ||
component: LikeButton, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof LikeButton>; | ||
|
||
export const Default: Story = { | ||
args: { | ||
isLiked: false, | ||
likeCount: 10, | ||
}, | ||
}; | ||
|
||
export const IsLiked: Story = { | ||
args: { | ||
isLiked: true, | ||
likeCount: 999, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { APIBookshelfInfo } from '@/types/bookshelf'; | ||
import { IconHeart } from '@public/icons'; | ||
|
||
type LikeButtonProps = { | ||
isLiked: APIBookshelfInfo['isLiked']; | ||
likeCount: APIBookshelfInfo['likeCount']; | ||
onClick?: () => void; | ||
}; | ||
|
||
const LikeButton = ({ isLiked, likeCount, onClick }: LikeButtonProps) => { | ||
const BG_COLOR_CLASS = isLiked ? 'bg-warning-800' : 'bg-white'; | ||
const ICON_COLOR_CLASS = isLiked ? 'stroke-white' : 'stroke-warning-800'; | ||
const TEXT_COLOR_CLASS = isLiked ? 'text-white' : 'text-warning-800'; | ||
|
||
return ( | ||
<button | ||
onClick={onClick} | ||
className={`${BG_COLOR_CLASS} flex h-[2.4rem] min-w-[5.6rem] items-center gap-[0.4rem] rounded-full border-[0.1rem] border-warning-800 bg-warning-800 px-[1rem]`} | ||
> | ||
<IconHeart | ||
className={`${ICON_COLOR_CLASS} h-[1.5rem] w-[1.5rem] fill-white stroke-[0.15rem]`} | ||
/> | ||
<p | ||
className={`${TEXT_COLOR_CLASS} min-w-[1.5rem] text-center text-xs font-bold`} | ||
> | ||
{likeCount} | ||
</p> | ||
</button> | ||
); | ||
}; | ||
|
||
export default LikeButton; |