Skip to content

Commit e8de94d

Browse files
committed
Feat: 댓글 리스트 불러오기 #65
1 parent 6f526dd commit e8de94d

File tree

11 files changed

+120
-27
lines changed

11 files changed

+120
-27
lines changed

components/pages/main/Feed/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export default function Feed() {
2525
showModal={showModal}
2626
setShowModal={setShowModal}
2727
board={selectedBoard}
28-
comments={selectedBoard?.replyListDto}
2928
/>
3029
</FlexBox>
3130
);

components/ui/BoardCard/BoardCardPackage/CommentWrapper.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export function BoardCardCommentWrapper({
2626
parentId: 1,
2727
content: commentText,
2828
});
29+
setCommentText('');
2930
};
3031

3132
return (
@@ -50,6 +51,7 @@ export function BoardCardCommentWrapper({
5051
<FlexBox
5152
direction="column"
5253
justify="start"
54+
align="start"
5355
className="gap-[5px] overflow-scroll h-full"
5456
>
5557
{children}
@@ -80,8 +82,12 @@ export function BoardCardCommentWrapper({
8082
value={commentText}
8183
onChange={(event) => setCommentText(event.target.value)}
8284
/>
83-
<Button onClickAction={postNewComment} disabled={isLoading}>
84-
{isLoading ? <p>등록 중...</p> : <span>등록</span>}
85+
<Button
86+
onClickAction={postNewComment}
87+
disabled={isLoading}
88+
variant="ghost"
89+
>
90+
{isLoading ? <p>...</p> : <span></span>}
8591
</Button>
8692
</FlexBox>
8793
</FlexBox>

components/ui/BoardCard/BoardCardPackage/Comments.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default function BoardCardComments({
99
}) {
1010
return (
1111
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
12-
<div onClick={onClickModal}>
12+
<div onClick={onClickModal} className="flex flex-row">
1313
<div className="inline-block mr-1 body2 text-grey-500">{userName}</div>
1414
<div className="inline body4 text-grey-500">{content}</div>
1515
</div>

components/ui/BoardCard/FeedBoardCard.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ interface FeedBoardCardProps {
99
content: string;
1010
imgs: string[];
1111
setShowModal: Dispatch<SetStateAction<boolean>>;
12-
comments: Comment[] | undefined;
12+
comments: Comment[];
1313
commentsCount: number;
1414
likedCount: number;
1515
createdDate: string;
@@ -26,6 +26,7 @@ export default function FeedBoardCard({
2626
likedCount,
2727
createdDate,
2828
}: FeedBoardCardProps) {
29+
// const { data: commentList } = useGetShortCommentList(boardId);
2930
return (
3031
<FlexBox
3132
direction="column"
@@ -46,8 +47,8 @@ export default function FeedBoardCard({
4647
>
4748
<FlexBox
4849
direction="column"
49-
justify="start"
50-
className="max-h-[82px] overflow-scroll"
50+
align="start"
51+
className="max-h-[82px] overflow-hidden"
5152
>
5253
{comments?.map((comment) => (
5354
<BoardCard.Comments

components/ui/BoardCard/ModalBoardCard.tsx

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { Comment } from '@/types/types';
21
import { BoardCardModal } from '@/components/ui/BoardCard/BoardCardPackage/BoardCardModalPackage';
2+
import useGetCommentList from '@/hooks/queries/useGetCommentList';
33

44
interface ModalBoardCardProps {
55
boardId: number;
66
userName: string;
77
imgs: string[];
88
content: string;
9-
comments: Comment[] | undefined;
109
commentsCount: number;
1110
likedCount: number;
1211
createdDate: string;
@@ -16,11 +15,12 @@ export default function ModalBoardCard({
1615
userName,
1716
imgs,
1817
content,
19-
comments,
2018
commentsCount,
2119
likedCount,
2220
createdDate,
2321
}: ModalBoardCardProps) {
22+
const { data: commentList, Observer } = useGetCommentList(boardId);
23+
2424
return (
2525
<BoardCardModal imgs={imgs}>
2626
<BoardCardModal.Header userName={userName} createdDate={createdDate} />
@@ -31,15 +31,18 @@ export default function ModalBoardCard({
3131
commentsCount={commentsCount}
3232
likedCount={likedCount}
3333
>
34-
{comments?.map((comment) => (
35-
<BoardCardModal.ModalComments
36-
id={comment.id}
37-
userName={comment.nickname}
38-
content={comment.content}
39-
// TODO: 유저 프로필 사진 연결!
40-
userImg="/Feed/desktop/tempProfilePic.svg"
41-
/>
42-
))}
34+
{commentList?.pages.map((page) =>
35+
page.content.map((comment) => (
36+
<BoardCardModal.ModalComments
37+
id={comment.id}
38+
userName={comment.nickname}
39+
content={comment.content}
40+
// TODO: 유저 프로필 사진 연결!
41+
userImg="/Feed/desktop/tempProfilePic.svg"
42+
/>
43+
)),
44+
)}
45+
<Observer>로딩중...</Observer>
4346
</BoardCardModal.BoardCardCommentWrapper>
4447
</BoardCardModal.Content>
4548
</BoardCardModal>

components/ui/BoardModal/index.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable react/no-array-index-key */
22
import { Dispatch, SetStateAction } from 'react';
33
import Image from 'next/image';
4-
import { Comment, Board } from '@/types/types';
4+
import { Board } from '@/types/types';
55
import ModalBoardCard from '@/components/ui/BoardCard/ModalBoardCard';
66
import FlexBox from '../FlexBox';
77
import Modal from '../Modal';
@@ -10,12 +10,10 @@ export default function BoardModal({
1010
showModal,
1111
setShowModal,
1212
board,
13-
comments,
1413
}: {
1514
showModal: boolean;
1615
setShowModal: Dispatch<SetStateAction<boolean>>;
1716
board: Board | null;
18-
comments: Comment[] | undefined;
1917
}) {
2018
return (
2119
<Modal open={showModal} onClose={() => setShowModal(false)}>
@@ -36,7 +34,6 @@ export default function BoardModal({
3634
userName={board.writer}
3735
imgs={board.fileNames}
3836
content={board.title}
39-
comments={comments}
4037
commentsCount={board.replyCount}
4138
likedCount={board.likedCount}
4239
createdDate={board.createdDate}

hooks/mutations/usePostComment.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default function usePostComment() {
1010
postComment(postCommentData),
1111
onSuccess: () => {
1212
Toast.success('댓글이 성공적으로 업로드 되었습니다.');
13-
return queryClient.invalidateQueries(['comment']);
13+
return queryClient.invalidateQueries(['commentList']);
1414
},
1515
onError: () => {
1616
Toast.error('댓글을 업로드하지 못했습니다. 잠시후 다시 시도해주세요.🥲');

hooks/queries/useGetBoardList.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import useInfiniteScroll from '../common/useInfiniteScroll';
77
export default function useGetBoardList() {
88
const { data, isLoading, Observer, hasNextPage } =
99
useInfiniteScroll<BoardList>({
10-
queryKey: 'boardsList',
10+
queryKey: 'boardList',
1111
firstPageParam: 0,
1212
queryFn: getBoardList,
1313
getNextPageParamFn: (boardList) =>

hooks/queries/useGetCommentList.tsx

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useInfiniteQuery } from '@tanstack/react-query';
2+
import { CommentList } from '@/types/types';
3+
import { getCommentList } from '@/service/board';
4+
import { useEffect } from 'react';
5+
import { useInView } from 'react-intersection-observer';
6+
7+
export default function useGetCommentList(boardId: number) {
8+
const { data, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage } =
9+
useInfiniteQuery<CommentList>({
10+
queryKey: ['commentList'],
11+
queryFn: ({ pageParam = 0 }) => getCommentList(pageParam, boardId),
12+
getNextPageParam: (commentList) =>
13+
commentList.last ? undefined : commentList.number + 1,
14+
});
15+
// 무한 스크롤 화면 가장 아래 부분 탐지하는 observer
16+
function Observer({ children }: { children: React.ReactNode }) {
17+
const { ref, inView } = useInView({ threshold: 1 });
18+
useEffect(() => {
19+
if (inView && hasNextPage) {
20+
fetchNextPage();
21+
}
22+
}, [inView]);
23+
if (!hasNextPage || !data) return null;
24+
return (
25+
<div ref={ref}>{isLoading || isFetchingNextPage ? children : null}</div>
26+
);
27+
}
28+
29+
return {
30+
data,
31+
isLoading,
32+
Observer,
33+
hasNextPage,
34+
};
35+
}

service/board.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AuthError } from '@/lib/error';
2-
import { PostBoardType, PostCommentType } from '@/types/types';
2+
import { CommentList, PostBoardType, PostCommentType } from '@/types/types';
33

44
export async function postBoard(postBoardData: PostBoardType) {
55
const url = `endpoint/api/board/register`;
@@ -40,7 +40,6 @@ export async function getBoardList(pageParam: number) {
4040

4141
export async function postComment(postCommentData: PostCommentType) {
4242
const url = `endpoint/api/reply/register`;
43-
4443
const response = await fetch(url, {
4544
method: 'POST',
4645
credentials: 'include',
@@ -51,3 +50,29 @@ export async function postComment(postCommentData: PostCommentType) {
5150
});
5251
return response.json();
5352
}
53+
54+
export async function getCommentList(
55+
pageParam: number,
56+
boardId: number,
57+
): Promise<CommentList> {
58+
let url = `/endpoint/api/reply/list?boardId=${boardId}&pageSize=3`;
59+
if (pageParam) {
60+
url += `&pageNumber=${pageParam}`;
61+
}
62+
try {
63+
const response = await fetch(url);
64+
if (response.status === 401) {
65+
throw new AuthError('로그인이 필요한 서비스입니다.');
66+
}
67+
if (!response.ok) {
68+
throw new Error(`서버오류:${response.status}`);
69+
}
70+
return await response.json();
71+
} catch (error) {
72+
if (error instanceof AuthError) {
73+
window.location.replace('/auth/login');
74+
alert(error.message);
75+
}
76+
throw error;
77+
}
78+
}

types/types.ts

+27
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@ export interface Comment {
6161
// children: string[];
6262
}
6363

64+
export interface CommentList {
65+
content: Comment[];
66+
pageable: {
67+
sort: {
68+
empty: boolean;
69+
unsorted: boolean;
70+
sorted: boolean;
71+
};
72+
offset: 0;
73+
pageSize: 3;
74+
pageNumber: 0;
75+
paged: boolean;
76+
unpaged: boolean;
77+
};
78+
size: 3;
79+
number: 0;
80+
sort: {
81+
empty: boolean;
82+
unsorted: boolean;
83+
sorted: boolean;
84+
};
85+
numberOfElements: number;
86+
first: boolean;
87+
last: boolean;
88+
empty: boolean;
89+
}
90+
6491
export interface PostBoardType {
6592
title: string;
6693
content: string;

0 commit comments

Comments
 (0)