From bc2e3d0a027d4cdb312ad6fed9a0e3174c32e48b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=98=81=EA=B8=B8/KIM=20YOUNG=20GIL?=
<80146176+Gilpop8663@users.noreply.github.com>
Date: Thu, 3 Aug 2023 11:37:54 +0900
Subject: [PATCH] =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC,=20?=
=?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EB=AA=A9=EB=A1=9D=20=EC=97=B0?=
=?UTF-8?q?=EB=8F=99=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81=20?=
=?UTF-8?q?(#219)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: (#205) 카테고리에 관련된 API 서버와 연동
wus폴더에 있던 파일들 밖으로 이동
* feat: (#205) 게시글 작성 페이지에서 카테고리 리스트를 불러와 옵션으로 변환하는 기능 구현
* refactor: (#205) 마감 시간을 구하는 유틸 함수 분리
* refactor: (#205) sua 폴더에 있던 post.ts MSW 코드를 밖의 post.ts 파일과 병합
* refactor: (#205) wus 폴더에 있던 유저 MSW 코드 밖으로 이동
* refactor: (#205) wus 폴더의 게시글 목록 MSW 코드를 밖으로 분리 및 파일명 변경
* refactor: (#205) api 폴더에 있던 wus 폴더 삭제 및 파일 이동
* refactor: (#205) 댓글을 제외한 나머지 api에 BASE_URL 코드 추가
* refactor: (#205) AuthContext에서 User 타입 변경 및 액세스 토큰이 있을 경우 isLogged:true로 수정
* fix: (#205) 게시글의 카테고리 리스트에 ?를 붙혀 없어도 에러가 나지 않게 수정
* feat: (#205) 게시글 서버에서 받는 타입 명세 선언
* refactor: (#205) 서버에서 받은 게시글 목록을 클라이언트에서 사용하는 게시글 목록 명세로 변환
* refactor: (#205) 게시글 명세인 startTime, endTime의 이름을 변경
---
frontend/__test__/api/categoryList.test.ts | 2 +-
frontend/__test__/api/postList.test.ts | 12 +--
frontend/__test__/api/user.test.ts | 2 +-
.../__test__/changeCategoryToOption.test.ts | 27 ++++++
frontend/__test__/getDeadlineTime.test.ts | 53 ++++++++++++
.../hooks/query/useCategoryList.test.tsx | 48 +++++++++++
.../__test__/hooks/query/usePostList.test.tsx | 22 +++--
frontend/src/api/{wus => }/categoryList.ts | 10 ++-
frontend/src/api/comment.ts | 1 +
frontend/src/api/post.ts | 43 ++++++++--
frontend/src/api/postList.ts | 10 ++-
frontend/src/api/{wus => }/userInfo.ts | 2 +-
frontend/src/api/voteResult.ts | 6 +-
.../components/PostForm/PostForm.stories.tsx | 4 +-
frontend/src/components/PostForm/index.tsx | 52 ++++--------
.../src/components/common/Layout/index.tsx | 7 +-
frontend/src/components/common/Post/index.tsx | 8 +-
.../src/components/common/Post/mockData.ts | 8 +-
frontend/src/hooks/context/auth.tsx | 2 +-
.../category/useCategoryFavoriteToggle.ts | 2 +-
.../hooks/query/category/useCategoryList.ts | 2 +-
frontend/src/hooks/query/usePostList.tsx | 1 +
frontend/src/hooks/query/user/useUserInfo.ts | 6 +-
frontend/src/index.tsx | 12 +--
frontend/src/mocks/{wus => }/categoryList.ts | 0
frontend/src/mocks/handlers.ts | 6 +-
frontend/src/mocks/mockData/post.ts | 12 ++-
frontend/src/mocks/mockData/postList.ts | 53 ++++++------
frontend/src/mocks/post.ts | 28 ++++++-
.../src/mocks/{wus/post.ts => postList.ts} | 0
frontend/src/mocks/sua/post.ts | 82 -------------------
frontend/src/mocks/{wus => }/userInfo.ts | 0
frontend/src/pages/MyInfo/index.tsx | 19 ++---
frontend/src/pages/post/EditPost/index.tsx | 4 +-
frontend/src/pages/post/PostDetail/index.tsx | 2 +-
frontend/src/types/post.ts | 28 ++++++-
frontend/src/types/user.ts | 3 +-
.../src/utils/post/changeCategoryToOption.ts | 7 ++
frontend/src/utils/post/getDeadlineTime.ts | 33 ++++++++
frontend/src/utils/time.ts | 4 +-
40 files changed, 395 insertions(+), 228 deletions(-)
create mode 100644 frontend/__test__/changeCategoryToOption.test.ts
create mode 100644 frontend/__test__/getDeadlineTime.test.ts
create mode 100644 frontend/__test__/hooks/query/useCategoryList.test.tsx
rename frontend/src/api/{wus => }/categoryList.ts (65%)
rename frontend/src/api/{wus => }/userInfo.ts (93%)
rename frontend/src/mocks/{wus => }/categoryList.ts (100%)
rename frontend/src/mocks/{wus/post.ts => postList.ts} (100%)
delete mode 100644 frontend/src/mocks/sua/post.ts
rename frontend/src/mocks/{wus => }/userInfo.ts (100%)
create mode 100644 frontend/src/utils/post/changeCategoryToOption.ts
create mode 100644 frontend/src/utils/post/getDeadlineTime.ts
diff --git a/frontend/__test__/api/categoryList.test.ts b/frontend/__test__/api/categoryList.test.ts
index eaf34f352..ccc34acb5 100644
--- a/frontend/__test__/api/categoryList.test.ts
+++ b/frontend/__test__/api/categoryList.test.ts
@@ -4,7 +4,7 @@ import {
getUserCategoryList,
removeFavoriteCategory,
transformCategoryListResponse,
-} from '@api/wus/categoryList';
+} from '@api/categoryList';
import { MOCK_CATEGORY_LIST, MOCK_GUEST_CATEGORY_LIST } from '@mocks/mockData/categoryList';
diff --git a/frontend/__test__/api/postList.test.ts b/frontend/__test__/api/postList.test.ts
index 57f594d3a..33ae82d61 100644
--- a/frontend/__test__/api/postList.test.ts
+++ b/frontend/__test__/api/postList.test.ts
@@ -2,7 +2,7 @@ import { getPostList } from '@api/postList';
import { POST_TYPE, SORTING, STATUS } from '@constants/post';
-import { MOCK_POST_LIST } from '@mocks/mockData/postList';
+import { MOCK_TRANSFORM_POST_LIST } from '@mocks/mockData/postList';
describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확인한다.', () => {
test('게시글 목록의 개수는 10개씩 불러온다.', async () => {
@@ -36,7 +36,7 @@ describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확
}
);
- expect(data.postList).toEqual(MOCK_POST_LIST);
+ expect(data.postList).toEqual(MOCK_TRANSFORM_POST_LIST);
});
test('게시글 페이지의 정보를 불러온다.', async () => {
@@ -70,7 +70,7 @@ describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확
}
);
- expect(data.postList).toEqual(MOCK_POST_LIST);
+ expect(data.postList).toEqual(MOCK_TRANSFORM_POST_LIST);
});
test('내가 작성한 게시글 페이지의 정보를 불러온다.', async () => {
@@ -87,7 +87,7 @@ describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확
}
);
- expect(data.postList).toEqual(MOCK_POST_LIST);
+ expect(data.postList).toEqual(MOCK_TRANSFORM_POST_LIST);
});
test('내가 투표한 게시글 페이지의 정보를 불러온다.', async () => {
@@ -104,7 +104,7 @@ describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확
}
);
- expect(data.postList).toEqual(MOCK_POST_LIST);
+ expect(data.postList).toEqual(MOCK_TRANSFORM_POST_LIST);
});
test('내가 검색한 게시글 페이지의 정보를 불러온다.', async () => {
@@ -121,6 +121,6 @@ describe('서버와 통신하여 전체 게시글 목록을 불러오는지 확
}
);
- expect(data.postList).toEqual(MOCK_POST_LIST);
+ expect(data.postList).toEqual(MOCK_TRANSFORM_POST_LIST);
});
});
diff --git a/frontend/__test__/api/user.test.ts b/frontend/__test__/api/user.test.ts
index 870bc36f4..aef7a4a3d 100644
--- a/frontend/__test__/api/user.test.ts
+++ b/frontend/__test__/api/user.test.ts
@@ -3,7 +3,7 @@ import {
getUserInfo,
modifyNickname,
transformUserInfoResponse,
-} from '@api/wus/userInfo';
+} from '@api/userInfo';
import { MOCK_USER_INFO } from '@mocks/mockData/user';
diff --git a/frontend/__test__/changeCategoryToOption.test.ts b/frontend/__test__/changeCategoryToOption.test.ts
new file mode 100644
index 000000000..5f1d34d71
--- /dev/null
+++ b/frontend/__test__/changeCategoryToOption.test.ts
@@ -0,0 +1,27 @@
+import { Category } from '@type/category';
+
+import { Option } from '@components/common/MultiSelect/types';
+
+import { changeCategoryToOption } from '@utils/post/changeCategoryToOption';
+
+describe('changeCategoryToOption 함수를 이용해서 카테고리 리스트를 셀렉트 컴포넌트에 사용되는 옵션 리스트로 변환한다.', () => {
+ test('카테고리 리스트로 옵션 리스트를 만든다.', () => {
+ const categoryList: Category[] = [
+ { id: 1, isFavorite: false, name: '갤럭시' },
+ { id: 2, isFavorite: true, name: '애플' },
+ ];
+
+ const result: Option[] = changeCategoryToOption(categoryList);
+
+ expect(result).toEqual([
+ {
+ id: 1,
+ name: '갤럭시',
+ },
+ {
+ id: 2,
+ name: '애플',
+ },
+ ]);
+ });
+});
diff --git a/frontend/__test__/getDeadlineTime.test.ts b/frontend/__test__/getDeadlineTime.test.ts
new file mode 100644
index 000000000..162e19740
--- /dev/null
+++ b/frontend/__test__/getDeadlineTime.test.ts
@@ -0,0 +1,53 @@
+import { getDeadlineTime } from '@utils/post/getDeadlineTime';
+
+describe('getDeadlineTime를 이용하여 사용자에게 마감 시간을 알려준다.', () => {
+ test('5분을 설정했을 때 5분으로 표시된다', () => {
+ const result = getDeadlineTime({
+ day: 0,
+ hour: 0,
+ minute: 5,
+ });
+
+ expect(result).toBe('5분 후에 마감됩니다.');
+ });
+
+ test('1시간 5분을 설정했을 때 1시간 5분으로 표시된다', () => {
+ const result = getDeadlineTime({
+ day: 0,
+ hour: 1,
+ minute: 5,
+ });
+
+ expect(result).toBe('1시간 5분 후에 마감됩니다.');
+ });
+
+ test('2일 23시간 59분을 설정했을 때 2일 23시간 59분으로 표시된다', () => {
+ const result = getDeadlineTime({
+ day: 2,
+ hour: 23,
+ minute: 59,
+ });
+
+ expect(result).toBe('2일 23시간 59분 후에 마감됩니다.');
+ });
+
+ test('0일 0시간 0분을 설정했을 때 "마감 시간을 선택해주세요"를 표시된다', () => {
+ const result = getDeadlineTime({
+ day: 0,
+ hour: 0,
+ minute: 0,
+ });
+
+ expect(result).toBe('마감 시간을 선택해주세요');
+ });
+
+ test('-1일 -1시간 -1분을 설정했을 때 "마감 시간을 다시 설정해주세요"를 표시된다', () => {
+ const result = getDeadlineTime({
+ day: -1,
+ hour: -1,
+ minute: -1,
+ });
+
+ expect(result).toBe('마감 시간을 다시 설정해주세요');
+ });
+});
diff --git a/frontend/__test__/hooks/query/useCategoryList.test.tsx b/frontend/__test__/hooks/query/useCategoryList.test.tsx
new file mode 100644
index 000000000..d7fd1a04e
--- /dev/null
+++ b/frontend/__test__/hooks/query/useCategoryList.test.tsx
@@ -0,0 +1,48 @@
+import React, { ReactNode } from 'react';
+
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
+import { renderHook, waitFor } from '@testing-library/react';
+
+import { useCategoryList } from '@hooks/query/category/useCategoryList';
+
+import { transformCategoryListResponse } from '@api/categoryList';
+
+import { MOCK_CATEGORY_LIST, MOCK_GUEST_CATEGORY_LIST } from '@mocks/mockData/categoryList';
+
+const queryClient = new QueryClient();
+
+const wrapper = ({ children }: { children: ReactNode }) => (
+ {children}
+);
+
+describe('useCategoryList 훅이 카테고리 목록을 불러오는지 확인한다.', () => {
+ test('비회원 카테고리 목록을 불러온다.', async () => {
+ const { result } = renderHook(() => useCategoryList(false), {
+ wrapper,
+ });
+
+ await waitFor(() =>
+ expect(result.current.data).toEqual(transformCategoryListResponse(MOCK_GUEST_CATEGORY_LIST))
+ );
+ });
+
+ test('회원 카테고리 목록을 불러온다.', async () => {
+ const { result } = renderHook(() => useCategoryList(true), {
+ wrapper,
+ });
+
+ await waitFor(() =>
+ expect(result.current.data).toEqual(transformCategoryListResponse(MOCK_CATEGORY_LIST))
+ );
+ });
+
+ test('회원 카테고리 목록을 불러온다.', async () => {
+ const { result } = renderHook(() => useCategoryList(true), {
+ wrapper,
+ });
+
+ await waitFor(() =>
+ expect(result.current.data).toEqual(transformCategoryListResponse(MOCK_CATEGORY_LIST))
+ );
+ });
+});
diff --git a/frontend/__test__/hooks/query/usePostList.test.tsx b/frontend/__test__/hooks/query/usePostList.test.tsx
index 1595cf016..9f4944712 100644
--- a/frontend/__test__/hooks/query/usePostList.test.tsx
+++ b/frontend/__test__/hooks/query/usePostList.test.tsx
@@ -7,7 +7,7 @@ import { usePostList } from '@hooks/query/usePostList';
import { POST_TYPE, SORTING, STATUS } from '@constants/post';
-import { MOCK_POST_LIST } from '@mocks/mockData/postList';
+import { MOCK_TRANSFORM_POST_LIST } from '@mocks/mockData/postList';
const queryClient = new QueryClient();
@@ -35,7 +35,9 @@ describe('usePostList 훅이 게시글 목록을 불러오는지 확인한다.',
}
);
- await waitFor(() => expect(result.current.data?.pages[0].postList).toEqual(MOCK_POST_LIST));
+ await waitFor(() =>
+ expect(result.current.data?.pages[0].postList).toEqual(MOCK_TRANSFORM_POST_LIST)
+ );
});
test('카테고리별 게시글 목록을 불러온다.', async () => {
@@ -57,7 +59,9 @@ describe('usePostList 훅이 게시글 목록을 불러오는지 확인한다.',
}
);
- await waitFor(() => expect(result.current.data?.pages[0].postList).toEqual(MOCK_POST_LIST));
+ await waitFor(() =>
+ expect(result.current.data?.pages[0].postList).toEqual(MOCK_TRANSFORM_POST_LIST)
+ );
});
test('내가 작성한 게시글 목록을 불러온다.', async () => {
@@ -79,7 +83,9 @@ describe('usePostList 훅이 게시글 목록을 불러오는지 확인한다.',
}
);
- await waitFor(() => expect(result.current.data?.pages[0].postList).toEqual(MOCK_POST_LIST));
+ await waitFor(() =>
+ expect(result.current.data?.pages[0].postList).toEqual(MOCK_TRANSFORM_POST_LIST)
+ );
});
test('내가 투표한 게시글 목록을 불러온다.', async () => {
@@ -101,7 +107,9 @@ describe('usePostList 훅이 게시글 목록을 불러오는지 확인한다.',
}
);
- await waitFor(() => expect(result.current.data?.pages[0].postList).toEqual(MOCK_POST_LIST));
+ await waitFor(() =>
+ expect(result.current.data?.pages[0].postList).toEqual(MOCK_TRANSFORM_POST_LIST)
+ );
});
test('내가 검색한 게시글 목록을 불러온다.', async () => {
@@ -123,6 +131,8 @@ describe('usePostList 훅이 게시글 목록을 불러오는지 확인한다.',
}
);
- await waitFor(() => expect(result.current.data?.pages[0].postList).toEqual(MOCK_POST_LIST));
+ await waitFor(() =>
+ expect(result.current.data?.pages[0].postList).toEqual(MOCK_TRANSFORM_POST_LIST)
+ );
});
});
diff --git a/frontend/src/api/wus/categoryList.ts b/frontend/src/api/categoryList.ts
similarity index 65%
rename from frontend/src/api/wus/categoryList.ts
rename to frontend/src/api/categoryList.ts
index d899874af..7b329df08 100644
--- a/frontend/src/api/wus/categoryList.ts
+++ b/frontend/src/api/categoryList.ts
@@ -10,22 +10,24 @@ export const transformCategoryListResponse = (categoryList: CategoryResponse[])
}));
};
+const BASE_URL = process.env.VOTOGETHER_BASE_URL;
+
export const getUserCategoryList = async () => {
- const categoryList = await getFetch('/categories');
+ const categoryList = await getFetch(`${BASE_URL}/categories`);
return transformCategoryListResponse(categoryList);
};
export const getGuestCategoryList = async () => {
- const categoryList = await getFetch('/categories/guest');
+ const categoryList = await getFetch(`${BASE_URL}/categories/guest`);
return transformCategoryListResponse(categoryList);
};
export const addFavoriteCategory = async (categoryId: number) => {
- await postFetch(`/categories/${categoryId}/like`, '');
+ await postFetch(`${BASE_URL}/categories/${categoryId}/like`, '');
};
export const removeFavoriteCategory = async (categoryId: number) => {
- await deleteFetch(`/categories/${categoryId}/like`);
+ await deleteFetch(`${BASE_URL}/categories/${categoryId}/like`);
};
diff --git a/frontend/src/api/comment.ts b/frontend/src/api/comment.ts
index 1f87c568d..5f82e0088 100644
--- a/frontend/src/api/comment.ts
+++ b/frontend/src/api/comment.ts
@@ -11,6 +11,7 @@ export const transformCommentListResponse = (commentList: CommentResponse[]): Co
isEdit: comment.createdAt !== comment.updatedAt,
}));
};
+
export const getCommentList = async (postId: number): Promise => {
const commentList = await getFetch(`/posts/${postId}/comments`);
diff --git a/frontend/src/api/post.ts b/frontend/src/api/post.ts
index 4666b886b..b570bb74b 100644
--- a/frontend/src/api/post.ts
+++ b/frontend/src/api/post.ts
@@ -1,4 +1,4 @@
-import { PostInfo } from '@type/post';
+import { PostInfo, PostInfoResponse } from '@type/post';
import {
getFetch,
@@ -11,8 +11,35 @@ import {
const BASE_URL = process.env.VOTOGETHER_BASE_URL;
+export const transformPostResponse = (post: PostInfoResponse): PostInfo => {
+ return {
+ category: post.categories.map(category => ({ id: category.id, name: category.name })),
+ content: post.content,
+ deadline: post.deadline,
+ imageUrl: post.imageUrl,
+ postId: post.postId,
+ createTime: post.createdAt,
+ title: post.title,
+ voteInfo: {
+ allPeopleCount: post.voteInfo.totalVoteCount,
+ selectedOptionId: post.voteInfo.selectedOptionId,
+ options: post.voteInfo.options.map(option => ({
+ id: option.optionId,
+ text: option.content,
+ peopleCount: option.voteCount,
+ percent: option.votePercent,
+ imageUrl: option.imageUrl,
+ })),
+ },
+ writer: {
+ id: post.writer.id,
+ nickname: post.writer.nickname,
+ },
+ };
+};
+
export const votePost = async (postId: number, optionId: number) => {
- return await postFetch(`/posts/${postId}/options/${optionId}`, '');
+ return await postFetch(`${BASE_URL}/posts/${postId}/options/${optionId}`, '');
};
interface OptionData {
@@ -22,12 +49,14 @@ interface OptionData {
export const changeVotedOption = async (postId: number, optionData: OptionData) => {
return await patchFetch(
- `/posts/${postId}/options?source=${optionData.originOptionId}&target=${optionData.newOptionId}`
+ `${BASE_URL}/posts/${postId}/options?source=${optionData.originOptionId}&target=${optionData.newOptionId}`
);
};
export const getPost = async (postId: number): Promise => {
- return await getFetch(`/posts/${postId}`);
+ const post = await getFetch(`${BASE_URL}/posts/${postId}`);
+
+ return transformPostResponse(post);
};
export const createPost = async (newPost: FormData) => {
@@ -35,13 +64,13 @@ export const createPost = async (newPost: FormData) => {
};
export const editPost = async (postId: number, updatedPost: FormData) => {
- return await multiPutFetch(`http://3.35.232.54/api/posts/${postId}`, updatedPost);
+ return await multiPutFetch(`${BASE_URL}/posts/${postId}`, updatedPost);
};
export const removePost = async (postId: number) => {
- return await deleteFetch(`/posts/${postId}`);
+ return await deleteFetch(`${BASE_URL}/posts/${postId}`);
};
export const setEarlyClosePost = async (postId: number) => {
- return await patchFetch(`/posts/${postId}/close`);
+ return await patchFetch(`${BASE_URL}/posts/${postId}/close`);
};
diff --git a/frontend/src/api/postList.ts b/frontend/src/api/postList.ts
index b5aaa1189..089623883 100644
--- a/frontend/src/api/postList.ts
+++ b/frontend/src/api/postList.ts
@@ -1,4 +1,4 @@
-import { PostInfo, PostListByOptionalOption, PostListByRequiredOption } from '@type/post';
+import { PostInfoResponse, PostListByOptionalOption, PostListByRequiredOption } from '@type/post';
import {
REQUEST_STATUS_OPTION,
@@ -10,7 +10,9 @@ import {
import { getFetch } from '@utils/fetch';
-const BASE_URL = process.env.VOTOGETHER_MOCKING_URL;
+import { transformPostResponse } from './post';
+
+const BASE_URL = process.env.VOTOGETHER_BASE_URL;
export const makePostListUrl = (
requiredOption: PostListByRequiredOption,
@@ -44,10 +46,10 @@ export const getPostList = async (
const postListUrl = makePostListUrl(requiredOption, optionalOption);
- const postList = await getFetch(postListUrl);
+ const postList = await getFetch(postListUrl);
return {
pageNumber,
- postList,
+ postList: postList.map(post => transformPostResponse(post)),
};
};
diff --git a/frontend/src/api/wus/userInfo.ts b/frontend/src/api/userInfo.ts
similarity index 93%
rename from frontend/src/api/wus/userInfo.ts
rename to frontend/src/api/userInfo.ts
index e712fc403..023ca2e83 100644
--- a/frontend/src/api/wus/userInfo.ts
+++ b/frontend/src/api/userInfo.ts
@@ -16,7 +16,7 @@ export const transformUserInfoResponse = (userInfo: UserInfoResponse): User => {
const BASE_URL = process.env.VOTOGETHER_BASE_URL;
-export const getUserInfo = async () => {
+export const getUserInfo = async (): Promise => {
const userInfo = await getFetch(`${BASE_URL}/members/me`);
return transformUserInfoResponse(userInfo);
diff --git a/frontend/src/api/voteResult.ts b/frontend/src/api/voteResult.ts
index d6bce671d..614ba5e0f 100644
--- a/frontend/src/api/voteResult.ts
+++ b/frontend/src/api/voteResult.ts
@@ -2,8 +2,10 @@ import { VoteResult } from '@components/VoteStatistics/type';
import { getFetch } from '@utils/fetch';
+const BASE_URL = process.env.VOTOGETHER_BASE_URL;
+
export const getPostStatistics = async (postId: number): Promise => {
- return await getFetch(`/posts/${postId}/options`);
+ return await getFetch(`${BASE_URL}/posts/${postId}/options`);
};
export const getOptionStatistics = async ({
@@ -13,5 +15,5 @@ export const getOptionStatistics = async ({
postId: number;
optionId: number;
}): Promise => {
- return await getFetch(`/posts/${postId}/options/${optionId}`);
+ return await getFetch(`${BASE_URL}/posts/${postId}/options/${optionId}`);
};
diff --git a/frontend/src/components/PostForm/PostForm.stories.tsx b/frontend/src/components/PostForm/PostForm.stories.tsx
index e9b255a38..13fe3863b 100644
--- a/frontend/src/components/PostForm/PostForm.stories.tsx
+++ b/frontend/src/components/PostForm/PostForm.stories.tsx
@@ -25,8 +25,8 @@ const MOCK_DATA: PostInfo = {
{ id: 13217, name: '게임' },
{ id: 13219, name: '연예' },
],
- startTime: '2023-07-18 12:40',
- endTime: '2023-08-15 12:40',
+ createTime: '2023-07-18 12:40',
+ deadline: '2023-08-15 12:40',
voteInfo: {
selectedOptionId: 1,
allPeopleCount: 0,
diff --git a/frontend/src/components/PostForm/index.tsx b/frontend/src/components/PostForm/index.tsx
index c88ec73c5..2589ffb0a 100644
--- a/frontend/src/components/PostForm/index.tsx
+++ b/frontend/src/components/PostForm/index.tsx
@@ -1,10 +1,12 @@
import type { UseMutateFunction } from '@tanstack/react-query';
-import React, { HTMLAttributes, useState } from 'react';
+import React, { HTMLAttributes, useContext, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { PostInfo } from '@type/post';
+import { AuthContext } from '@hooks/context/auth';
+import { useCategoryList } from '@hooks/query/category/useCategoryList';
import { useContentImage } from '@hooks/useContentImage';
import { useMultiSelect } from '@hooks/useMultiSelect';
import { useText } from '@hooks/useText';
@@ -20,9 +22,9 @@ import WritingVoteOptionList from '@components/optionList/WritingVoteOptionList'
import { POST_DESCRIPTION_MAX_LENGTH, POST_TITLE_MAX_LENGTH } from '@constants/post';
+import { changeCategoryToOption } from '@utils/post/changeCategoryToOption';
import { addTimeToDate, formatTimeWithOption } from '@utils/post/formatTime';
-
-import { MOCK_CATEGORY_LIST } from '@mocks/mockData/categoryList';
+import { getDeadlineTime } from '@utils/post/getDeadlineTime';
import { DEADLINE_OPTION } from './constants';
import ContentImagePart from './ContentImageSection';
@@ -44,8 +46,8 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
title,
content,
category: categoryIds,
- startTime,
- endTime: deadline,
+ createTime,
+ deadline,
voteInfo,
imageUrl,
} = data ?? {};
@@ -53,6 +55,8 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
const navigate = useNavigate();
const writingOptionHook = useWritingOption(voteInfo?.options);
const contentImageHook = useContentImage(imageUrl);
+ const { isLogged } = useContext(AuthContext).loggedInfo;
+ const { data: categoryList } = useCategoryList(isLogged);
const { isOpen, openComponent, closeComponent } = useToggle();
const [time, setTime] = useState({
@@ -60,7 +64,7 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
hour: 0,
minute: 0,
});
- const baseTime = startTime ? new Date(startTime) : new Date();
+ const baseTime = createTime ? new Date(createTime) : new Date();
const { text: writingTitle, handleTextChange: handleTitleChange } = useText(title ?? '');
const { text: writingContent, handleTextChange: handleContentChange } = useText(content ?? '');
@@ -69,6 +73,8 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
CATEGORY_COUNT_LIMIT
);
+ const categoryOptionList = changeCategoryToOption(categoryList ?? []);
+
const handleDeadlineButtonClick = (option: string) => {
setTime(formatTimeWithOption(option));
};
@@ -143,36 +149,6 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
}
};
- const getDeadlineTime = ({
- day,
- hour,
- minute,
- }: {
- day: number;
- hour: number;
- minute: number;
- }) => {
- const timeMessage = [];
-
- if (day === 0 && hour === 0 && minute === 0) {
- return '마감 시간을 선택해주세요';
- }
-
- if (day > 0) {
- timeMessage.push(`${day}일`);
- }
-
- if (hour > 0) {
- timeMessage.push(`${hour}시간`);
- }
-
- if (minute > 0) {
- timeMessage.push(`${minute}분`);
- }
-
- return `${timeMessage.join(' ')} 후에 마감됩니다.`;
- };
-
return (
<>
@@ -188,7 +164,7 @@ export default function PostForm({ data, mutate, isError, error }: PostFormProps
- 글 작성일({startTime})로부터 하루 이후 (
+ 글 작성일({createTime})로부터 하루 이후 (
{addTimeToDate({ day: 1, hour: 0, minute: 0 }, baseTime)})까지만 선택
가능합니다.
diff --git a/frontend/src/components/common/Layout/index.tsx b/frontend/src/components/common/Layout/index.tsx
index 9438d9aa7..6cba03095 100644
--- a/frontend/src/components/common/Layout/index.tsx
+++ b/frontend/src/components/common/Layout/index.tsx
@@ -2,12 +2,11 @@ import { PropsWithChildren, useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import { AuthContext } from '@hooks/context/auth';
+import { useCategoryList } from '@hooks/query/category/useCategoryList';
import Dashboard from '@components/common/Dashboard';
import WideHeader from '@components/common/WideHeader';
-import { MOCK_FAVORITE_CATEGORIES } from '@mocks/mockData/category';
-
import * as S from './style';
interface LayoutProps extends PropsWithChildren {
@@ -19,7 +18,7 @@ export default function Layout({ children, isSidebarVisible }: LayoutProps) {
const { loggedInfo } = useContext(AuthContext);
- const categoryList = MOCK_FAVORITE_CATEGORIES;
+ const { data: categoryList } = useCategoryList(loggedInfo.isLogged);
const selectedCategory = undefined;
const handleLogoutClick = () => {};
@@ -37,7 +36,7 @@ export default function Layout({ children, isSidebarVisible }: LayoutProps) {
diff --git a/frontend/src/components/common/Post/index.tsx b/frontend/src/components/common/Post/index.tsx
index 8ce8366bc..8e58aa984 100644
--- a/frontend/src/components/common/Post/index.tsx
+++ b/frontend/src/components/common/Post/index.tsx
@@ -15,7 +15,7 @@ interface PostProps {
}
export default function Post({ postInfo, isPreview }: PostProps) {
- const { postId, category, title, writer, startTime, endTime, content, voteInfo } = postInfo;
+ const { postId, category, title, writer, createTime, deadline, content, voteInfo } = postInfo;
const handleVoteClick = (newOptionId: number) => {
if (voteInfo.selectedOptionId === newOptionId) return;
@@ -34,13 +34,13 @@ export default function Post({ postInfo, isPreview }: PostProps) {
return (
- {category.map(category => category.name).join(' | ')}
+ {category?.map(category => category.name).join(' | ')}
{title}
{writer.nickname}
- {startTime}
- {endTime}
+ {createTime}
+ {deadline}
{content}
diff --git a/frontend/src/components/common/Post/mockData.ts b/frontend/src/components/common/Post/mockData.ts
index 45081314e..0395adeb1 100644
--- a/frontend/src/components/common/Post/mockData.ts
+++ b/frontend/src/components/common/Post/mockData.ts
@@ -25,8 +25,8 @@ export const MOCK_NOT_VOTE_POST: PostInfo = {
name: '상담',
},
],
- startTime: '2023-07-12 12:40',
- endTime: '2023-07-20 18:40',
+ createTime: '2023-07-12 12:40',
+ deadline: '2023-07-20 18:40',
voteInfo: {
selectedOptionId: 0,
allPeopleCount: 100,
@@ -88,8 +88,8 @@ export const MOCK_VOTE_POST: PostInfo = {
name: '상담',
},
],
- startTime: '2023-07-12 12:40',
- endTime: '2023-07-21 18:40',
+ createTime: '2023-07-12 12:40',
+ deadline: '2023-07-21 18:40',
voteInfo: {
selectedOptionId: 12312,
allPeopleCount: 123,
diff --git a/frontend/src/hooks/context/auth.tsx b/frontend/src/hooks/context/auth.tsx
index f94924615..586d96c95 100644
--- a/frontend/src/hooks/context/auth.tsx
+++ b/frontend/src/hooks/context/auth.tsx
@@ -28,7 +28,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
const accessToken = getCookieToken().accessToken;
- if (accessToken) setLoggedInfo(origin => ({ ...origin, accessToken }));
+ if (accessToken) setLoggedInfo(origin => ({ ...origin, accessToken, isLogged: true }));
}, []);
return (
diff --git a/frontend/src/hooks/query/category/useCategoryFavoriteToggle.ts b/frontend/src/hooks/query/category/useCategoryFavoriteToggle.ts
index 63eca3657..6c45fd49a 100644
--- a/frontend/src/hooks/query/category/useCategoryFavoriteToggle.ts
+++ b/frontend/src/hooks/query/category/useCategoryFavoriteToggle.ts
@@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Category } from '@type/category';
-import { addFavoriteCategory, removeFavoriteCategory } from '@api/wus/categoryList';
+import { addFavoriteCategory, removeFavoriteCategory } from '@api/categoryList';
import { QUERY_KEY } from '@constants/queryKey';
diff --git a/frontend/src/hooks/query/category/useCategoryList.ts b/frontend/src/hooks/query/category/useCategoryList.ts
index 41fb6af62..475f1e835 100644
--- a/frontend/src/hooks/query/category/useCategoryList.ts
+++ b/frontend/src/hooks/query/category/useCategoryList.ts
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import { Category } from '@type/category';
-import { getGuestCategoryList, getUserCategoryList } from '@api/wus/categoryList';
+import { getGuestCategoryList, getUserCategoryList } from '@api/categoryList';
import { QUERY_KEY } from '@constants/queryKey';
diff --git a/frontend/src/hooks/query/usePostList.tsx b/frontend/src/hooks/query/usePostList.tsx
index e5a477381..bb68705db 100644
--- a/frontend/src/hooks/query/usePostList.tsx
+++ b/frontend/src/hooks/query/usePostList.tsx
@@ -24,6 +24,7 @@ export const usePostList = (
return lastPage.pageNumber + 1;
},
+ suspense: true,
}
);
diff --git a/frontend/src/hooks/query/user/useUserInfo.ts b/frontend/src/hooks/query/user/useUserInfo.ts
index 27a2e22de..3a93eac67 100644
--- a/frontend/src/hooks/query/user/useUserInfo.ts
+++ b/frontend/src/hooks/query/user/useUserInfo.ts
@@ -1,13 +1,13 @@
import { useQuery } from '@tanstack/react-query';
-import { UserInfoResponse } from '@type/user';
+import { User } from '@type/user';
-import { getUserInfo } from '@api/wus/userInfo';
+import { getUserInfo } from '@api/userInfo';
import { QUERY_KEY } from '@constants/queryKey';
export const useUserInfo = (isLogged: boolean) => {
- const { data, error, isLoading, isError } = useQuery(
+ const { data, error, isLoading, isError } = useQuery(
[QUERY_KEY.USER_INFO, isLogged],
getUserInfo
);
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
index 0e00ec7b4..e494a44a0 100644
--- a/frontend/src/index.tsx
+++ b/frontend/src/index.tsx
@@ -5,13 +5,13 @@ import ReactDOM from 'react-dom/client';
import App from './App';
import { worker } from './mocks/worker';
-// if (process.env.NODE_ENV === 'development') {
-// worker.start();
-// }
+if (process.env.NODE_ENV === 'development') {
+ worker.start();
+}
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
- //
-
- //
+
+
+
);
diff --git a/frontend/src/mocks/wus/categoryList.ts b/frontend/src/mocks/categoryList.ts
similarity index 100%
rename from frontend/src/mocks/wus/categoryList.ts
rename to frontend/src/mocks/categoryList.ts
diff --git a/frontend/src/mocks/handlers.ts b/frontend/src/mocks/handlers.ts
index a0768687a..ef1df12a0 100644
--- a/frontend/src/mocks/handlers.ts
+++ b/frontend/src/mocks/handlers.ts
@@ -1,11 +1,11 @@
+import { mockCategoryHandlers } from './categoryList';
import { mockComment } from './comment';
import { example } from './example/get';
import { mockVoteResult } from './getVoteDetail';
import { mockPost } from './post';
+import { mockPostList } from './postList';
+import { mockUserInfo } from './userInfo';
import { mockVote } from './vote';
-import { mockCategoryHandlers } from './wus/categoryList';
-import { mockPostList } from './wus/post';
-import { mockUserInfo } from './wus/userInfo';
export const handlers = [
...example,
diff --git a/frontend/src/mocks/mockData/post.ts b/frontend/src/mocks/mockData/post.ts
index e361baeec..839ae3a2f 100644
--- a/frontend/src/mocks/mockData/post.ts
+++ b/frontend/src/mocks/mockData/post.ts
@@ -1,4 +1,6 @@
-export const MOCK_POST_INFO = {
+import { PostInfo } from '@type/post';
+
+export const MOCK_POST_INFO: PostInfo = {
postId: 1,
title:
'어느 곳에서 정보를 찾아야 할지도 막막한 사람들을 위한, 심심풀이로 나의 취향과 남의 취향을 비교해보고 싶은 사람들을 위한 프로젝트',
@@ -6,6 +8,7 @@ export const MOCK_POST_INFO = {
id: 12121221,
nickname: '우아한 잔치국수',
},
+ imageUrl: 'https://source.unsplash.com/random',
content:
'이는 사람들에게 재미와 정보, 두 가지를 줄 수 있습니다. 사람들은 MBTI, 밸런스게임처럼 나와 같은 사람들을 찾고, 나와 다른 사람들과 비교하는 것을 즐깁니다. 이를 컨텐츠화하여 보다 빠르게 질문하고 답변하며, 사람들의 반응을 확인할 수 있다면 사람들은 충분한 즐거움을 느낄 것입니다. 또한 20대가 많은 대학가에 창업을 하고 싶지만 20대의 의견을 모르겠을 때, 확실한 답은 아닐지라도 어느 정도의 가이드를 줄 수 있을 것입니다. 질문자에게 제공되는 성별/나이대별 투표 결과 정보는 질문자가 하고자 하는 의사결정의 근거가 될 수 있을 것입니다.',
category: [
@@ -22,8 +25,8 @@ export const MOCK_POST_INFO = {
name: '상담',
},
],
- startTime: '2023-07-12 12:40',
- endTime: '2023-07-13 18:40',
+ createTime: '2023-07-12 12:40',
+ deadline: '2023-07-13 18:40',
voteInfo: {
selectedOptionId: 2,
allPeopleCount: 123,
@@ -33,18 +36,21 @@ export const MOCK_POST_INFO = {
text: '당선',
peopleCount: 30,
percent: 30,
+ imageUrl: '',
},
{
id: 123,
text: 'votogether',
peopleCount: 40,
percent: 40,
+ imageUrl: 'https://source.unsplash.com/random',
},
{
id: 1234,
text: '인스타그램, 블라인드와 같은 SNS의 형식을 차용합니다. 누군가는 글을 쓰고, 누군가는 반응합니다. 다만, 댓글은 없습니다. 투표로 자신의 의견을 표현하고 이를 사람들에게 보여줍니다.',
peopleCount: 20,
percent: 20,
+ imageUrl: 'https://source.unsplash.com/random',
},
{
id: 2,
diff --git a/frontend/src/mocks/mockData/postList.ts b/frontend/src/mocks/mockData/postList.ts
index ba85cf666..8a1d8d142 100644
--- a/frontend/src/mocks/mockData/postList.ts
+++ b/frontend/src/mocks/mockData/postList.ts
@@ -1,8 +1,10 @@
-import { PostInfo } from '@type/post';
+import { PostInfo, PostInfoResponse } from '@type/post';
-export const MOCK_POST_LIST: PostInfo[] = [];
+import { transformPostResponse } from '@api/post';
-const getMockPost = () => ({
+export const MOCK_POST_LIST: PostInfoResponse[] = [];
+
+const getMockPost = (): PostInfoResponse => ({
postId: Math.floor(Math.random() * 100000),
title:
'어느 곳에서 정보를 찾아야 할지도 막막한 사람들을 위한, 심심풀이로 나의 취향과 남의 취향을 비교해보고 싶은 사람들을 위한 프로젝트',
@@ -13,7 +15,7 @@ const getMockPost = () => ({
content:
'이는 사람들에게 재미와 정보, 두 가지를 줄 수 있습니다. 사람들은 MBTI, 밸런스게임처럼 나와 같은 사람들을 찾고, 나와 다른 사람들과 비교하는 것을 즐깁니다. 이를 컨텐츠화하여 보다 빠르게 질문하고 답변하며, 사람들의 반응을 확인할 수 있다면 사람들은 충분한 즐거움을 느낄 것입니다. 또한 20대가 많은 대학가에 창업을 하고 싶지만 20대의 의견을 모르겠을 때, 확실한 답은 아닐지라도 어느 정도의 가이드를 줄 수 있을 것입니다. 질문자에게 제공되는 성별/나이대별 투표 결과 정보는 질문자가 하고자 하는 의사결정의 근거가 될 수 있을 것입니다.',
imageUrl: '',
- category: [
+ categories: [
{
id: 1,
name: '개발',
@@ -27,39 +29,40 @@ const getMockPost = () => ({
name: '상담',
},
],
- startTime: '2023-07-12 12:40',
- endTime: '2023-07-13 18:40',
+ createdAt: '2023-07-12 12:40',
+ deadline: '2023-07-13 18:40',
voteInfo: {
selectedOptionId: 9,
- allPeopleCount: 123,
+ totalVoteCount: 123,
options: [
{
- id: 6,
- text: '당선',
- peopleCount: 30,
- percent: 30,
+ optionId: 6,
+ content: '당선',
+ voteCount: 30,
+ votePercent: 30,
imageUrl: '',
},
{
- id: 7,
- text: 'votogether',
- peopleCount: 40,
- percent: 40,
+ optionId: 7,
+ content: 'votogether',
+ voteCount: 40,
+ votePercent: 40,
imageUrl: '',
},
{
- id: 8,
- text: '인스타그램, 블라인드와 같은 SNS의 형식을 차용합니다. 누군가는 글을 쓰고, 누군가는 반응합니다. 다만, 댓글은 없습니다. 투표로 자신의 의견을 표현하고 이를 사람들에게 보여줍니다.',
- peopleCount: 20,
+ optionId: 8,
+ content:
+ '인스타그램, 블라인드와 같은 SNS의 형식을 차용합니다. 누군가는 글을 쓰고, 누군가는 반응합니다. 다만, 댓글은 없습니다. 투표로 자신의 의견을 표현하고 이를 사람들에게 보여줍니다.',
+ voteCount: 20,
imageUrl: '',
- percent: 20,
+ votePercent: 20,
},
{
- id: 9,
- text: 'fun from choice, 오늘도 즐거운 한 표 ',
+ optionId: 9,
+ content: 'fun from choice, 오늘도 즐거운 한 표 ',
imageUrl: 'https://source.unsplash.com/random',
- peopleCount: 10,
- percent: 10,
+ voteCount: 10,
+ votePercent: 10,
},
],
},
@@ -68,3 +71,7 @@ const getMockPost = () => ({
for (let index = 0; index < 10; index += 1) {
MOCK_POST_LIST.push(getMockPost());
}
+
+export const MOCK_TRANSFORM_POST_LIST: PostInfo[] = MOCK_POST_LIST.map(POST =>
+ transformPostResponse(POST)
+);
diff --git a/frontend/src/mocks/post.ts b/frontend/src/mocks/post.ts
index 7b271e0ac..0ed9d50ce 100644
--- a/frontend/src/mocks/post.ts
+++ b/frontend/src/mocks/post.ts
@@ -1,6 +1,30 @@
import { rest } from 'msw';
+import { MOCK_POST_INFO } from './mockData/post';
+
export const mockPost = [
+ rest.get('/posts/:postId', (req, res, ctx) => {
+ return res(ctx.delay(1000), ctx.status(200), ctx.json(MOCK_POST_INFO));
+ }),
+
+ rest.delete('/posts/:postId', (req, res, ctx) => {
+ return res(
+ ctx.delay(1000),
+ ctx.status(200),
+ ctx.json({ message: '게시글이 성공적으로 삭제되었습니다' })
+ );
+ }),
+
+ rest.patch('/posts/:postId/close', (req, res, ctx) => {
+ MOCK_POST_INFO.deadline = '2023-07-13 18:40';
+
+ return res(
+ ctx.delay(1000),
+ ctx.status(200),
+ ctx.json({ message: '게시글이 성공적으로 조기 마감 되었습니다' })
+ );
+ }),
+
//게시글 작성
rest.post('/posts', (req, res, ctx) => {
window.console.log('게시글 작성 완료', req.body);
@@ -8,13 +32,13 @@ export const mockPost = [
return res(
ctx.delay(1000),
ctx.status(201),
- ctx.json({ message: '게시글이 성공적으로 생성되었습니다!!' })
+ ctx.json({ message: '게시글이 성공적으로 생성되었습니다' })
);
}),
//게시글 수정
rest.put('/posts/:postId', (req, res, ctx) => {
- window.console.log('게시글 수정 완료', req.body);
+ window.console.log('게시글 수정 완료되었습니다', req.body);
return res(
ctx.delay(1000),
diff --git a/frontend/src/mocks/wus/post.ts b/frontend/src/mocks/postList.ts
similarity index 100%
rename from frontend/src/mocks/wus/post.ts
rename to frontend/src/mocks/postList.ts
diff --git a/frontend/src/mocks/sua/post.ts b/frontend/src/mocks/sua/post.ts
deleted file mode 100644
index 9462f4d84..000000000
--- a/frontend/src/mocks/sua/post.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { rest } from 'msw';
-
-import { PostInfo } from '@type/post';
-
-const examplePost: PostInfo = {
- postId: 1,
- title:
- '어느 곳에서 정보를 찾아야 할지도 막막한 사람들을 위한, 심심풀이로 나의 취향과 남의 취향을 비교해보고 싶은 사람들을 위한 프로젝트',
- writer: {
- id: 12121221,
- nickname: '우아한 잔치국수',
- },
- content:
- '이는 사람들에게 재미와 정보, 두 가지를 줄 수 있습니다. 사람들은 MBTI, 밸런스게임처럼 나와 같은 사람들을 찾고, 나와 다른 사람들과 비교하는 것을 즐깁니다. 이를 컨텐츠화하여 보다 빠르게 질문하고 답변하며, 사람들의 반응을 확인할 수 있다면 사람들은 충분한 즐거움을 느낄 것입니다. 또한 20대가 많은 대학가에 창업을 하고 싶지만 20대의 의견을 모르겠을 때, 확실한 답은 아닐지라도 어느 정도의 가이드를 줄 수 있을 것입니다. 질문자에게 제공되는 성별/나이대별 투표 결과 정보는 질문자가 하고자 하는 의사결정의 근거가 될 수 있을 것입니다.',
- imageUrl: '',
- category: [
- {
- id: 76767,
- name: '개발',
- },
- {
- id: 74632,
- name: '연애',
- },
- {
- id: 71347,
- name: '상담',
- },
- ],
- startTime: '2023-07-12 12:40',
- endTime: '2023-07-21 18:40',
- voteInfo: {
- selectedOptionId: 2,
- allPeopleCount: 123,
- options: [
- {
- id: 12,
- text: '당선',
- peopleCount: 30,
- percent: 30,
- imageUrl: '',
- },
- {
- id: 123,
- text: 'votogether',
- peopleCount: 40,
- percent: 40,
- imageUrl: '',
- },
- {
- id: 1234,
- text: '인스타그램, 블라인드와 같은 SNS의 형식을 차용합니다. 누군가는 글을 쓰고, 누군가는 반응합니다. 다만, 댓글은 없습니다. 투표로 자신의 의견을 표현하고 이를 사람들에게 보여줍니다.',
- peopleCount: 20,
- percent: 20,
- imageUrl: '',
- },
- {
- id: 2,
- text: 'fun from choice, 오늘도 즐거운 한 표 ',
- imageUrl: 'https://source.unsplash.com/random',
- peopleCount: 10,
- percent: 10,
- },
- ],
- },
-};
-
-export const getPostTest = [
- rest.get('/posts/:postId', (req, res, ctx) => {
- return res(ctx.delay(1000), ctx.status(200), ctx.json(examplePost));
- }),
-
- rest.delete('/posts/:postId', (req, res, ctx) => {
- return res(ctx.delay(1000), ctx.status(200), ctx.json({ message: 'ok' }));
- }),
-
- rest.patch('/posts/:postId/close', (req, res, ctx) => {
- examplePost.endTime = '2023-07-13 18:40';
-
- return res(ctx.delay(1000), ctx.status(200), ctx.json({ message: 'ok' }));
- }),
-];
diff --git a/frontend/src/mocks/wus/userInfo.ts b/frontend/src/mocks/userInfo.ts
similarity index 100%
rename from frontend/src/mocks/wus/userInfo.ts
rename to frontend/src/mocks/userInfo.ts
diff --git a/frontend/src/pages/MyInfo/index.tsx b/frontend/src/pages/MyInfo/index.tsx
index ac2a49bf3..ecba39835 100644
--- a/frontend/src/pages/MyInfo/index.tsx
+++ b/frontend/src/pages/MyInfo/index.tsx
@@ -1,7 +1,7 @@
+import { useContext } from 'react';
import { useNavigate } from 'react-router-dom';
-import { User } from '@type/user';
-
+import { AuthContext } from '@hooks/context/auth';
import { useToggle } from '@hooks/useToggle';
import Accordion from '@components/common/Accordion';
@@ -18,13 +18,12 @@ export default function MyInfo() {
const navigate = useNavigate();
const { isOpen, openComponent, closeComponent } = useToggle();
- // const { data: userInfo, error, isLoading, isError } = useUserInfo(); // 유저 정보 조회 관련 pr merge 필요
- const MOCK_USER_INFO: User = {
- nickname: '우아한 코끼리',
- postCount: 4,
- voteCount: 128,
- userPoint: 200,
- };
+ const { userInfo } = useContext(AuthContext).loggedInfo;
+
+ if (!userInfo) {
+ navigate('/');
+ return;
+ }
return (
@@ -40,7 +39,7 @@ export default function MyInfo() {
-
+
diff --git a/frontend/src/pages/post/EditPost/index.tsx b/frontend/src/pages/post/EditPost/index.tsx
index 69033420e..939899af0 100644
--- a/frontend/src/pages/post/EditPost/index.tsx
+++ b/frontend/src/pages/post/EditPost/index.tsx
@@ -25,8 +25,8 @@ export default function EditPost() {
{ id: 13217, name: '게임' },
{ id: 13219, name: '연예' },
],
- startTime: '2023-07-18 12:40',
- endTime: '2023-08-15 12:40',
+ createTime: '2023-07-18 12:40',
+ deadline: '2023-08-15 12:40',
voteInfo: {
selectedOptionId: 1,
allPeopleCount: 0,
diff --git a/frontend/src/pages/post/PostDetail/index.tsx b/frontend/src/pages/post/PostDetail/index.tsx
index 8e604cb11..56cfdf662 100644
--- a/frontend/src/pages/post/PostDetail/index.tsx
+++ b/frontend/src/pages/post/PostDetail/index.tsx
@@ -46,7 +46,7 @@ export default function PostDetailPage() {
}
const isWriter = postData.writer.id === userId;
- const isClosed = checkClosedPost(postData.endTime);
+ const isClosed = checkClosedPost(postData.deadline);
const movePage = {
moveWritePostPage: () => {
diff --git a/frontend/src/types/post.ts b/frontend/src/types/post.ts
index 98e638ba1..5d2dd9e10 100644
--- a/frontend/src/types/post.ts
+++ b/frontend/src/types/post.ts
@@ -8,6 +8,14 @@ export interface WrittenVoteOptionType {
imageUrl: string;
}
+export interface WrittenVoteOptionTypeResponse {
+ optionId: number;
+ content: string;
+ voteCount: number;
+ votePercent: number;
+ imageUrl: string;
+}
+
export interface PostInfo {
postId: number;
title: string;
@@ -15,8 +23,8 @@ export interface PostInfo {
content: string;
imageUrl: string;
category: { id: number; name: string }[];
- startTime: string;
- endTime: string;
+ createTime: string;
+ deadline: string;
voteInfo: {
selectedOptionId: number;
allPeopleCount: number;
@@ -24,6 +32,22 @@ export interface PostInfo {
};
}
+export interface PostInfoResponse {
+ postId: number;
+ title: string;
+ writer: { id: number; nickname: string };
+ content: string;
+ imageUrl: string;
+ categories: { id: number; name: string }[];
+ createdAt: string;
+ deadline: string;
+ voteInfo: {
+ selectedOptionId: number;
+ totalVoteCount: number;
+ options: WrittenVoteOptionTypeResponse[];
+ };
+}
+
export interface PostList {
pageNumber: number;
postList: PostInfo[];
diff --git a/frontend/src/types/user.ts b/frontend/src/types/user.ts
index 2bc5ed5fe..a81a4cd03 100644
--- a/frontend/src/types/user.ts
+++ b/frontend/src/types/user.ts
@@ -18,9 +18,8 @@ export interface ModifyNicknameRequest {
nickname: string;
}
-
export interface LoggedInfo {
accessToken: string;
isLogged: boolean;
- userInfo?: UserInfoResponse;
+ userInfo?: User;
}
diff --git a/frontend/src/utils/post/changeCategoryToOption.ts b/frontend/src/utils/post/changeCategoryToOption.ts
new file mode 100644
index 000000000..54fd1cb00
--- /dev/null
+++ b/frontend/src/utils/post/changeCategoryToOption.ts
@@ -0,0 +1,7 @@
+import { Category } from '@type/category';
+
+import { Option } from '@components/common/MultiSelect/types';
+
+export const changeCategoryToOption = (categoryList: Category[]): Option[] => {
+ return categoryList.map(category => ({ id: category.id, name: category.name }));
+};
diff --git a/frontend/src/utils/post/getDeadlineTime.ts b/frontend/src/utils/post/getDeadlineTime.ts
new file mode 100644
index 000000000..4952300ff
--- /dev/null
+++ b/frontend/src/utils/post/getDeadlineTime.ts
@@ -0,0 +1,33 @@
+export const getDeadlineTime = ({
+ day,
+ hour,
+ minute,
+}: {
+ day: number;
+ hour: number;
+ minute: number;
+}) => {
+ const timeMessage = [];
+
+ if (day < 0 || hour < 0 || minute < 0) {
+ return '마감 시간을 다시 설정해주세요';
+ }
+
+ if (day === 0 && hour === 0 && minute === 0) {
+ return '마감 시간을 선택해주세요';
+ }
+
+ if (day > 0) {
+ timeMessage.push(`${day}일`);
+ }
+
+ if (hour > 0) {
+ timeMessage.push(`${hour}시간`);
+ }
+
+ if (minute > 0) {
+ timeMessage.push(`${minute}분`);
+ }
+
+ return `${timeMessage.join(' ')} 후에 마감됩니다.`;
+};
diff --git a/frontend/src/utils/time.ts b/frontend/src/utils/time.ts
index f15736a55..b33ba3728 100644
--- a/frontend/src/utils/time.ts
+++ b/frontend/src/utils/time.ts
@@ -17,8 +17,8 @@ const convertTimeFromStringToNumber = (date: string) => {
return Number([...datePieces, ...timePieces].join(''));
};
-export const checkClosedPost = (endTime: string) => {
+export const checkClosedPost = (deadline: string) => {
const nowTimeNumber = convertNowTimeToNumber();
- const endTimeNumber = convertTimeFromStringToNumber(endTime);
+ const endTimeNumber = convertTimeFromStringToNumber(deadline);
return nowTimeNumber >= endTimeNumber;
};