|
1 | 1 | import { useState } from 'react'; |
2 | 2 |
|
3 | | -import { QueryClient, useMutation } from '@tanstack/react-query'; |
4 | | - |
5 | 3 | import { postLike, deleteLike } from '@/api/handleLikeRequest'; |
6 | 4 | import FullLikeIcon from '@/assets/icons/fullLike.svg'; |
7 | 5 | import LikeIcon from '@/assets/icons/like.svg'; |
8 | 6 | import { Button } from '@/components/ui/button'; |
| 7 | +import { useUser } from '@/hooks/useUser'; |
9 | 8 | import { cn } from '@/lib/utils'; |
| 9 | +import useReviewCardStore from '@/stores/reviewCardStore'; |
| 10 | + |
| 11 | +import ErrorModal from '../common/Modal/ErrorModal'; |
10 | 12 |
|
11 | 13 | interface Props { |
12 | 14 | isLike?: boolean; |
13 | 15 | reviewId: number; |
14 | 16 | } |
15 | 17 |
|
16 | | -const queryClient = new QueryClient(); |
17 | | - |
18 | | -export function usePostLikeMutation() { |
19 | | - return useMutation({ |
20 | | - mutationFn: (reviewId: number) => postLike(reviewId), |
21 | | - onSuccess: () => { |
22 | | - queryClient.invalidateQueries({ queryKey: ['wineDetail'] }); // 필요한 캐시 무효화 |
23 | | - }, |
24 | | - throwOnError: true, |
25 | | - }); |
26 | | -} |
27 | | - |
28 | | -export function useDeleteLikeMutation() { |
29 | | - return useMutation({ |
30 | | - mutationFn: (reviewId: number) => deleteLike(reviewId), |
31 | | - onSuccess: () => { |
32 | | - queryClient.invalidateQueries({ queryKey: ['wineDetail'] }); |
33 | | - }, |
34 | | - throwOnError: true, |
35 | | - }); |
36 | | -} |
37 | | - |
38 | 18 | function LikeButton({ isLike, reviewId }: Props) { |
39 | 19 | const [isClicked, setIsClicked] = useState(isLike); |
40 | | - const postLikeMutation = usePostLikeMutation(); |
41 | | - const deleteLikeMutation = useDeleteLikeMutation(); |
| 20 | + const [openAlertModal, setOpenAlertModal] = useState(false); |
42 | 21 |
|
43 | | - async function handleToggle() { |
44 | | - setIsClicked((prev) => !prev); //미리 업데이트 |
| 22 | + const { user } = useUser(); |
| 23 | + const id = useReviewCardStore((state) => state.allReviews[reviewId]?.user.id); |
45 | 24 |
|
46 | | - try { |
47 | | - isClicked |
48 | | - ? await deleteLikeMutation.mutateAsync(reviewId) |
49 | | - : await postLikeMutation.mutateAsync(reviewId); |
50 | | - } catch (err) { |
51 | | - setIsClicked((prev) => !prev); //실패하면 업데이트 했던 거 취소 |
52 | | - } |
| 25 | + async function handleToggle() { |
| 26 | + if (user?.id !== id) { |
| 27 | + setIsClicked((prev) => !prev); |
| 28 | + try { |
| 29 | + isClicked ? await deleteLike(reviewId) : await postLike(reviewId); |
| 30 | + } catch (err) { |
| 31 | + setIsClicked((prev) => !prev); //실패하면 업데이트 했던 거 취소 |
| 32 | + } |
| 33 | + } else { |
| 34 | + setOpenAlertModal(true); |
| 35 | + } //미리 업데이트 |
53 | 36 | } |
54 | 37 | return ( |
55 | | - <Button |
56 | | - onClick={handleToggle} |
57 | | - variant='onlyCancel' |
58 | | - className={cn( |
59 | | - 'border-0 hover:text-primary w-8 h-8 md:w-9.5 md:h-9.5 mr-4.5 md:mr-5 [&_svg]:w-8 [&_svg]:h-8', |
60 | | - { 'text-primary': isClicked }, |
| 38 | + <> |
| 39 | + <Button |
| 40 | + onClick={handleToggle} |
| 41 | + variant='onlyCancel' |
| 42 | + className={cn( |
| 43 | + 'border-0 hover:text-primary w-8 h-8 md:w-9.5 md:h-9.5 mr-4.5 md:mr-5 [&_svg]:w-8 [&_svg]:h-8', |
| 44 | + { 'text-primary': isClicked }, |
| 45 | + )} |
| 46 | + > |
| 47 | + {isClicked ? <FullLikeIcon /> : <LikeIcon />} |
| 48 | + </Button> |
| 49 | + {openAlertModal && ( |
| 50 | + <ErrorModal |
| 51 | + open={openAlertModal} |
| 52 | + onOpenChange={() => {}} |
| 53 | + onConfirm={() => setOpenAlertModal(false)} |
| 54 | + > |
| 55 | + <div className='custom-text-lg-bold'> |
| 56 | + 본인이 작성한 리뷰에는 좋아요를 할 수 없습니다.{' '} |
| 57 | + </div> |
| 58 | + </ErrorModal> |
61 | 59 | )} |
62 | | - > |
63 | | - {isClicked ? <FullLikeIcon /> : <LikeIcon />} |
64 | | - </Button> |
| 60 | + </> |
65 | 61 | ); |
66 | 62 | } |
67 | 63 |
|
|
0 commit comments