diff --git a/client/public/mockServiceWorker.js b/client/public/mockServiceWorker.js
index 7898a62..78933b6 100644
--- a/client/public/mockServiceWorker.js
+++ b/client/public/mockServiceWorker.js
@@ -2,7 +2,7 @@
/* tslint:disable */
/**
- * Mock Service Worker (2.0.3).
+ * Mock Service Worker (2.0.4).
* @see https://github.com/mswjs/msw
* - Please do NOT modify this file.
* - Please do NOT serve this file on production.
diff --git a/client/src/app/@Modal/(.)post/[userId]/[postId]/page.tsx b/client/src/app/@Modal/(.)post/[userId]/[postId]/page.tsx
index 58560f7..182539e 100644
--- a/client/src/app/@Modal/(.)post/[userId]/[postId]/page.tsx
+++ b/client/src/app/@Modal/(.)post/[userId]/[postId]/page.tsx
@@ -1,22 +1,13 @@
import ModalWrapper from "@/components/ModalWrapper";
import PostDetail from "@/components/post/PostDetail";
-
-const mockData = {
- id: "123458",
- createdAt: "Mon Nov 06 2023 00:13:07",
- nickname: "testNick",
- userId: "userID",
- userImage: "https://source.unsplash.com/random?wallpapers",
- content:
- "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eos ullam aut minus aliquam quis officia, non dolore omnis, magnam totam tenetur ad harum? Mollitia omnis odit atque blanditiis exercitationem! Voluptatum.",
- image: ["https://source.unsplash.com/random?wallpapers"],
- tags: ["해시태그1", "해시태그2"],
-};
+import { Suspense } from "react";
const page = () => {
return (
-
+ 로딩>}>
+
+
);
};
diff --git a/client/src/app/layout.tsx b/client/src/app/layout.tsx
index dc527ac..4eaccf4 100644
--- a/client/src/app/layout.tsx
+++ b/client/src/app/layout.tsx
@@ -7,6 +7,7 @@ import Pretendard from "~/assets/font/Pretendard";
import NavigationBar from "~/components/NavigationBar";
import "./globals.css";
import MSWInit from "@/components/mock/MSWInit";
+import CustomQueryClientProvider from "@/components/queryClient/CustomQueryClientProvider";
export const metadata: Metadata = {
title: `${nameOfApp} | ${oneLineMessage}`,
@@ -27,7 +28,7 @@ export default function RootLayout({
return (
-
+
{Modal}
@@ -37,11 +38,11 @@ export default function RootLayout({
overflow: "auto",
}}
>
- {children}
+ {children}
-
+
);
diff --git a/client/src/app/page.tsx b/client/src/app/page.tsx
index d75255b..051987a 100644
--- a/client/src/app/page.tsx
+++ b/client/src/app/page.tsx
@@ -1,10 +1,19 @@
+"use client";
import PostCardList from "@/components/post/PostCardList";
+// import { getPostListQueryFn } from "@/queries/post/useGetPostListQuery";
import { Container } from "@mui/material";
+import { Suspense } from "react";
export default function Home() {
+ // const initialData = await getPostListQueryFn();
return (
-
+ 로딩중>}>
+ {/* FIXME */}{/* @ts-ignore*/}
+
+
);
}
diff --git a/client/src/components/post/PostCard.tsx b/client/src/components/post/PostCard.tsx
index 92c16e5..f6373fe 100644
--- a/client/src/components/post/PostCard.tsx
+++ b/client/src/components/post/PostCard.tsx
@@ -17,7 +17,6 @@ import {
CardMedia,
Typography,
ButtonBase,
- Button,
} from "@mui/material";
import PostHashTagList from "./PostHashtagList";
import { useOpenPostDetailPage } from "@/hooks/useOpenPostDetailPage";
@@ -32,10 +31,9 @@ const PostCard = ({
tagList,
postNo,
likeCount,
+ profileImgUrls
}: PostInterface) => {
const openPostDetailPage = useOpenPostDetailPage();
- // FIXME 유저이미지가 오지 않음
- const userImage = undefined;
const hasImage = useMemo(() => postAttachUrl.length !== 0, [postAttachUrl]);
return (
@@ -43,10 +41,10 @@ const PostCard = ({
- {userImage || id[0].toUpperCase()}
+ {profileImgUrls || id[0].toUpperCase()}
{/* Header */}
diff --git a/client/src/components/post/PostCardList.tsx b/client/src/components/post/PostCardList.tsx
index 59bedff..0a62745 100644
--- a/client/src/components/post/PostCardList.tsx
+++ b/client/src/components/post/PostCardList.tsx
@@ -1,20 +1,19 @@
"use client";
+
import PostCard from "@/components/post/PostCard";
import { PostInterface } from "@/types/post/PostInterface";
-import axios from "@/libs/axios";
-import { useEffect, useState } from "react";
+import useGetPostListQuery from "@/queries/post/useGetPostListQuery";
+
+interface PostCardListProps {
+ initialData: { content: PostInterface[] };
+}
-const PostCardList = () => {
- const [data, setData] = useState<{ content: PostInterface[] }>();
- useEffect(() => {
- axios.get<{ content: PostInterface[] }>("/posts").then(({ data }) => {
- setData(data);
- });
- }, []);
+const PostCardList = ({ initialData }: PostCardListProps) => {
+ const { data } = useGetPostListQuery(initialData);
return (
<>
- {data?.content.map((post) => (
+ {data.content.map((post) => (
))}
>
diff --git a/client/src/components/post/PostDetail.tsx b/client/src/components/post/PostDetail.tsx
index b722855..89de4ce 100644
--- a/client/src/components/post/PostDetail.tsx
+++ b/client/src/components/post/PostDetail.tsx
@@ -1,3 +1,5 @@
+// FIXME 실제 서버연결시 바꿔야함
+"use client";
import { PostInterface } from "@/types/post/PostInterface";
import {
Avatar,
@@ -11,53 +13,59 @@ import {
Typography,
} from "@mui/material";
import PostHashTagList from "./PostHashtagList";
+import { FavoriteBorder, ShareOutlined } from "@mui/icons-material";
+import useGetPostDetailQuery from "@/queries/post/useGetPostDetailQuery";
-const PostDetail = ({
- image,
- createdAt,
- userId,
- nickname,
- content,
- userImage,
- tags,
- id,
-}: PostInterface) => {
+const PostDetail = () => {
+ const { data } = useGetPostDetailQuery('1');
+ const {
+ postAttachUrl,
+ createdAt,
+ id,
+ nickname,
+ postContent,
+ tagList,
+ likeCount,
+ profileImgUrls,
+ }: PostInterface = data
return (
- {userImage || userId[0].toUpperCase()}
+ {profileImgUrls || id[0].toUpperCase()}
}
- title={`${userId} ${nickname}`}
+ title={`${id} ${nickname}`}
subheader={createdAt}
sx={{ p: 0 }}
/>
- {content}
-
+ {postContent}
+
{/* 이미지 */}
- {image.length !== 0 && (
+ {postAttachUrl.length !== 0 && (
)}
- 좋아요
+
+ {likeCount}
+
공유하기
diff --git a/client/src/components/queryClient/CustomQueryClientProvider.tsx b/client/src/components/queryClient/CustomQueryClientProvider.tsx
new file mode 100644
index 0000000..e1aaea9
--- /dev/null
+++ b/client/src/components/queryClient/CustomQueryClientProvider.tsx
@@ -0,0 +1,16 @@
+"use client";
+
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ReactNode, useState } from "react";
+
+export default function CustomQueryClientProvider({
+ children,
+}: {
+ children?: ReactNode;
+}) {
+ const [queryClient] = useState(() => new QueryClient());
+
+ return (
+ {children}
+ );
+}
diff --git a/client/src/mocks/handlers.ts b/client/src/mocks/handlers.ts
index b7062a3..97e450a 100644
--- a/client/src/mocks/handlers.ts
+++ b/client/src/mocks/handlers.ts
@@ -1,38 +1,6 @@
-import { HttpResponse, http } from "msw";
-import { randomNumber, randomSelect } from "./utils/random";
-import { PostInterface } from "@/types/post/PostInterface";
+import getPostList from "./handlers/getPostList";
+import getPostDetail from "./handlers/getPostDetail";
export const handlers = [
- http.get(`${process.env.NEXT_PUBLIC_BASE_URL}/posts`, () => {
- return HttpResponse.json({
- content: Array.from(new Array(5)).map((_data, i):PostInterface => {
- return {
- nickname: "testNick",
- id: "userID",
- updateDt: "2023-11-08T13:05:09.531Z",
- createdAt: "2023-11-08T13:05:09.531Z",
- edited: randomSelect(true, false),
- postNo: i,
- postContent:
- "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eos ullam aut minus aliquam quis officia, non dolore omnis, magnam totam tenetur ad harum? Mollitia omnis odit atque blanditiis exercitationem! Voluptatum.",
- positionInfo: "울릉도 동남쪽 뱃길따라 200리",
- alcoholName: "string",
- postAttachUrl: ["https://source.unsplash.com/random?wallpapers"],
- tagList: randomSelect(["tag1", "tag2"], []),
- quoteInfo: randomSelect(
- [
- {
- quoteNo: 1,
- quoteContent: "1",
- },
- ],
- []
- ),
- likeCount: randomNumber(),
- quoteCount: randomNumber(),
- followedByMe: randomSelect(true, false),
- };
- }),
- });
- }),
+ getPostList,getPostDetail
];
diff --git a/client/src/mocks/handlers/getPostDetail.ts b/client/src/mocks/handlers/getPostDetail.ts
new file mode 100644
index 0000000..bfcda67
--- /dev/null
+++ b/client/src/mocks/handlers/getPostDetail.ts
@@ -0,0 +1,42 @@
+import { PostInterface } from "@/types/post/PostInterface";
+import { HttpResponse, http } from "msw";
+import { randomBoolean, randomNumber, randomSelect } from "../utils/random";
+/**
+ * 포스트 상세보기 정보를 받아오는 핸들러
+ */
+export default http.get(`${process.env.NEXT_PUBLIC_BASE_URL}/posts/1`, () => {
+ return HttpResponse.json({
+ nickname: "testNick",
+ id: "userID",
+ updateDt: "2023-11-08T13:05:09.531Z",
+ createdAt: "2023-11-08T13:05:09.531Z",
+ edited: randomBoolean(),
+ postNo: 135,
+ postContent:
+ "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eos ullam aut minus aliquam quis officia, non dolore omnis, magnam totam tenetur ad harum? Mollitia omnis odit atque blanditiis exercitationem! Voluptatum.",
+ positionInfo: "울릉도 동남쪽 뱃길따라 200리",
+ alcoholName: "string",
+ postAttachUrl: randomSelect(
+ ["https://source.unsplash.com/random?wallpapers"],
+ []
+ ),
+ tagList: randomSelect(["tag1", "tag2"], []),
+ quoteInfo: randomSelect(
+ [
+ {
+ quoteNo: 1,
+ quoteContent: "1",
+ },
+ ],
+ []
+ ),
+ likeCount: randomNumber(),
+ quoteCount: randomNumber(),
+ followedByMe: randomBoolean(),
+ likedByme: randomBoolean(),
+ profileImgUrls: randomSelect(
+ "https://source.unsplash.com/random?wallpapers",
+ ""
+ ),
+ });
+ });
diff --git a/client/src/mocks/handlers/getPostList.ts b/client/src/mocks/handlers/getPostList.ts
new file mode 100644
index 0000000..989b929
--- /dev/null
+++ b/client/src/mocks/handlers/getPostList.ts
@@ -0,0 +1,47 @@
+import { PostInterface } from "@/types/post/PostInterface";
+import { HttpResponse, http } from "msw";
+import { randomBoolean, randomNumber, randomSelect } from "../utils/random";
+/**
+ * 포스트 리스트를 받아오는 핸들러
+ */
+export default http.get(`${process.env.NEXT_PUBLIC_BASE_URL}/posts`, () => {
+ return HttpResponse.json({
+ content: Array.from(new Array(5)).map((_data, i): PostInterface => {
+ return {
+ nickname: "testNick",
+ id: "userID",
+ updateDt: "2023-11-08T13:05:09.531Z",
+ createdAt: "2023-11-08T13:05:09.531Z",
+ edited: randomBoolean(),
+ postNo: i,
+ postContent:
+ "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eos ullam aut minus aliquam quis officia, non dolore omnis, magnam totam tenetur ad harum? Mollitia omnis odit atque blanditiis exercitationem! Voluptatum.",
+ positionInfo: "울릉도 동남쪽 뱃길따라 200리",
+ alcoholName: "string",
+ postAttachUrl: randomSelect(
+ ["https://source.unsplash.com/random?wallpapers"],
+ []
+ ),
+ tagList: randomSelect(["tag1", "tag2"], []),
+ quoteInfo: randomSelect(
+ [
+ {
+ quoteNo: 1,
+ quoteContent: "1",
+ },
+ ],
+ []
+ ),
+ likeCount: randomNumber(),
+ quoteCount: randomNumber(),
+ followedByMe: randomBoolean(),
+ likedByme: randomBoolean(),
+ profileImgUrls: randomSelect(
+ "https://source.unsplash.com/random?wallpapers",
+ ""
+ ),
+ };
+ }),
+ });
+ });
+
diff --git a/client/src/queries/post/useGetPostDetailQuery.tsx b/client/src/queries/post/useGetPostDetailQuery.tsx
new file mode 100644
index 0000000..e268127
--- /dev/null
+++ b/client/src/queries/post/useGetPostDetailQuery.tsx
@@ -0,0 +1,20 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "@/libs/axios";
+import { PostInterface } from "@/types/post/PostInterface";
+
+const useGetPostDetailQuery = (postId: string) => {
+ return useSuspenseQuery({
+ queryKey: ["post", postId],
+ queryFn: () => getPostListQueryFn(postId),
+ // initialData: initialData,
+ });
+};
+
+export const getPostListQueryFn = async (postId: string) => {
+ const { data } = await axios.get(
+ `/posts/${postId}`
+ );
+ return data;
+};
+
+export default useGetPostDetailQuery;
diff --git a/client/src/queries/post/useGetPostListQuery.tsx b/client/src/queries/post/useGetPostListQuery.tsx
new file mode 100644
index 0000000..1e3b49a
--- /dev/null
+++ b/client/src/queries/post/useGetPostListQuery.tsx
@@ -0,0 +1,18 @@
+import { useSuspenseQuery } from "@tanstack/react-query";
+import axios from "@/libs/axios";
+import { PostInterface } from "@/types/post/PostInterface";
+
+const useGetPostListQuery = (initialData: { content: PostInterface[] }) => {
+ return useSuspenseQuery({
+ queryKey: ["posts"],
+ queryFn: getPostListQueryFn,
+ initialData: initialData,
+ });
+};
+
+export const getPostListQueryFn = async () => {
+ const { data } = await axios.get<{ content: PostInterface[] }>("/posts");
+ return data;
+};
+
+export default useGetPostListQuery;
diff --git a/client/src/types/post/PostInterface.ts b/client/src/types/post/PostInterface.ts
index 213e0b0..bc0e2b4 100644
--- a/client/src/types/post/PostInterface.ts
+++ b/client/src/types/post/PostInterface.ts
@@ -25,7 +25,7 @@ export interface PostInterface {
/**
* 게시글 내 위치 정보
*/
- positionInfo:string;
+ positionInfo: string;
/**
* 마신 술 정보
*/
@@ -38,6 +38,10 @@ export interface PostInterface {
* 유저가 설정한 닉네임
*/
nickname: string;
+ /**
+ * 유저가 설정한 프로필 이미지
+ */
+ profileImgUrls: string;
/**
* 이미지 Href 배열
*/
@@ -62,6 +66,10 @@ export interface PostInterface {
* 내가 팔로우 하는지 여부
*/
followedByMe: boolean;
+ /**
+ * 내가 좋아요를 눌렀는지 여부
+ */
+ likedByme :boolean;
}
type QuoteInfoType = {