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
1 change: 1 addition & 0 deletions src/features/auth/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ export interface UpdateMyProfileResponse {

export interface UserProfile {
message: string;
userId?: string;
email: string;
name: string;
nickname: string;
Expand Down
6 changes: 6 additions & 0 deletions src/features/community/api/boards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
CreateBoardRequest,
CreateBoardResponse,
DeleteBoardResponse,
MyBoardListResponse,
TempSavedBoardResponse,
TempSaveBoardRequest,
TempSaveBoardResponse,
Expand All @@ -18,6 +19,11 @@ export async function getBoardList(params: { page: number; size: number }): Prom
return response.data;
}

export async function getMyBoardList(params: { page: number; size: number }): Promise<MyBoardListResponse> {
const response = await apiClient.get<MyBoardListResponse>('/boards/me', { params });
return response.data;
}

export async function createBoard(payload: CreateBoardRequest): Promise<CreateBoardResponse> {
const response = await apiClient.post<CreateBoardResponse>('/boards', payload);
return response.data;
Expand Down
39 changes: 39 additions & 0 deletions src/features/community/api/comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { apiClient } from '@/shared/api/axios';

import type {
CommentListResponse,
CreateCommentRequest,
CreateCommentResponse,
DeleteCommentResponse,
MyCommentListResponse,
UpdateCommentRequest,
UpdateCommentResponse,
} from '../model/types';

export async function getCommentList(
boardId: number,
params: { page: number; size: number },
): Promise<CommentListResponse> {
const response = await apiClient.get<CommentListResponse>(`/comments/${boardId}`, { params });
return response.data;
}

export async function getMyCommentList(params: { page: number; size: number }): Promise<MyCommentListResponse> {
const response = await apiClient.get<MyCommentListResponse>('/comments/me', { params });
return response.data;
}

export async function createComment(payload: CreateCommentRequest): Promise<CreateCommentResponse> {
const response = await apiClient.post<CreateCommentResponse>('/comments', payload);
return response.data;
}

export async function updateComment(commentId: number, payload: UpdateCommentRequest): Promise<UpdateCommentResponse> {
const response = await apiClient.patch<UpdateCommentResponse>(`/comments/${commentId}`, payload);
return response.data;
}

export async function deleteComment(commentId: number): Promise<DeleteCommentResponse> {
const response = await apiClient.delete<DeleteCommentResponse>(`/comments/${commentId}`);
return response.data;
}
22 changes: 22 additions & 0 deletions src/features/community/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ export {
deleteBoard,
getBoardDetail,
getBoardList,
getMyBoardList,
getTempSavedBoard,
tempSaveBoard,
updateBoard,
} from './api/boards';
export { createComment, deleteComment, getCommentList, getMyCommentList, updateComment } from './api/comments';
export {
BOARD_DETAIL_STATUS_MESSAGES,
BOARD_DRAFT_STATUS_MESSAGES,
BOARD_LIST_STATUS_MESSAGES,
BOARD_MUTATION_STATUS_MESSAGES,
COMMENT_LIST_STATUS_MESSAGES,
COMMENT_MUTATION_STATUS_MESSAGES,
COMMUNITY_DRAFT_SESSION_KEY,
MY_ACTIVITY_STATUS_MESSAGES,
} from './lib/constants';
export {
clearStoredBoardDraftSessionKey,
Expand All @@ -23,10 +28,16 @@ export { INITIAL_BOARD_EDITOR_FORM_STATE, validateBoardEditorForm } from './lib/
export { useBoardDetail } from './model/useBoardDetail';
export { useBoardEditorForm } from './model/useBoardEditorForm';
export { useBoardList } from './model/useBoardList';
export { useCommentList } from './model/useCommentList';
export { useCreateBoard } from './model/useCreateBoard';
export { useCreateComment } from './model/useCreateComment';
export { useDeleteBoard } from './model/useDeleteBoard';
export { useDeleteComment } from './model/useDeleteComment';
export { useMyBoardList } from './model/useMyBoardList';
export { useMyCommentList } from './model/useMyCommentList';
export { useTempSaveBoard } from './model/useTempSaveBoard';
export { useTempSavedBoard } from './model/useTempSavedBoard';
export { useUpdateComment } from './model/useUpdateComment';
export { useUpdateBoard } from './model/useUpdateBoard';
export { CommunityFeedCard } from './ui/CommunityFeedCard';
export { CommunityLayout } from './ui/CommunityLayout';
Expand All @@ -36,16 +47,27 @@ export { BoardDetailContent } from './ui/BoardDetailContent';
export { BoardEditorForm } from './ui/BoardEditorForm';
export { DeleteBoardDialog } from './ui/DeleteBoardDialog';
export type {
BoardComment,
BoardDetailResponse,
BoardListItem,
BoardListResponse,
BoardPayload,
CommentListResponse,
CommentPageInfo,
CreateCommentRequest,
CreateCommentResponse,
CreateBoardRequest,
CreateBoardResponse,
DeleteCommentResponse,
DeleteBoardResponse,
MyBoardListResponse,
MyCommentListItem,
MyCommentListResponse,
TempSavedBoardResponse,
TempSaveBoardRequest,
TempSaveBoardResponse,
UpdateCommentRequest,
UpdateCommentResponse,
UpdateBoardRequest,
UpdateBoardResponse,
} from './model/types';
Expand Down
53 changes: 37 additions & 16 deletions src/features/community/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,51 @@
export const COMMUNITY_DRAFT_SESSION_KEY = 'community-board-draft-session-key';

export const BOARD_LIST_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '잘못된 요청입니다.',
401: '로그인이 필요합니다. 다시 로그인해주세요.',
500: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',
400: '잘못된 요청이에요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const BOARD_MUTATION_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '입력값을 다시 확인해주세요.',
401: '로그인이 필요합니다. 다시 로그인해주세요.',
403: '게시글을 처리할 권한이 없습니다.',
500: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
403: '게시글을 처리할 권한이 없어요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const BOARD_DETAIL_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '잘못된 게시글 요청입니다.',
401: '로그인이 필요합니다. 다시 로그인해주세요.',
403: '게시글을 조회할 권한이 없습니다.',
404: '게시글을 찾을 수 없습니다.',
500: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',
400: '잘못된 게시글 요청이에요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
403: '게시글을 조회할 권한이 없어요.',
404: '게시글을 찾을 수 없어요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const BOARD_DRAFT_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '임시 저장 요청을 처리할 수 없습니다.',
401: '로그인이 필요합니다. 다시 로그인해주세요.',
403: '임시 저장 게시글을 처리할 권한이 없습니다.',
404: '임시 저장된 게시글을 찾을 수 없습니다.',
500: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',
400: '임시 저장 요청을 처리할 수 없어요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
403: '임시 저장 게시글을 처리할 권한이 없어요.',
404: '임시 저장한 게시글을 찾을 수 없어요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const COMMENT_LIST_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '댓글 조회 요청이 올바르지 않아요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
404: '해당 게시글을 찾을 수 없어요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const COMMENT_MUTATION_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '입력한 댓글 내용을 다시 확인해주세요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
403: '댓글을 처리할 권한이 없어요.',
404: '대상 댓글 또는 게시글을 찾을 수 없어요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};

export const MY_ACTIVITY_STATUS_MESSAGES: Partial<Record<number, string>> = {
400: '내 활동 조회 요청이 올바르지 않아요.',
401: '로그인이 필요해요. 다시 로그인해주세요.',
500: '서버 오류가 발생했어요. 잠시 후 다시 시도해주세요.',
};
80 changes: 80 additions & 0 deletions src/features/community/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,83 @@ export interface UpdateBoardResponse {
export interface DeleteBoardResponse {
message: string;
}

export interface MyBoardListResponse {
message: string;
boards: BoardListItem[];
}

export interface CommentAuthor {
userId?: string;
nickname: string;
profileUrl?: string | null;
}

export interface BoardComment {
commentId: number;
parentCommentId: number | null;
commentContent: string;
author?: CommentAuthor;
userId?: string;
nickname?: string;
profileUrl?: string | null;
createdAt?: string;
modifiedAt?: string;
deleted?: boolean;
isDeleted?: boolean;
}

export interface CommentPageInfo {
page: number;
size: number;
totalElements: number;
totalPages: number;
}

export interface CommentListResponse {
message: string;
pageInfo: CommentPageInfo;
data: BoardComment[];
}

export interface CreateCommentRequest {
boardId: number;
commentContent: string;
parentCommentId?: number | null;
}

export interface CreateCommentResponse {
message: string;
commentId: number;
commentContent: string;
userId: string;
nickname: string;
}

export interface UpdateCommentRequest {
commentContent: string;
}

export interface UpdateCommentResponse {
message: string;
}

export interface DeleteCommentResponse {
message: string;
}

export interface MyCommentListItem {
commentId: number;
boardId: number;
boardTitle: string;
parentCommentId: number | null;
commentContent: string;
createdAt?: string;
modifiedAt?: string;
}

export interface MyCommentListResponse {
message: string;
pageInfo: CommentPageInfo;
data: MyCommentListItem[];
}
14 changes: 14 additions & 0 deletions src/features/community/model/useCommentList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useQuery } from '@tanstack/react-query';

import { getCommentList } from '@/features/community/api/comments';
import { queryKeys } from '@/shared/lib/react-query/queryKey';

export function useCommentList(boardId: number | null, params: { page: number; size: number }) {
const isValidId = boardId !== null && !Number.isNaN(boardId);

return useQuery({
queryKey: isValidId ? queryKeys.boards.comments(boardId, params) : ['boards', 'comments', 'idle'],
queryFn: () => getCommentList(boardId as number, params),
enabled: isValidId,
});
}
20 changes: 20 additions & 0 deletions src/features/community/model/useCreateComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { createComment } from '@/features/community/api/comments';
import type { CreateCommentRequest, CreateCommentResponse } from '@/features/community/model/types';

export function useCreateComment() {
const queryClient = useQueryClient();

return useMutation<CreateCommentResponse, unknown, CreateCommentRequest>({
mutationFn: createComment,
onSuccess: (_, variables) => {
void queryClient.invalidateQueries({
queryKey: ['boards', variables.boardId, 'comments'],
});
void queryClient.invalidateQueries({
queryKey: ['boards', variables.boardId, 'detail'],
});
},
});
}
25 changes: 25 additions & 0 deletions src/features/community/model/useDeleteComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { deleteComment } from '@/features/community/api/comments';
import type { DeleteCommentResponse } from '@/features/community/model/types';

interface DeleteCommentVariables {
boardId: number;
commentId: number;
}

export function useDeleteComment() {
const queryClient = useQueryClient();

return useMutation<DeleteCommentResponse, unknown, DeleteCommentVariables>({
mutationFn: ({ commentId }) => deleteComment(commentId),
onSuccess: (_, variables) => {
void queryClient.invalidateQueries({
queryKey: ['boards', variables.boardId, 'comments'],
});
void queryClient.invalidateQueries({
queryKey: ['boards', variables.boardId, 'detail'],
});
},
});
}
12 changes: 12 additions & 0 deletions src/features/community/model/useMyBoardList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import { getMyBoardList } from '../api/boards';
import { queryKeys } from '@/shared/lib/react-query/queryKey';

export function useMyBoardList(params: { page: number; size: number }, options?: { enabled?: boolean }) {
return useQuery({
queryKey: queryKeys.boards.mine(params),
queryFn: () => getMyBoardList(params),
enabled: options?.enabled,
});
}
12 changes: 12 additions & 0 deletions src/features/community/model/useMyCommentList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useQuery } from '@tanstack/react-query';

import { getMyCommentList } from '../api/comments';
import { queryKeys } from '@/shared/lib/react-query/queryKey';

export function useMyCommentList(params: { page: number; size: number }, options?: { enabled?: boolean }) {
return useQuery({
queryKey: queryKeys.comments.mine(params),
queryFn: () => getMyCommentList(params),
enabled: options?.enabled,
});
}
23 changes: 23 additions & 0 deletions src/features/community/model/useUpdateComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';

import { updateComment } from '@/features/community/api/comments';
import type { UpdateCommentRequest, UpdateCommentResponse } from '@/features/community/model/types';

interface UpdateCommentVariables {
boardId: number;
commentId: number;
payload: UpdateCommentRequest;
}

export function useUpdateComment() {
const queryClient = useQueryClient();

return useMutation<UpdateCommentResponse, unknown, UpdateCommentVariables>({
mutationFn: ({ commentId, payload }) => updateComment(commentId, payload),
onSuccess: (_, variables) => {
void queryClient.invalidateQueries({
queryKey: ['boards', variables.boardId, 'comments'],
});
},
});
}
Loading
Loading