@@ -19,15 +19,28 @@ const LikeSection = ({ contestId, teamId, isLiked }: LikeSectionProps) => {
1919 const navigate = useNavigate ( ) ;
2020 const toast = useToast ( ) ;
2121
22+ const [ showLikeCountTooltip , setShowLikeCountTooltip ] = useState ( false ) ;
23+ const [ likeCount , setLikeCount ] = useState < number | null > ( null ) ;
24+ const handleLikeCountTooltip = ( likeCount : number ) => {
25+ setLikeCount ( likeCount ) ;
26+ setShowLikeCountTooltip ( true ) ;
27+ setTimeout ( ( ) => setShowLikeCountTooltip ( false ) , 2000 ) ;
28+ } ;
29+
2230 const queryClient = useQueryClient ( ) ;
2331 const { user } = useAuth ( ) ;
2432 const likeMutation = useMutation ( {
2533 mutationFn : ( nextIsLiked : boolean ) => patchLikeToggle ( { teamId, isLiked : nextIsLiked } ) ,
26- onSuccess : ( ) => {
34+ onSuccess : ( res ) => {
2735 queryClient . invalidateQueries ( { queryKey : [ 'projectDetails' , teamId ] } ) ;
2836 queryClient . invalidateQueries ( { queryKey : [ 'teams' , 'current' , user ?. id ?? 'guest' ] } ) ;
2937 queryClient . invalidateQueries ( { queryKey : [ 'teams' , contestId , user ?. id ?? 'guest' ] } ) ;
3038 toast ( ! isLiked ? '좋아요를 눌렀어요' : '좋아요를 취소했어요' ) ;
39+
40+ handleLikeCountTooltip ( res . remainingLikeCount ) ;
41+ } ,
42+ onError : ( err : any ) => {
43+ toast ( err . response . data . message ?? '요청에 실패했어요' , 'error' ) ;
3144 } ,
3245 } ) ;
3346
@@ -42,16 +55,18 @@ const LikeSection = ({ contestId, teamId, isLiked }: LikeSectionProps) => {
4255
4356 return (
4457 < LikeAbuseToolTip >
45- < button
46- onClick = { handleClick }
47- disabled = { likeMutation . isPending }
48- className = { `${
49- isLiked ? 'bg-mainGreen text-white hover:bg-emerald-600' : 'bg-lightGray text-white hover:bg-gray-300'
50- } relative flex cursor-pointer items-center gap-5 justify-self-center rounded-full p-4 text-sm sm:px-8 sm:py-3`}
51- >
52- < FaHeart className = { `${ isLiked ? 'text-white' : 'text-whiteGray' } ` } size = { 20 } />
53- < span className = "hidden sm:inline" > 좋아요</ span >
54- </ button >
58+ < LikeCountToolTip isOpen = { showLikeCountTooltip } likeCount = { likeCount } >
59+ < button
60+ onClick = { handleClick }
61+ disabled = { likeMutation . isPending }
62+ className = { `${
63+ isLiked ? 'bg-mainGreen text-white hover:bg-emerald-600' : 'bg-lightGray text-white hover:bg-gray-300'
64+ } relative flex cursor-pointer items-center gap-5 justify-self-center rounded-full p-4 text-sm sm:px-8 sm:py-3`}
65+ >
66+ < FaHeart className = { `${ isLiked ? 'text-white' : 'text-whiteGray' } ` } size = { 20 } />
67+ < span className = "hidden sm:inline" > 좋아요</ span >
68+ </ button >
69+ </ LikeCountToolTip >
5570 </ LikeAbuseToolTip >
5671 ) ;
5772} ;
@@ -94,3 +109,26 @@ const LikeAbuseToolTip = ({ children }: { children: ReactNode }) => {
94109 </ div >
95110 ) ;
96111} ;
112+ const LikeCountToolTip = ( {
113+ isOpen,
114+ likeCount,
115+ children,
116+ } : {
117+ isOpen : boolean ;
118+ likeCount : number | null ;
119+ children : ReactNode ;
120+ } ) => {
121+ return (
122+ < Tooltip open = { isOpen && likeCount !== null } >
123+ < TooltipTrigger className = "z-50 rounded-lg bg-white p-2" > { children } </ TooltipTrigger >
124+ < TooltipContent className = "max-w-3xs duration-100" >
125+ < div className = "flex flex-col gap-2 p-2 text-base" >
126+ < p className = "break-keep" >
127+ < span > { '남은 좋아요 ' } </ span >
128+ < strong className = "text-mainBlue font-semibold" > { `${ likeCount } 개` } </ strong >
129+ </ p >
130+ </ div >
131+ </ TooltipContent >
132+ </ Tooltip >
133+ ) ;
134+ } ;
0 commit comments