| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- 'use client';
- import { useState } from 'react';
- import { Heart, MessageCircle, Share2, MoreHorizontal, Bookmark, Link as LinkIcon, Flag } from 'lucide-react';
- import { fetchApi } from '@/lib/utils/client';
- import useAuth from '@/hooks/useAuth';
- import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger
- } from '@/components/ui/dropdown-menu';
- type Props = {
- postID: number;
- initialLikes: number;
- initialComments: number;
- initialBookmarks: number;
- };
- export default function FeedActionBar({ postID, initialLikes, initialComments }: Props) {
- const { loginCheck } = useAuth();
- const [likes, setLikes] = useState(initialLikes);
- const [liked, setLiked] = useState(false);
- const [bookmarked, setBookmarked] = useState(false);
- const [busy, setBusy] = useState(false);
- const handleLike = async () => {
- if (!loginCheck() || busy) {
- return;
- }
- setBusy(true);
- try {
- const res = await fetchApi<{ hasLike: boolean; likes: number }>(`/api/feed/post/${postID}/like`, {
- method: 'POST',
- silent: true
- });
- if (res.success && res.data) {
- setLiked(res.data.hasLike);
- setLikes(res.data.likes);
- }
- } catch (err) {
- console.error(err);
- } finally {
- setBusy(false);
- }
- };
- const handleBookmark = async () => {
- if (!loginCheck() || busy) {
- return;
- }
- setBusy(true);
- try {
- const res = await fetchApi<{ hasBookmark: boolean; bookmarks: number }>(`/api/feed/post/${postID}/bookmark`, {
- method: 'POST',
- silent: true
- });
- if (res.success && res.data) {
- setBookmarked(res.data.hasBookmark);
- }
- } catch (err) {
- console.error(err);
- } finally {
- setBusy(false);
- }
- };
- const handleShare = async () => {
- const url = `${window.location.origin}/feed/post/${postID}`;
- try {
- await navigator.clipboard.writeText(url);
- alert('링크가 복사되었습니다.');
- } catch {
- prompt('링크를 복사하세요:', url);
- }
- };
- return (
- <div className="feed__card-actions">
- <button type="button" className={`feed__action${liked ? ' feed__action--active' : ''}`} onClick={handleLike} aria-pressed={liked} aria-label="좋아요">
- <span className="feed__action-icon">
- <Heart size={18} fill={liked ? 'currentColor' : 'none'} />
- </span>
- <span className="feed__action-count">{likes}</span>
- </button>
- <a href={`/feed/post/${postID}`} className="feed__action" aria-label="답글">
- <span className="feed__action-icon">
- <MessageCircle size={18} />
- </span>
- <span className="feed__action-count">{initialComments}</span>
- </a>
- <button type="button" className="feed__action" onClick={handleShare} aria-label="공유">
- <span className="feed__action-icon">
- <Share2 size={18} />
- </span>
- </button>
- <DropdownMenu>
- <DropdownMenuTrigger asChild>
- <button type="button" className="feed__action" aria-label="더보기">
- <span className="feed__action-icon">
- <MoreHorizontal size={18} />
- </span>
- </button>
- </DropdownMenuTrigger>
- <DropdownMenuContent align="end">
- <DropdownMenuItem onClick={handleBookmark}>
- <Bookmark size={14} fill={bookmarked ? 'currentColor' : 'none'} className="mr-2" />
- {bookmarked ? '저장 해제' : '저장'}
- </DropdownMenuItem>
- <DropdownMenuItem onClick={handleShare}>
- <LinkIcon size={14} className="mr-2" />
- 링크 복사
- </DropdownMenuItem>
- <DropdownMenuItem>
- <Flag size={14} className="mr-2" />
- 신고
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- </div>
- );
- }
|