diff --git a/src/app/(routes)/user/[userId]/layout.tsx b/src/app/(routes)/user/[userId]/layout.tsx index d2857576..f90c9669 100644 --- a/src/app/(routes)/user/[userId]/layout.tsx +++ b/src/app/(routes)/user/[userId]/layout.tsx @@ -1,4 +1,4 @@ -import { UserController } from '@/components' +import { ProfileTap } from '@/components' import { fetchGetUserProfile } from '@/services/user/profile/profile' import { Metadata } from 'next' @@ -6,9 +6,14 @@ type Props = { params: { userId: number } } +export async function getProfile(userId: number) { + const response = await fetchGetUserProfile({ memberId: userId }) + return response +} + export async function generateMetadata({ params }: Props): Promise { const userId = params.userId - const user = await fetchGetUserProfile({ memberId: userId }) + const user = await getProfile(userId) return { title: user.nickname, @@ -19,7 +24,12 @@ export async function generateMetadata({ params }: Props): Promise { } const UserLayout = ({ children }: { children: React.ReactNode }) => { - return {children} + return ( + <> + + {children} + + ) } export default UserLayout diff --git a/src/app/(routes)/user/[userId]/page.tsx b/src/app/(routes)/user/[userId]/page.tsx index 98e9cc7b..fc1cb366 100644 --- a/src/app/(routes)/user/[userId]/page.tsx +++ b/src/app/(routes)/user/[userId]/page.tsx @@ -1,41 +1,20 @@ -'use client' - -import { Avatar, CategoryListItem, Spinner } from '@/components' -import Button from '@/components/common/Button/Button' -import FollowList from '@/components/common/FollowList/FollowList' -import LoginModal from '@/components/common/Modal/LoginModal' -import { CATEGORIES_RENDER, PROFILE_MSG } from '@/constants' -import { useFollowUser, useModal } from '@/hooks' -import useGetProfile from '@/hooks/useGetProfile' import { - fetchGetFollowers, - fetchGetFollowing, -} from '@/services/user/follow/follow' -import { cls, getProfileButtonColor, getProfileButtonText } from '@/utils' -import { useRouter } from 'next/navigation' + Avatar, + CategoryListItem, + FollowListButton, + ProfileEditButton, +} from '@/components' +import { CATEGORIES_RENDER, PROFILE_MSG } from '@/constants' +import { getProfile } from './layout' + +interface UserPageProps { + params: { userId: number } +} -const UserPage = () => { - const { user, myId, isProfileLoading } = useGetProfile() - const router = useRouter() - const { Modal, isOpen, modalClose, currentModal, handleOpenCurrentModal } = - useModal() - const { - isFollowing, - followingCount, - setFollowingCount, - followerCount, - handleClickFollow, - } = useFollowUser({ - memberId: user?.memberId || 0, - isInitFollowing: !!user?.isFollowing, - followingInitCount: user?.followingCount || 0, - followerInitCount: user?.followerCount || 0, - handleOpenCurrentModal, - }) +export default async function UserPage({ params: { userId } }: UserPageProps) { + const user = await getProfile(userId) - return isProfileLoading ? ( - - ) : ( + return ( <>
@@ -55,49 +34,11 @@ const UserPage = () => { {user?.newsEmail}
-
{ - handleOpenCurrentModal('following') - }}> - {PROFILE_MSG.FOLLOWING} {followingCount} -
- {PROFILE_MSG.LIST_DIVIDER} -
{ - handleOpenCurrentModal('follower') - }}> - {PROFILE_MSG.FOLLOWER} {followerCount} -
+
- +
{PROFILE_MSG.FAVORITE_CATEGORY} @@ -121,48 +62,6 @@ const UserPage = () => {
{user?.aboutMe}
- {currentModal !== 'login' && isOpen && ( - -
- {currentModal === 'following' && ( - - )} - {currentModal === 'follower' && ( - - )} -
-
- )} - {currentModal === 'login' && ( - - )} ) } - -export default UserPage diff --git a/src/app/api/user/[memberId]/profile/route.ts b/src/app/api/user/[memberId]/profile/route.ts index f159693e..3ea01584 100644 --- a/src/app/api/user/[memberId]/profile/route.ts +++ b/src/app/api/user/[memberId]/profile/route.ts @@ -14,7 +14,7 @@ export async function GET( } try { - const userData = await apiServer.get(path, { cache: 'no-cache' }, headers) + const userData = await apiServer.get(path, {}, headers) return NextResponse.json(userData) } catch (error: any) { return NextResponse.json( diff --git a/src/components/FollowListButton/FollowListButton.tsx b/src/components/FollowListButton/FollowListButton.tsx new file mode 100644 index 00000000..41ead172 --- /dev/null +++ b/src/components/FollowListButton/FollowListButton.tsx @@ -0,0 +1,88 @@ +'use client' + +import { PROFILE_MSG } from '@/constants' +import { useFollowUser, useModal } from '@/hooks' +import { useCurrentUser } from '@/hooks/useCurrentUser' +import { + fetchGetFollowers, + fetchGetFollowing, +} from '@/services/user/follow/follow' +import { UserProfileResBody } from '@/types' +import FollowList from '../common/FollowList/FollowList' +import LoginModal from '../common/Modal/LoginModal' + +const FollowListButton = ({ user }: { user: UserProfileResBody }) => { + const { currentUser } = useCurrentUser() + 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 ( + <> +
{ + handleOpenCurrentModal('following') + }}> + {PROFILE_MSG.FOLLOWING} {followingCount} +
+ {PROFILE_MSG.LIST_DIVIDER} +
{ + handleOpenCurrentModal('follower') + }}> + {PROFILE_MSG.FOLLOWER} {followerCount} +
+ {currentModal !== 'login' && isOpen && ( + +
+ {currentModal === 'following' && ( + + )} + {currentModal === 'follower' && ( + + )} +
+
+ )} + {currentModal === 'login' && ( + + )} + + ) +} + +export default FollowListButton diff --git a/src/components/ProfileEditButton/ProfileEditButton.tsx b/src/components/ProfileEditButton/ProfileEditButton.tsx new file mode 100644 index 00000000..ca3ce215 --- /dev/null +++ b/src/components/ProfileEditButton/ProfileEditButton.tsx @@ -0,0 +1,55 @@ +'use client' + +import { useFollowUser, useModal } from '@/hooks' +import { useCurrentUser } from '@/hooks/useCurrentUser' +import { UserProfileResBody } from '@/types' +import { cls, getProfileButtonColor, getProfileButtonText } from '@/utils' +import { useRouter } from 'next/navigation' +import Button from '../common/Button/Button' +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, + handleOpenCurrentModal, + }) + + return myId ? ( + + ) : ( + + ) +} + +export default ProfileEditButton diff --git a/src/components/UserController/UserController.tsx b/src/components/ProfileTap/ProfileTap.tsx similarity index 86% rename from src/components/UserController/UserController.tsx rename to src/components/ProfileTap/ProfileTap.tsx index deea6e5b..70ed927b 100644 --- a/src/components/UserController/UserController.tsx +++ b/src/components/ProfileTap/ProfileTap.tsx @@ -6,7 +6,7 @@ import TabItem from '@/components/common/Tab/TabItem' import useTab from '@/components/common/Tab/hooks/useTab' import useGetProfile from '@/hooks/useGetProfile' -const UserController = ({ children }: { children: React.ReactNode }) => { +const ProfileTap = () => { const { user, myId, isProfileLoading } = useGetProfile() const { currentTab, tabList } = useTab({ type: 'user', @@ -28,9 +28,8 @@ const UserController = ({ children }: { children: React.ReactNode }) => { ))} )} - {children} ) } -export default UserController +export default ProfileTap diff --git a/src/components/UserInfoForm/UserInfoForm.tsx b/src/components/UserInfoForm/UserInfoForm.tsx index 31abde22..6148c098 100644 --- a/src/components/UserInfoForm/UserInfoForm.tsx +++ b/src/components/UserInfoForm/UserInfoForm.tsx @@ -155,6 +155,7 @@ const UserInfoForm = ({ userData, formType }: UserInfoFormProps) => { userData?.memberId && (await fetchPostUserProfile(userData?.memberId, data, imageFile)) notify('success', '수정되었습니다.') + router.refresh() router.back() } catch (e) { notify('error', '수정에 실패했습니다.') diff --git a/src/components/common/CategoryList/CategoryListItem.tsx b/src/components/common/CategoryList/CategoryListItem.tsx index 2ca33bb3..ddc2d557 100644 --- a/src/components/common/CategoryList/CategoryListItem.tsx +++ b/src/components/common/CategoryList/CategoryListItem.tsx @@ -1,3 +1,5 @@ +'use client' + import { cls } from '@/utils' import Link from 'next/link' import { usePathname, useSearchParams } from 'next/navigation' diff --git a/src/components/index.ts b/src/components/index.ts index 7664fcb1..22e67100 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -21,5 +21,7 @@ export { default as SpaceList } from './SpaceList/SpaceList' export { default as Spinner } from './common/Spinner/Spinner' export { default as SearchController } from './SearchController/SearchController' export { default as NotificationController } from './NotificationController/NotificationController' -export { default as UserController } from './UserController/UserController' +export { default as ProfileTap } from './ProfileTap/ProfileTap' export { default as SettingController } from './SettingController/SettingController' +export { default as FollowListButton } from './FollowListButton/FollowListButton' +export { default as ProfileEditButton } from './ProfileEditButton/ProfileEditButton' diff --git a/src/services/user/profile/profile.ts b/src/services/user/profile/profile.ts index dfe375f8..48f7743b 100644 --- a/src/services/user/profile/profile.ts +++ b/src/services/user/profile/profile.ts @@ -9,7 +9,7 @@ const fetchGetUserProfile = async ({ memberId }: FetchGetUserProfileProps) => { const path = `/api/user/${memberId}/profile` try { - const response = await apiClient.get(path) + const response = await apiClient.get(path, { cache: 'no-store' }) return response } catch (e) { if (e instanceof Error) throw new Error(e.message)