Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/app/(routes)/user/[userId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
'use client'

import {
Avatar,
CategoryListItem,
FollowListButton,
ProfileEditButton,
Spinner,
} from '@/components'
import { CATEGORIES_RENDER, PROFILE_MSG } from '@/constants'
import { fetchGetUserProfile } from '@/services/users/useUsers'
import { useGetUserProfile } from '@/services/users/useUsers'
import { UserLayoutProps } from './layout'

export default async function UserPage({
params: { userId },
}: UserLayoutProps) {
const user = await fetchGetUserProfile({ memberId: userId })
export default function UserPage({ params: { userId } }: UserLayoutProps) {
const { data: user, isFetching: isUserLoading } = useGetUserProfile(
Number(userId),
)

return (
<>
{isUserLoading && <Spinner />}
<div className="flex flex-col gap-4 px-4 py-6">
<div className="flex gap-3">
{user?.profileImagePath && (
Expand Down
19 changes: 5 additions & 14 deletions src/components/FollowListButton/FollowListButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { PROFILE_MSG } from '@/constants'
import { useFollowUser, useModal } from '@/hooks'
import { useModal } from '@/hooks'
import { useCurrentUser } from '@/hooks/useCurrentUser'
import { fetchGetFollowers, fetchGetFollowing } from '@/services/users/useUsers'
import { UserProfileResBody } from '@/types'
Expand All @@ -13,13 +13,6 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => {
const myId = currentUser?.memberId
const { Modal, isOpen, modalClose, currentModal, handleOpenCurrentModal } =
useModal()
const { followingCount, setFollowingCount, followerCount } = useFollowUser({
memberId: user?.memberId || 0,
isInitFollowing: !!user?.isFollowing,
followingInitCount: user?.followingCount || 0,
followerInitCount: user?.followerCount || 0,
handleOpenCurrentModal,
})

return (
<>
Expand All @@ -28,15 +21,15 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => {
onClick={() => {
handleOpenCurrentModal('following')
}}>
{PROFILE_MSG.FOLLOWING} {followingCount}
{PROFILE_MSG.FOLLOWING} {user?.followingCount}
</div>
{PROFILE_MSG.LIST_DIVIDER}
<div
className="cursor-pointer hover:font-semibold"
onClick={() => {
handleOpenCurrentModal('follower')
}}>
{PROFILE_MSG.FOLLOWER} {followerCount}
{PROFILE_MSG.FOLLOWER} {user?.followerCount}
</div>
{currentModal !== 'login' && isOpen && (
<Modal
Expand All @@ -54,8 +47,7 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => {
fetchFn={fetchGetFollowing}
myId={myId}
type="following"
followingCount={followingCount}
setFollowingCount={setFollowingCount}
followingCount={user?.followingCount}
/>
)}
{currentModal === 'follower' && (
Expand All @@ -64,8 +56,7 @@ const FollowListButton = ({ user }: { user: UserProfileResBody }) => {
fetchFn={fetchGetFollowers}
myId={myId}
type="follower"
followingCount={followingCount}
setFollowingCount={setFollowingCount}
followingCount={user?.followingCount}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ const PopularLinkList = () => {
url={link.url}
tagName={link.tagName}
tagColor={link.tagColor as ChipColors}
isInitLiked={link.isLiked}
likeInitCount={link.likeCount}
isLiked={link.isLiked}
likeCount={link.likeCount}
type="card"
/>
</SwiperSlide>
Expand Down
72 changes: 35 additions & 37 deletions src/components/ProfileEditButton/ProfileEditButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,50 @@ import { UserProfileResBody } from '@/types'
import { cls, getProfileButtonColor, getProfileButtonText } from '@/utils'
import { useRouter } from 'next/navigation'
import Button from '../common/Button/Button'
import DeferredComponent from '../common/DeferedComponent/DeferedComponent'
import Spinner from '../common/Spinner/Spinner'

const ProfileEditButton = ({ user }: { user: UserProfileResBody }) => {
const router = useRouter()
const { currentUser } = useCurrentUser()
const myId = currentUser?.memberId
const { handleOpenCurrentModal } = useModal()
const { isFollowing, handleClickFollow } = useFollowUser({
memberId: user?.memberId || 0,
isInitFollowing: !!user?.isFollowing,
followingInitCount: user?.followingCount || 0,
followerInitCount: user?.followerCount || 0,
const { handleClickFollow } = useFollowUser({
profileId: user?.memberId || 0,
memberId: currentUser?.memberId || 0,
myId: myId || 0,
handleOpenCurrentModal,
})

return myId ? (
<Button
type="button"
onClick={() => {
if (user?.memberId === myId) {
router.push('/user/setting')
} else if (isFollowing) {
handleClickFollow(isFollowing)
} else {
handleClickFollow(isFollowing)
}
}}
className={cls(
'button button-md button-lg',
getProfileButtonColor({
isFollowing,
memberId: user?.memberId,
myId,
}),
)}>
{getProfileButtonText({
isFollowing,
memberId: user?.memberId,
myId,
})}
</Button>
) : (
<DeferredComponent>
<Spinner />
</DeferredComponent>
const buttonColor = getProfileButtonColor({
isFollowing: user?.isFollowing,
memberId: user?.memberId,
myId,
})

const buttonText = getProfileButtonText({
isFollowing: user?.isFollowing,
memberId: user?.memberId,
myId,
})

return (
<>
{user?.memberId && myId && (
<Button
type="button"
onClick={() => {
if (user?.memberId === myId) {
router.push('/user/setting')
} else if (user?.isFollowing) {
handleClickFollow(user?.isFollowing)
} else {
handleClickFollow(user?.isFollowing)
}
}}
className={cls('button button-md button-lg', buttonColor)}>
{buttonText}
</Button>
)}
</>
)
}

Expand Down
60 changes: 28 additions & 32 deletions src/components/common/FollowList/FollowList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dispatch, Fragment, SetStateAction } from 'react'
import { Fragment, useEffect } from 'react'
import { Spinner } from '@/components'
import useFollowQuery from '@/components/common/FollowList/hooks/useFollowQuery'
import useInfiniteScroll from '@/hooks/useInfiniteScroll'
Expand All @@ -12,7 +12,6 @@ export interface FollowListProps {
myId?: number
type?: string
followingCount?: number
setFollowingCount?: Dispatch<SetStateAction<number | undefined>>
}

export interface FollowUserProps {
Expand All @@ -29,7 +28,6 @@ const FollowList = ({
myId,
type,
followingCount,
setFollowingCount,
}: FollowListProps) => {
const { followList, fetchNextPage, hasNextPage, isFollowLoading } =
useFollowQuery({
Expand All @@ -39,35 +37,33 @@ const FollowList = ({
})
const { target } = useInfiniteScroll({ hasNextPage, fetchNextPage })

return isFollowLoading ? (
<DeferredComponent>
<Spinner />
</DeferredComponent>
) : (
<ul className="flex flex-col gap-y-2">
{followList &&
followList.pages.map((group, i) => (
<Fragment key={i}>
{group.responses?.map((user: FollowUserProps) => (
<li key={user.memberId}>
<User
memberId={user.memberId}
nickname={user.nickname}
profileImagePath={user.profileImagePath}
aboutMe={user.aboutMe}
isFollowing={user.isFollowing}
isAuth={myId === user.memberId}
followingCount={followingCount}
myId={myId}
profileId={memberId}
setFollowingCount={setFollowingCount}
/>
</li>
))}
</Fragment>
))}
<div ref={target}></div>
</ul>
return (
<>
{isFollowLoading && <Spinner />}
<ul className="flex flex-col gap-y-2">
{followList &&
followList.pages.map((group, i) => (
<Fragment key={i}>
{group.responses?.map((user: FollowUserProps) => (
<li key={user.memberId}>
<User
memberId={user.memberId}
nickname={user.nickname}
profileImagePath={user.profileImagePath}
aboutMe={user.aboutMe}
isFollowing={user.isFollowing}
isAuth={myId === user.memberId}
followingCount={followingCount}
myId={myId}
profileId={memberId}
/>
</li>
))}
</Fragment>
))}
<div ref={target}></div>
</ul>
</>
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/common/FollowList/hooks/useFollowQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useInfiniteQuery } from '@tanstack/react-query'
const useFollowQuery = ({ memberId, fetchFn, type }: FollowListProps) => {
const queryKey =
type === 'following' ? QUERY_KEYS.FOLLOWING : QUERY_KEYS.FOLLOWERS
const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({
const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteQuery({
queryKey: [queryKey, memberId],
queryFn: ({ pageParam }) =>
fetchFn({
Expand All @@ -22,7 +22,7 @@ const useFollowQuery = ({ memberId, fetchFn, type }: FollowListProps) => {
followList: data,
fetchNextPage,
hasNextPage,
isFollowLoading: isLoading,
isFollowLoading: isFetching,
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/components/common/LinkItem/LinkItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export interface LinkItemProps {
tagName: string
tagColor: ChipColors
readUsers?: linkViewHistories[]
isInitLiked?: boolean
likeInitCount: number
isLiked: boolean
likeCount: number
read?: boolean
summary?: boolean
edit?: boolean
Expand All @@ -62,8 +62,8 @@ const LinkItem = ({
tagName,
tagColor,
readUsers,
isInitLiked,
likeInitCount,
isLiked,
likeCount,
read = false,
summary = false,
edit = false,
Expand Down Expand Up @@ -110,11 +110,9 @@ const LinkItem = ({
linkId,
})
const { handleSaveReadInfo } = useReadSaveLink({ spaceId, linkId })
const { isLiked, likeCount, handleClickLike } = useLikeLink({
const { handleClickLike } = useLikeLink({
spaceId,
linkId,
isLikedValue: isInitLiked,
likeCountValue: likeInitCount,
})
return (
<>
Expand Down
50 changes: 14 additions & 36 deletions src/components/common/LinkItem/hooks/useLikeLink.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,35 @@
import { useCallback, useMemo, useState } from 'react'
import { useCallback } from 'react'
import { useDeleteLikeLink, usePostLikeLink } from '@/services/link/useLink'
import { debounce } from 'lodash'
import useToggle from '../../Toggle/hooks/useToggle'

export interface UseLikeLinkProps {
spaceId?: number
linkId: number
isLikedValue?: boolean
likeCountValue: number
}

const useLikeLink = ({
linkId,
isLikedValue,
likeCountValue,
}: UseLikeLinkProps) => {
const [isLiked, likeToggle] = useToggle(isLikedValue)
const [likeCount, setLikeCount] = useState<number>(likeCountValue)
const useLikeLink = ({ spaceId, linkId }: UseLikeLinkProps) => {
const { mutate: deleteLikeLink } = useDeleteLikeLink({ spaceId })
const { mutate: postLikeLink } = usePostLikeLink({ spaceId })

const { mutate: deleteLikeLink } = useDeleteLikeLink()
const { mutate: postLikeLink } = usePostLikeLink()
const handleRemoveLike = useCallback(() => {
deleteLikeLink({ linkId })
}, [deleteLikeLink, linkId])

const debounceUnLikeLink = useMemo(
() =>
debounce(async () => {
await deleteLikeLink({ linkId })
}, 300),
[deleteLikeLink, linkId],
)

const debounceLikeLink = useMemo(
() =>
debounce(async () => {
await postLikeLink({ linkId })
}, 300),
[postLikeLink, linkId],
)
const handleAddLike = useCallback(() => {
postLikeLink({ linkId })
}, [postLikeLink, linkId])

const handleClickLike = useCallback(
(isLike: boolean) => {
likeToggle()
if (isLike) {
setLikeCount((prev) => prev - 1)
debounceUnLikeLink()
handleRemoveLike()
} else {
setLikeCount((prev) => prev + 1)
debounceLikeLink()
handleAddLike()
}
},
[likeToggle, debounceUnLikeLink, debounceLikeLink],
[handleRemoveLike, handleAddLike],
)

return { isLiked, likeCount, handleClickLike }
return { handleClickLike }
}

export default useLikeLink
Loading