import React, { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { API_URL, toggleVideoLike, isLoggedIn } from '../utils/api'; import { buildContentShareUrl, tryNativeShare } from '../utils/nativeShare'; import LoginPromptModal from './LoginPromptModal'; interface ContentCardSocialActionsProps { videoId: number; /** * 콘텐츠 종류. video.id 와 ssul_content.id 가 겹치므로 좋아요 API 와 * 공유 URL(/video/{id} vs /ssul/{id}) 분기에 반드시 필요하다. * ContentType 전체가 아니라 이 둘로 좁힌 이유: 좋아요·공유 축은 video·ssul * 에만 있다 — P2V 항목은 이 컴포넌트를 렌더하지 않는다(MyContentsPage 분기). */ contentType?: 'video' | 'ssul'; storeName: string; region?: string; title?: string | null; description?: string | null; commentCount: number; initialLikeCount: number; initialIsLiked?: boolean; } const ContentCardSocialActions: React.FC = ({ videoId, contentType = 'video', storeName, region, title, description, commentCount, initialLikeCount, initialIsLiked = false, }) => { const { t } = useTranslation(); const [likeCount, setLikeCount] = useState(initialLikeCount); const [isLiked, setIsLiked] = useState(initialIsLiked); const [showLoginModal, setShowLoginModal] = useState(false); const likeDebounceRef = useRef | null>(null); const shareUrl = buildContentShareUrl(API_URL, videoId, contentType); const shareTitle = title || storeName || t('videoDetail.kakaoDefaultTitle'); const handleShareBtnClick = async (e: React.MouseEvent) => { e.stopPropagation(); const handled = await tryNativeShare({ title: shareTitle, url: shareUrl, }); if (handled) { return; } try { await navigator.clipboard.writeText(shareUrl); } catch { // clipboard API 미지원 환경에서는 무시 } }; const handleLikeClick = (e: React.MouseEvent) => { e.stopPropagation(); if (!isLoggedIn()) { setShowLoginModal(true); return; } const prevLiked = isLiked; const prevCount = likeCount; setIsLiked(!prevLiked); setLikeCount(prevLiked ? prevCount - 1 : prevCount + 1); if (likeDebounceRef.current) clearTimeout(likeDebounceRef.current); likeDebounceRef.current = setTimeout(async () => { try { const res = await toggleVideoLike(String(videoId), contentType); setIsLiked(res.is_liked); setLikeCount(res.like_count); } catch (err) { console.error('Failed to toggle like:', err); setIsLiked(prevLiked); setLikeCount(prevCount); } }, 500); }; return (
e.stopPropagation()}> {commentCount} {showLoginModal && ( setShowLoginModal(false)} /> )}
); }; export default ContentCardSocialActions;