source: chapterx-frontend/src/components/story/LikeButton.tsx@ 99c1e45

main
Last change on this file since 99c1e45 was 99c1e45, checked in by kikisrbinoska <srbinoskakristina07@…>, 11 days ago

Fixed writer section and admin management

  • Property mode set to 100644
File size: 3.0 KB
Line 
1import React, { useEffect, useState } from 'react'
2import { Heart } from 'lucide-react'
3import { useNavigate } from 'react-router-dom'
4import axios from 'axios'
5import { useAuthStore } from '../../store/authStore'
6import { useNotificationStore } from '../../store/notificationStore'
7import { useUIStore } from '../../store/uiStore'
8
9const API = 'https://localhost:7125/api'
10
11interface LikeButtonProps {
12 storyId: number
13 authorUserId: number
14 totalLikes: number
15 onCountChange?: (count: number) => void
16}
17
18export const LikeButton: React.FC<LikeButtonProps> = ({ storyId, authorUserId, totalLikes, onCountChange }) => {
19 const navigate = useNavigate()
20 const { currentUser, token } = useAuthStore()
21 const { addNotification } = useNotificationStore()
22 const authHeaders = token ? { Authorization: `Bearer ${token}` } : {}
23 const { addToast } = useUIStore()
24 const [liked, setLiked] = useState(false)
25 const [count, setCount] = useState(totalLikes)
26 const [loading, setLoading] = useState(false)
27
28 useEffect(() => {
29 axios.get(`${API}/likes/story/${storyId}`)
30 .then(res => {
31 const c = res.data?.count ?? totalLikes
32 setCount(c)
33 onCountChange?.(c)
34 if (currentUser) {
35 setLiked((res.data?.userIds ?? []).includes(currentUser.user_id))
36 }
37 })
38 .catch(() => {})
39 }, [storyId, currentUser?.user_id])
40
41 const handleClick = async () => {
42 if (!currentUser) {
43 addToast('Please sign in to like stories.', 'info')
44 navigate('/login')
45 return
46 }
47 if (loading) return
48 setLoading(true)
49 try {
50 if (liked) {
51 await axios.delete(`${API}/likes/user/${currentUser.user_id}/story/${storyId}`, { headers: authHeaders })
52 setLiked(false)
53 setCount(c => { const n = c - 1; onCountChange?.(n); return n })
54 addToast('Removed from likes', 'info')
55 } else {
56 await axios.post(`${API}/likes`, { userId: currentUser.user_id, storyId }, { headers: authHeaders })
57 setLiked(true)
58 setCount(c => { const n = c + 1; onCountChange?.(n); return n })
59 if (currentUser.user_id !== authorUserId) {
60 await addNotification({
61 recipientUserId: authorUserId,
62 type: 'like',
63 content: `${currentUser.username} liked your story.`,
64 link: `/story/${storyId}`,
65 })
66 }
67 addToast('Added to likes!', 'success')
68 }
69 } catch {
70 addToast('Something went wrong.', 'error')
71 }
72 setLoading(false)
73 }
74
75 return (
76 <button
77 onClick={handleClick}
78 disabled={loading}
79 className={`flex items-center gap-2 px-4 py-2 rounded-xl border transition-all duration-200 ${
80 liked
81 ? 'bg-rose-500/20 border-rose-500/40 text-rose-400 hover:bg-rose-500/30'
82 : 'bg-slate-800 border-slate-700 text-slate-400 hover:border-rose-500/40 hover:text-rose-400 hover:bg-rose-500/10'
83 }`}
84 >
85 <Heart size={16} className={liked ? 'fill-rose-400' : ''} />
86 <span className="text-sm font-medium">{count.toLocaleString()}</span>
87 </button>
88 )
89}
Note: See TracBrowser for help on using the repository browser.