Changeset 73b69b2 for chapterx-frontend/src/components/story/LikeButton.tsx
- Timestamp:
- 03/24/26 22:13:36 (3 months ago)
- Branches:
- main
- Children:
- 7fbb91c
- Parents:
- acf690c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
chapterx-frontend/src/components/story/LikeButton.tsx
racf690c r73b69b2 1 import React from 'react'1 import React, { useEffect, useState } from 'react' 2 2 import { Heart } from 'lucide-react' 3 3 import { useNavigate } from 'react-router-dom' 4 import axios from 'axios' 4 5 import { useAuthStore } from '../../store/authStore' 5 import { useStoryStore } from '../../store/storyStore'6 6 import { useNotificationStore } from '../../store/notificationStore' 7 7 import { useUIStore } from '../../store/uiStore' 8 9 const API = 'https://localhost:7125/api' 10 11 function getAuthHeaders() { 12 try { 13 const token = JSON.parse(localStorage.getItem('chapterx-auth') || '{}')?.state?.token 14 return token ? { Authorization: `Bearer ${token}` } : {} 15 } catch { return {} } 16 } 8 17 9 18 interface LikeButtonProps { … … 11 20 authorUserId: number 12 21 totalLikes: number 22 onCountChange?: (count: number) => void 13 23 } 14 24 15 export const LikeButton: React.FC<LikeButtonProps> = ({ storyId, authorUserId, totalLikes }) => {25 export const LikeButton: React.FC<LikeButtonProps> = ({ storyId, authorUserId, totalLikes, onCountChange }) => { 16 26 const navigate = useNavigate() 17 27 const { currentUser } = useAuthStore() 18 const { toggleLike, isLiked } = useStoryStore()19 28 const { addNotification } = useNotificationStore() 20 29 const { addToast } = useUIStore() 30 const [liked, setLiked] = useState(false) 31 const [count, setCount] = useState(totalLikes) 32 const [loading, setLoading] = useState(false) 21 33 22 const liked = currentUser ? isLiked(currentUser.user_id, storyId) : false 34 useEffect(() => { 35 axios.get(`${API}/likes/story/${storyId}`) 36 .then(res => { 37 const c = res.data?.count ?? totalLikes 38 setCount(c) 39 onCountChange?.(c) 40 if (currentUser) { 41 setLiked((res.data?.userIds ?? []).includes(currentUser.user_id)) 42 } 43 }) 44 .catch(() => {}) 45 }, [storyId, currentUser?.user_id]) 23 46 24 const handleClick = () => {47 const handleClick = async () => { 25 48 if (!currentUser) { 26 49 addToast('Please sign in to like stories.', 'info') … … 28 51 return 29 52 } 30 toggleLike(currentUser.user_id, storyId) 31 if (!liked && currentUser.user_id !== authorUserId) { 32 addNotification({ 33 user_id: authorUserId, 34 type: 'like', 35 title: 'New Like', 36 message: `${currentUser.username} liked your story.`, 37 link: `/story/${storyId}`, 38 }) 53 if (loading) return 54 setLoading(true) 55 try { 56 if (liked) { 57 await axios.delete(`${API}/likes/user/${currentUser.user_id}/story/${storyId}`, { headers: getAuthHeaders() }) 58 setLiked(false) 59 setCount(c => { const n = c - 1; onCountChange?.(n); return n }) 60 addToast('Removed from likes', 'info') 61 } else { 62 await axios.post(`${API}/likes`, { userId: currentUser.user_id, storyId }, { headers: getAuthHeaders() }) 63 setLiked(true) 64 setCount(c => { const n = c + 1; onCountChange?.(n); return n }) 65 if (currentUser.user_id !== authorUserId) { 66 await addNotification({ 67 recipientUserId: authorUserId, 68 type: 'like', 69 content: `${currentUser.username} liked your story.`, 70 link: `/story/${storyId}`, 71 }) 72 } 73 addToast('Added to likes!', 'success') 74 } 75 } catch { 76 addToast('Something went wrong.', 'error') 39 77 } 40 addToast(liked ? 'Removed from likes' : 'Added to likes!', liked ? 'info' : 'success')78 setLoading(false) 41 79 } 42 80 … … 44 82 <button 45 83 onClick={handleClick} 84 disabled={loading} 46 85 className={`flex items-center gap-2 px-4 py-2 rounded-xl border transition-all duration-200 ${ 47 86 liked … … 51 90 > 52 91 <Heart size={16} className={liked ? 'fill-rose-400' : ''} /> 53 <span className="text-sm font-medium">{ totalLikes.toLocaleString()}</span>92 <span className="text-sm font-medium">{count.toLocaleString()}</span> 54 93 </button> 55 94 )
Note:
See TracChangeset
for help on using the changeset viewer.
