Skip to content

Commit

Permalink
Merge pull request #109 from Nubblee/feature/likeApi-108
Browse files Browse the repository at this point in the history
[Feature]좋아요 api적용, 낙관적 업데이트 적용
  • Loading branch information
ssuminii authored Nov 5, 2024
2 parents ed4759b + d782953 commit 7dc5015
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 14 deletions.
28 changes: 16 additions & 12 deletions src/components/FloatingMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
/** @jsxImportSource @emotion/react */
import colors from '@/constants/color'
import { useAuthStore } from '@/stores/authStore'
import { useLikeStore } from '@/stores/likeStore'
import styled from '@emotion/styled'
import { useState } from 'react'
import { HeartIcon, Share2Icon } from 'lucide-react'
import colors from '@/constants/color'
import { useParams } from 'react-router-dom'

const FloatingMenu = () => {
const [liked, setLiked] = useState(false)
const [likeCount, setLikeCount] = useState(0)
const { liked, likeCount, toggleLike } = useLikeStore()

const { sessionId } = useAuthStore()
const { postId } = useParams<{ postId: string }>()

const handleLikeClick = () => {
setLiked(!liked)
setLikeCount(liked ? likeCount - 1 : likeCount + 1)
const handleLikeClick = async () => {
if (!postId) return
toggleLike(postId, sessionId as string)
}

const handleCopyUrl = async () => {
Expand All @@ -19,7 +23,7 @@ const FloatingMenu = () => {
await navigator.clipboard.writeText(currentUrl)
alert('클립보드에 링크가 복사되었어요.')
} catch (err) {
console.log(err)
console.error('링크 복사 실패:', err)
}
}

Expand Down Expand Up @@ -56,19 +60,19 @@ const MenuContainer = styled.div`
border-radius: 30px;
transition:
left 0.3s ease,
top 0.3s ease; /* 위치 변경을 부드럽게 만듦 */
top 0.3s ease;
@media (max-width: 1440px) {
left: 12%; /* 1440px 이하에서 점진적으로 변경 */
left: 12%;
top: 26%;
}
@media (max-width: 1280px) {
left: 9%; /* 1280px 이하에서 위치 변경 */
left: 9%;
}
@media (max-width: 1090px) {
display: none; /* 1080px 이하에서는 메뉴를 숨김 */
display: none;
}
`

Expand Down
2 changes: 1 addition & 1 deletion src/components/comment/CommentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const CommentForm = () => {
console.log('비로그인 댓글 제출', res.data)
} else {
const res = await postMemberComment()
console.log('비로그인 댓글 제출', res.data)
console.log('멤버 댓글 제출', res.data)
}
setSubmitSuccess(true)
setFormData({ nickname: '', password: '', comment: '' })
Expand Down
7 changes: 6 additions & 1 deletion src/pages/PostDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import colors from '@/constants/color'
import { fontSize } from '@/constants/font'
import { useAuthStore } from '@/stores/authStore'
import { useLikeStore } from '@/stores/likeStore'
import { formatDate } from '@/utils/formatDate'
import CommentForm from '@components/comment/CommentForm'
import CommentList from '@components/comment/CommentList'
Expand Down Expand Up @@ -30,6 +31,7 @@ const PostDetail = () => {
const { sessionId } = useAuthStore()
const navigate = useNavigate()
const { userName } = useAuthStore()
const { setLikeData, liked, likeCount } = useLikeStore()

const handlePostEdit = () => {
navigate(`/write?id=${postId}`, { state: { postData } })
Expand All @@ -46,10 +48,13 @@ const PostDetail = () => {
},
})
setPostData(res.data)
if (res.data.postLiked !== liked || res.data.likeCount !== likeCount) {
setLikeData(res.data.postLiked, res.data.likeCount)
}
console.log(res.data)

if (res.data.title !== title) {
navigate('/error') // 에러 페이지 경로에 맞게 수정
navigate('/error')
}
} catch (err: unknown) {
if (axios.isAxiosError(err)) {
Expand Down
56 changes: 56 additions & 0 deletions src/stores/likeStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { create } from 'zustand'
import axios from 'axios'

interface LikeStore {
liked: boolean
likeCount: number
toggleLike: (postId: string, sessionId: string) => Promise<void>
setLikeData: (liked: boolean, likeCount: number) => void // 초기 데이터를 설정하는 함수
}

export const useLikeStore = create<LikeStore>((set) => ({
liked: false,
likeCount: 0,

setLikeData: (liked, likeCount) => set({ liked, likeCount }),

toggleLike: async (postId, sessionId) => {
if (!sessionId) {
alert('로그인이 필요합니다.')
return
}

const currentLiked = useLikeStore.getState().liked
const currentLikeCount = useLikeStore.getState().likeCount

// 낙관적 업데이트
set({
liked: !currentLiked,
likeCount: currentLiked ? currentLikeCount - 1 : currentLikeCount + 1,
})

try {
if (!useLikeStore.getState().liked) {
await axios.delete(`${import.meta.env.VITE_NUBBLE_SERVER}/posts/${postId}/likes`, {
headers: {
'SESSION-ID': sessionId,
},
})
} else {
await axios.put(
`${import.meta.env.VITE_NUBBLE_SERVER}/posts/${postId}/likes`,
{},
{
headers: {
'SESSION-ID': sessionId,
},
},
)
}
} catch (err) {
console.error('좋아요 요청 실패:', err)
// 요청 실패 시 원래 상태로 롤백
set({ liked: currentLiked, likeCount: currentLikeCount })
}
},
}))

0 comments on commit 7dc5015

Please sign in to comment.