Skip to content

Commit 02d0a1f

Browse files
authored
Merge pull request #187 from PNUops/feat/remain-like-count
feat: 남은 좋아요 개수 표현 툴팁 구현
2 parents a9a09b3 + 1d29900 commit 02d0a1f

3 files changed

Lines changed: 58 additions & 12 deletions

File tree

src/apis/projectViewer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CommentEditRequestDto,
99
CommentDto,
1010
PreviewResult,
11+
LikeUpdateResponseDto,
1112
} from 'types/DTO/projectViewerDto';
1213

1314
export const getProjectDetails = async (teamId: number): Promise<ProjectDetailsResponseDto> => {
@@ -43,7 +44,7 @@ export const getPreviewImages = async (teamId: number, imageIds: number[]): Prom
4344
return { imageResults };
4445
};
4546

46-
export const patchLikeToggle = async (request: LikeUpdateRequestDto) => {
47+
export const patchLikeToggle = async (request: LikeUpdateRequestDto): Promise<LikeUpdateResponseDto> => {
4748
const { teamId, isLiked } = request;
4849
const response = await apiClient.patch(`/teams/${teamId}/like`, { isLiked });
4950
return response.data;

src/pages/project-viewer/LikeSection.tsx

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
};

src/types/DTO/projectViewerDto.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ export interface LikeUpdateRequestDto {
6666
teamId: number;
6767
isLiked: boolean;
6868
}
69+
export interface LikeUpdateResponseDto {
70+
teamId: number;
71+
isLiked: boolean;
72+
message: string;
73+
remainingLikeCount: number;
74+
maxLikeCount: number;
75+
}
6976

7077
export interface PreviewImage {
7178
id?: number;

0 commit comments

Comments
 (0)