diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx
index f4d9abb..71e5e31 100644
--- a/client/src/app/layout.tsx
+++ b/client/src/app/layout.tsx
@@ -4,7 +4,7 @@ import { nameOfApp, oneLineMessage } from "@/const/brand";
import OverrideCSS from "@/const/overrideCSS";
import { Box, GlobalStyles } from "@mui/material";
import Pretendard from "~/assets/font/Pretendard";
-import NavigationBar from "~/components/NavigationBar";
+import NavigationBar from "~/components/Navigation/NavigationBar";
import "./globals.css";
import CustomQueryClientProvider from "@/components/queryClient/CustomQueryClientProvider";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index 6aed334..7005b37 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -1,11 +1,11 @@
"use server";
import PostCardList from "@/components/post/PostCardList";
import { getPostListQueryFn } from "@/queries/post/useGetPostListInfiniteQuery";
+import getTokenFromCookies from "@/utils/getTokenFromCookies";
import { Container, Paper } from "@mui/material";
-import { cookies } from "next/headers";
export default async function Home() {
- const accessToken = cookies().get("accessToken")?.value;
+ const accessToken = await getTokenFromCookies()
const initialData = await getPostListQueryFn({
page: 0,
diff --git a/client/src/app/search/page.tsx b/client/src/app/search/page.tsx
index 03f6393..f77fa1e 100644
--- a/client/src/app/search/page.tsx
+++ b/client/src/app/search/page.tsx
@@ -1,6 +1,7 @@
"use server";
import SearchArea from "@/components/search/SearchArea";
import { getPostListQueryFn } from "@/queries/post/useGetPostListInfiniteQuery";
+import getTokenFromCookies from "@/utils/getTokenFromCookies";
import { Container } from "@mui/material";
import { cookies } from "next/headers";
@@ -9,7 +10,7 @@ const SearchPage = async ({
}: {
searchParams?: { [key: string]: string | undefined };
}) => {
- const accessToken = cookies().get("accessToken")?.value;
+ const accessToken = await getTokenFromCookies()
const initialData = await getPostListQueryFn({
searchKeyword: searchParams?.keyword,
headers: { Authorization: accessToken },
diff --git a/client/src/components/Navigation/NavbarUserImage.tsx b/client/src/components/Navigation/NavbarUserImage.tsx
new file mode 100644
index 0000000..2101e99
--- /dev/null
+++ b/client/src/components/Navigation/NavbarUserImage.tsx
@@ -0,0 +1,20 @@
+"use client";
+import { useUserInfoQuery } from "@/queries/auth/useUserInfoQuery";
+import UserAvatar from "../user/info/UserAvatar";
+import MyIcon from "~/assets/icons/MyIcon.svg";
+const NavbarUserImage = () => {
+ try {
+ const { data } = useUserInfoQuery();
+ return (
+
+ );
+ } catch (err) {
+ return ;
+ }
+};
+
+export default NavbarUserImage;
diff --git a/client/src/components/Navigation/NavigationBar.tsx b/client/src/components/Navigation/NavigationBar.tsx
new file mode 100644
index 0000000..4ca22fe
--- /dev/null
+++ b/client/src/components/Navigation/NavigationBar.tsx
@@ -0,0 +1,82 @@
+"use client";
+import { BottomNavigation, BottomNavigationAction, Paper } from "@mui/material";
+
+import HomeIcon from "~/assets/icons/HomeIcon.svg";
+import SearchIcon from "~/assets/icons/SearchIcon.svg";
+import PostIcon from "~/assets/icons/PostIcon.svg";
+import BeverageIcon from "~/assets/icons/BeverageIcon.svg";
+
+import HOME, { MY_PROFILE, NEW_POST, SEARCH, WIKI } from "@/const/clientPath";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import NavbarUserImage from "@/components/Navigation/NavbarUserImage";
+import { useMemo } from "react";
+
+const NavigationBar = () => {
+ const path = usePathname();
+ const NavbarData = useMemo(
+ () => [
+ {
+ iconComponent: ,
+ label: "홈",
+ href: HOME,
+ },
+ {
+ iconComponent: ,
+ label: "검색",
+ href: SEARCH,
+ },
+ {
+ iconComponent: ,
+ href: NEW_POST,
+ },
+ {
+ iconComponent: ,
+ label: "술과사전",
+ href: WIKI,
+ },
+ {
+ iconComponent: ,
+ label: "내 정보",
+ href: MY_PROFILE,
+ },
+ ],
+ []
+ );
+ return (
+
+
+ {NavbarData.map(({ label, href, iconComponent, ...others }) => {
+ return (
+
+ );
+ })}
+
+
+ );
+};
+
+const WrapperStyle = {
+ position: "fixed",
+ bottom: 0,
+ left: 0,
+ right: 0,
+ borderRadius: 0,
+};
+const BtnStyle = {
+ borderRadius: "12px 12px 0 0",
+ border: "1px solid",
+ borderBottom: "none",
+ borderColor: "gray.secondary",
+ boxSizing: "border-box",
+};
+
+export default NavigationBar;
diff --git a/client/src/components/NavigationBar.tsx b/client/src/components/NavigationBar.tsx
deleted file mode 100644
index 4f0cf11..0000000
--- a/client/src/components/NavigationBar.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-"use client";
-import { BottomNavigation, BottomNavigationAction, Paper } from "@mui/material";
-
-import HomeIcon from "~/assets/icons/HomeIcon.svg";
-import SearchIcon from "~/assets/icons/SearchIcon.svg";
-import PostIcon from "~/assets/icons/PostIcon.svg";
-import BeverageIcon from "~/assets/icons/BeverageIcon.svg";
-import MyIcon from "~/assets/icons/MyIcon.svg";
-import HOME, { MY_PROFILE, NEW_POST, SEARCH, WIKI } from "@/const/clientPath";
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-
-const NavbarData = [
- {
- iconComponent: ,
- label: "홈",
- href: HOME,
- },
- {
- iconComponent: ,
- label: "검색",
- href: SEARCH,
- },
- {
- iconComponent: ,
- href: NEW_POST,
- },
- {
- iconComponent: ,
- label: "술과사전",
- href: WIKI,
- },
- {
- iconComponent: ,
- label: "내 정보",
- //FIXME 실제 URL로 변경
- href: MY_PROFILE+"/1",
- },
-];
-
-const NavigationBar = () => {
- const path = usePathname();
- return (
-
-
- {NavbarData.map(({ label, href, iconComponent, ...others }) => {
- return (
-
- );
- })}
-
-
- );
-};
-
-export default NavigationBar;
diff --git a/client/src/components/post/PostCard.tsx b/client/src/components/post/PostCard.tsx
index b7b7e31..bc6f82f 100644
--- a/client/src/components/post/PostCard.tsx
+++ b/client/src/components/post/PostCard.tsx
@@ -25,13 +25,17 @@ import useUnLikePostMutation from "@/queries/post/useUnLikePostMutation";
import "../newpost/quill.mention.css";
import { sanitize } from "isomorphic-dompurify";
import UserAvatar from "../user/info/UserAvatar";
+import Link from "next/link";
+import { USER_PAGE } from "@/const/clientPath";
+import { useUserInfoQuery } from "@/queries/auth/useUserInfoQuery";
const PostCard = ({
postAttachUrls,
id,
+ createdBy,
nickname,
postContent,
- updateDt,
+ lastModifiedDate,
tagList,
postNo,
likeCount,
@@ -46,13 +50,21 @@ const PostCard = ({
const hasImage = useMemo(() => postAttachUrls.length !== 0, [postAttachUrls]);
const { mutate: likeHandler } = useLikePostMutation();
const { mutate: unLikeHandler } = useUnLikePostMutation();
+ const { data: currentUser } = useUserInfoQuery();
+
+ const isMyPost = useMemo(
+ () => currentUser?.userNo === createdBy,
+ [currentUser]
+ );
return (
-
+
+
+
{/* Header */}
{/* 타이틀 */}
- {nickname}
- {`@${id}`}
+
+ {nickname}
+
+
+ {`@${id}`}
+
- {dayjs(updateDt).format("MM.DD")}
+ {dayjs(lastModifiedDate).format("MM.DD")}
-
-
+
+ {isMyPost && }
+
{alcoholName && (
)}
@@ -110,7 +127,11 @@ const PostCard = ({
onClick={() => openPostDetailPage(id, String(postNo))}
image={postAttachUrls[0].attachUrl}
alt={`${id}의 포스트`}
- sx={{ borderRadius: 2, bgcolor: "background.default" }}
+ sx={{
+ borderRadius: 2,
+ bgcolor: "background.default",
+ cursor: "pointer",
+ }}
/>
)}
{/* CTA */}
diff --git a/client/src/components/queryClient/CustomQueryClientProvider.tsx b/client/src/components/queryClient/CustomQueryClientProvider.tsx
index 4843009..0c6faf7 100644
--- a/client/src/components/queryClient/CustomQueryClientProvider.tsx
+++ b/client/src/components/queryClient/CustomQueryClientProvider.tsx
@@ -13,6 +13,7 @@ export default function CustomQueryClientProvider({
new QueryClient({
defaultOptions: {
queries: {
+ retry:false,
staleTime: 60 * 1000,
},
},
diff --git a/client/src/const/clientPath.ts b/client/src/const/clientPath.ts
index 480b2bd..255107d 100644
--- a/client/src/const/clientPath.ts
+++ b/client/src/const/clientPath.ts
@@ -15,6 +15,11 @@ export const FORGOTPASSWORD = "/auth/forgot-password" as const;
* 로그인 했을 경우만 접근 가능한 마이페이지
*/
export const MY_PROFILE = "/user" as const;
+/**
+ * 유저의 PK를 입력받아 해당유저의 프로필 페이지로 이동하는 URL
+ */
+export const USER_PAGE = (pk:string|number)=>`/user/${pk}`
+
/**
* 술과사전 페이지 라우트
*/
diff --git a/client/src/queries/auth/useUserInfoQuery.tsx b/client/src/queries/auth/useUserInfoQuery.tsx
index 2122f49..9f74b1e 100644
--- a/client/src/queries/auth/useUserInfoQuery.tsx
+++ b/client/src/queries/auth/useUserInfoQuery.tsx
@@ -1,20 +1,21 @@
"use client";
import { MY_INFO } from "@/const/serverPath";
-import {axiosPrivate} from "@/libs/axios";
+import { axiosPrivate } from "@/libs/axios";
import { MyInfoInterface } from "@/types/auth/myInfo";
import { SigninRequirement } from "@/types/auth/signinRequirement";
-import { useSuspenseQuery } from "@tanstack/react-query";
+import getTokenFromLocalStorage from "@/utils/getTokenFromLocalStorage";
+import { useQuery } from "@tanstack/react-query";
export const useUserInfoQuery = () =>
- useSuspenseQuery({
+ useQuery({
queryKey: userInfoQueryKeys.all,
queryFn: getMyInfoByLocalStorage,
});
export const getMyInfoByLocalStorage = async () => {
- // const accessToken = localStorage.get("accessToken");
+ const accessToken = getTokenFromLocalStorage();
const { data } = await axiosPrivate.get(MY_INFO, {
- // headers: { Authorization: accessToken },
+ headers: { Authorization: accessToken },
});
return data;
};
diff --git a/client/src/queries/post/useDeletePostMutation.ts b/client/src/queries/post/useDeletePostMutation.ts
index 41bc682..b209aef 100644
--- a/client/src/queries/post/useDeletePostMutation.ts
+++ b/client/src/queries/post/useDeletePostMutation.ts
@@ -1,6 +1,6 @@
import { REMOVE_POST } from "@/const/serverPath";
import { axiosPrivate } from "@/libs/axios";
-import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { useMutation } from "@tanstack/react-query";
import { useInvalidatePostList } from "./useGetPostListInfiniteQuery";
export const useDeletePostMutation = () => {
diff --git a/client/src/queries/post/useGetPostDetailQuery.tsx b/client/src/queries/post/useGetPostDetailQuery.tsx
index 9054e2f..2133e18 100644
--- a/client/src/queries/post/useGetPostDetailQuery.tsx
+++ b/client/src/queries/post/useGetPostDetailQuery.tsx
@@ -1,4 +1,4 @@
-import { useSuspenseQuery } from "@tanstack/react-query";
+import { useQuery } from "@tanstack/react-query";
import axios from "@/libs/axios";
import { PostInterface } from "@/types/post/PostInterface";
@@ -6,7 +6,7 @@ const useGetPostDetailQuery = (
postId: string,
options?: { initialData: PostInterface }
) => {
- return useSuspenseQuery({
+ return useQuery({
queryKey: ["post", postId],
queryFn: () => getPostDetailQueryFn(postId),
initialData: options?.initialData,
diff --git a/client/src/queries/post/useGetPostListInfiniteQuery.tsx b/client/src/queries/post/useGetPostListInfiniteQuery.tsx
index 38f554e..5667dbd 100644
--- a/client/src/queries/post/useGetPostListInfiniteQuery.tsx
+++ b/client/src/queries/post/useGetPostListInfiniteQuery.tsx
@@ -49,6 +49,7 @@ export interface GetPostListOptions {
page?: number;
size?: number;
searchKeyword?: string;
+ searchUserNos?:string;
}
/**
* 실제 서버에서 응답해주는 값
diff --git a/client/src/stories/Components/Navigation/Navbar.stories.tsx b/client/src/stories/Components/Navigation/Navbar.stories.tsx
index 562477d..6bbfd2e 100644
--- a/client/src/stories/Components/Navigation/Navbar.stories.tsx
+++ b/client/src/stories/Components/Navigation/Navbar.stories.tsx
@@ -1,4 +1,4 @@
-import NavigationBar from "@/components/NavigationBar";
+import NavigationBar from "@/components/Navigation/NavigationBar";
import { Meta, StoryObj } from "@storybook/react";
const meta = {
diff --git a/client/src/types/auth/myInfo.ts b/client/src/types/auth/myInfo.ts
index 59c1962..46f356a 100644
--- a/client/src/types/auth/myInfo.ts
+++ b/client/src/types/auth/myInfo.ts
@@ -1,5 +1,6 @@
export interface MyInfoInterface {
id: string;
+ userNo:string;
nickname: string;
profileImages: ProfileImagesType[];
introduction: string;
diff --git a/client/src/types/post/PostInterface.ts b/client/src/types/post/PostInterface.ts
index 6f492d4..52d33a0 100644
--- a/client/src/types/post/PostInterface.ts
+++ b/client/src/types/post/PostInterface.ts
@@ -9,8 +9,12 @@ export interface PostInterface {
/**
* 업데이트 된 날짜
*/
- updateDt?: string;
+ lastModifiedDate?: string;
/**
+ * 해당 게시글을 생성한유저PK
+ */
+ createdBy:string;
+ /**
* 수정 됬는지 여부
*/
edited?: boolean;
diff --git a/client/src/utils/getTokenFromCookies.ts b/client/src/utils/getTokenFromCookies.ts
new file mode 100644
index 0000000..9b0c662
--- /dev/null
+++ b/client/src/utils/getTokenFromCookies.ts
@@ -0,0 +1,14 @@
+import { cookies } from "next/headers";
+
+/**
+ * 쿠키에서 AccessToken을 불러오는 유틸함수
+ * 서버단에서만 동작
+ */
+export default async function getTokenFromCookies() {
+ "use server";
+ if (typeof window !== "undefined") {
+ return;
+ }
+ const accessToken = cookies().get("accessToken")?.value;
+ return accessToken;
+}