import { useState } from 'react'; import { ShareButton } from './ShareButton'; import { CopyLinkButton } from './CopyLinkButton'; import { type SharePlatform, type ShareData, getShareUrl } from '@/lib/social-utils'; import { trackShare } from '@/lib/analytics'; export type SocialShareVariant = 'default' | 'compact' | 'footer' | 'floating'; interface SocialShareButtonsProps extends ShareData { articleId: string; variant?: SocialShareVariant; className?: string; onShare?: (platform: SharePlatform) => void; } const PLATFORMS: SharePlatform[] = ['facebook', 'twitter', 'whatsapp', 'telegram', 'email', 'link']; export function SocialShareButtons({ articleId, title, url, excerpt, image, tags, variant = 'default', className = '', onShare, }: SocialShareButtonsProps) { const [isTracking, setIsTracking] = useState(false); const [isExpanded, setIsExpanded] = useState(false); const shareData: ShareData = { title, url, excerpt, image, tags, }; const handleShare = async (platform: SharePlatform) => { try { // Track the share event setIsTracking(true); await trackShare({ articleId, platform, userAgent: navigator.userAgent, // Note: We don't send IP address from frontend for privacy reasons // Backend should extract it from the request if needed }); // Call the onShare callback if provided if (onShare) { onShare(platform); } // Open share URL in new window for social platforms if (platform !== 'link') { const shareUrl = getShareUrl(platform, shareData); window.open(shareUrl, '_blank', 'noopener,noreferrer'); } } catch (error) { console.error('Failed to track share:', error); // Still open the share URL even if tracking fails if (platform !== 'link') { const shareUrl = getShareUrl(platform, shareData); window.open(shareUrl, '_blank', 'noopener,noreferrer'); } } finally { setIsTracking(false); } }; const handleCopyLink = async (success: boolean) => { if (success) { await handleShare('link'); } }; // Determine layout based on variant const getLayoutClasses = () => { switch (variant) { case 'compact': return 'flex items-center space-x-1'; case 'footer': return 'flex flex-col sm:flex-row items-center justify-center space-y-2 sm:space-y-0 sm:space-x-4'; case 'floating': return 'fixed right-4 bottom-4 flex flex-col space-y-2 z-50'; default: return 'flex flex-wrap items-center gap-2'; } }; const getButtonSize = () => { switch (variant) { case 'compact': return 'sm' as const; case 'footer': return 'default' as const; case 'floating': return 'default' as const; default: return 'default' as const; } }; const getButtonVariant = () => { switch (variant) { case 'compact': return 'ghost' as const; case 'footer': return 'outline' as const; case 'floating': return 'default' as const; default: return 'outline' as const; } }; const showLabels = variant === 'footer'; // For compact variant, only show a single share button that expands on hover if (variant === 'compact') { return (
setIsExpanded(true)} onMouseLeave={() => setIsExpanded(false)} >
handleShare('link')} size={getButtonSize()} variant={getButtonVariant()} disabled={isTracking} /> {isExpanded && (
{PLATFORMS.filter(p => p !== 'link').map((platform) => ( handleShare(platform)} size={getButtonSize()} variant={getButtonVariant()} disabled={isTracking} /> ))}
)}
); } return (
{PLATFORMS.map((platform) => { if (platform === 'link') { return ( ); } return ( handleShare(platform)} size={getButtonSize()} variant={getButtonVariant()} disabled={isTracking} showLabel={showLabels} /> ); })}
); }