121 lines
3.4 KiB
TypeScript
121 lines
3.4 KiB
TypeScript
|
|
import { useAuth } from '../../../contexts/AuthContext';
|
|
import { useReactionCounts, useUserReaction, useAddReaction } from '../../../queries/comments';
|
|
import { Button } from '../../ui/button';
|
|
import { ThumbsUp, ThumbsDown } from 'lucide-react';
|
|
import { usePostHog } from '@posthog/react';
|
|
|
|
interface ReactionButtonsProps {
|
|
articleId?: string;
|
|
liveBlogId?: string;
|
|
commentId?: string;
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function ReactionButtons({
|
|
articleId,
|
|
liveBlogId,
|
|
commentId,
|
|
compact = false
|
|
}: ReactionButtonsProps) {
|
|
const { isAuthenticated } = useAuth();
|
|
const posthog = usePostHog();
|
|
|
|
const { data: counts } = useReactionCounts(articleId, liveBlogId, commentId);
|
|
const { data: userReaction } = useUserReaction(articleId, liveBlogId, commentId);
|
|
const addReactionMutation = useAddReaction();
|
|
|
|
const userReactionType = userReaction?.type;
|
|
|
|
const handleReaction = async (type: 'like' | 'dislike') => {
|
|
if (!isAuthenticated) {
|
|
window.location.href = '/auth';
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await addReactionMutation.mutateAsync({
|
|
type,
|
|
articleId,
|
|
liveBlogId,
|
|
commentId,
|
|
});
|
|
posthog.capture('article_reaction_added', {
|
|
reaction_type: type,
|
|
article_id: articleId,
|
|
live_blog_id: liveBlogId,
|
|
comment_id: commentId,
|
|
target_type: commentId ? 'comment' : liveBlogId ? 'live_blog' : 'article',
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to add reaction:', error);
|
|
}
|
|
};
|
|
|
|
const likes = counts?.likes || 0;
|
|
const dislikes = counts?.dislikes || 0;
|
|
|
|
if (compact) {
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => handleReaction('like')}
|
|
className={`h-8 px-2 ${userReactionType === 'like' ? 'text-primary' : ''}`}
|
|
>
|
|
<ThumbsUp className="w-4 h-4 mr-1" />
|
|
{likes > 0 && <span>{likes}</span>}
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => handleReaction('dislike')}
|
|
className={`h-8 px-2 ${userReactionType === 'dislike' ? 'text-destructive' : ''}`}
|
|
>
|
|
<ThumbsDown className="w-4 h-4 mr-1" />
|
|
{dislikes > 0 && <span>{dislikes}</span>}
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex items-center gap-4">
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
variant={userReactionType === 'like' ? 'default' : 'outline'}
|
|
size="sm"
|
|
onClick={() => handleReaction('like')}
|
|
className="gap-2"
|
|
>
|
|
<ThumbsUp className="w-4 h-4" />
|
|
<span>Ми се допаѓа</span>
|
|
{likes > 0 && (
|
|
<span className="ml-1 bg-primary/20 px-2 py-0.5 rounded-full text-xs">
|
|
{likes}
|
|
</span>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
variant={userReactionType === 'dislike' ? 'destructive' : 'outline'}
|
|
size="sm"
|
|
onClick={() => handleReaction('dislike')}
|
|
className="gap-2"
|
|
>
|
|
<ThumbsDown className="w-4 h-4" />
|
|
<span>Не ми се допаѓа</span>
|
|
{dislikes > 0 && (
|
|
<span className="ml-1 bg-destructive/20 px-2 py-0.5 rounded-full text-xs">
|
|
{dislikes}
|
|
</span>
|
|
)}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|