Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#486] [책 상세 / 모임 상세] 코멘트 목록 컴포넌트 #487

Merged
merged 13 commits into from
Feb 20, 2024
Merged
10 changes: 6 additions & 4 deletions src/app/group/[groupId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
'use client';

import Link from 'next/link';

import { isAuthed } from '@/utils/helpers';
import { KAKAO_LOGIN_URL } from '@/constants/url';

import SSRSafeSuspense from '@/components/SSRSafeSuspense';
import BookGroupInfo from '@/v1/bookGroup/detail/BookGroupInfo';
import CommentList from '@/v1/bookGroup/detail/CommentList';
import BookGroupCommentList from '@/v1/comment/BookGroupCommentList';
import BookGroupNavigation from '@/v1/bookGroup/BookGroupNavigation';
import JoinBookGroupButton from '@/v1/bookGroup/detail/JoinBookGroupButton';
import BottomActionButton from '@/v1/base/BottomActionButton';
import { isAuthed } from '@/utils/helpers';
import { KAKAO_LOGIN_URL } from '@/constants/url';

const DetailBookGroupPage = ({
params: { groupId },
Expand All @@ -30,7 +32,7 @@ const DetailBookGroupPage = ({
<Divider />
<div className="flex flex-col gap-[1rem]">
<Heading text="게시글" />
<CommentList groupId={groupId} />
<BookGroupCommentList groupId={groupId} />
</div>
</div>
{isAuthed() ? (
Expand Down
2 changes: 2 additions & 0 deletions src/queries/book/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const bookKeys = {
bestSeller: () => [...bookKeys.all, 'bestSeller'],
bookmark: (bookId: APIBook['bookId']) =>
[...bookKeys.detail(bookId), 'bookmark'] as const,
comments: (bookId: APIBook['bookId']) =>
[...bookKeys.detail(bookId), 'comments'] as const,
};

export default bookKeys;
46 changes: 38 additions & 8 deletions src/queries/book/useBookCommentsQuery.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
import { UseQueryOptions, useQuery } from '@tanstack/react-query';
import { UseQueryOptions } from '@tanstack/react-query';

import type {
APIBook,
APIBookCommentPagination,
BookComment,
} from '@/types/book';
import bookAPI from '@/apis/book';
import type { APIBook } from '@/types/book';
import useQueryWithSuspense from '@/hooks/useQueryWithSuspense';
import bookKeys from './key';

const useBookCommentsQuery = (
const useBookCommentsQuery = <TData = APIBookCommentPagination>(
bookId: APIBook['bookId'],
options?: Pick<
UseQueryOptions<Awaited<ReturnType<typeof bookAPI.getComments>>['data']>,
'onSuccess' | 'onError'
options?: UseQueryOptions<
Awaited<ReturnType<typeof bookAPI.getComments>>['data'],
unknown,
TData
>
) =>
useQuery(
['bookComments', bookId],
useQueryWithSuspense(
bookKeys.comments(bookId),
() => bookAPI.getComments(bookId).then(({ data }) => data),
options
);

export default useBookCommentsQuery;

const transformBookCommentsData = ({
bookComments,
}: APIBookCommentPagination) => {
return bookComments.map(
({ contents, createdAt, commentId, userId, userProfileImage, nickname }) =>
({
id: commentId,
writer: {
id: userId,
profileImageSrc: userProfileImage,
name: nickname,
},
createdAt,
content: contents,
} as BookComment)
);
};

export const useBookComments = (bookId: APIBook['bookId']) =>
useBookCommentsQuery(bookId, {
select: transformBookCommentsData,
});
58 changes: 58 additions & 0 deletions src/stories/comment/CommentList.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Meta, StoryObj } from '@storybook/react';
import CommentList from '@/v1/comment/CommentList';

const meta: Meta<typeof CommentList> = {
title: 'comment/CommentList',
component: CommentList,
tags: ['autodocs'],
};

export default meta;

type Story = StoryObj<typeof CommentList>;

const comments = [
{
id: 1,
writer: {
id: 2,
profileImageSrc: 'https://bit.ly/kent-c-dodds',
name: 'Kent C. Dodds',
},
createdAt: '2023.02.05',
content: '추천해요!',
},
{
id: 2,
writer: {
id: 3,
profileImageSrc: 'https://i.pravatar.cc/300',
name: '김계란',
},
createdAt: '2023.02.07',
content: '읽고 또 읽어도 새로워요. 🫠',
},
];

export const Default: Story = {
args: {
comments,
isEditableComment: ({ writer }) => writer.id === 3,
},
};

export const Hidden: Story = {
args: {
comments,
isHidden: true,
hiddenText: '멤버만 볼 수 있어요 🥲',
},
};

export const Empty: Story = {
args: {
comments: [],
emptyText: `아직 코멘트가 없어요.
첫 코멘트의 주인공이 되어보세요!`,
},
};
8 changes: 7 additions & 1 deletion src/types/book.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BookSearchPagination, Pagination } from './common';
import { APIJobGroup } from './job';
import { APIUser } from './user';
import { APIUser, Writer } from './user';

export interface APIBook {
bookId: number;
Expand Down Expand Up @@ -82,6 +82,12 @@ export interface APIBookCommentPagination extends Pagination {
bookComments: APIBookComment[];
}

export type BookComment = {
id: APIBook['bookId'];
writer: Writer;
createdAt: APIBookComment['createdAt'];
content: APIBookComment['contents'];
};
export interface APIBestSeller {
isbn: string;
title: string;
Expand Down
8 changes: 2 additions & 6 deletions src/types/group.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIBook } from './book';
import { APIUser } from './user';
import { APIUser, Writer } from './user';
import { Pagination } from './common';

type APIGroupOwner = {
Expand Down Expand Up @@ -91,11 +91,7 @@ export type BookGroupDetail = {

export type BookGroupComment = {
id: APIGroup['bookGroupId'];
writer: {
id: APIUser['userId'];
profileImageSrc: APIUser['profileImage'];
name: APIUser['nickname'];
};
writer: Writer;
createdAt: APIGroupComment['createdAt'];
content: APIGroupComment['contents'];
};
6 changes: 6 additions & 0 deletions src/types/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ export interface APIMyProfile extends Omit<APIUserProfile, 'nickname'> {
}

export type APIUser = APIUserProfile & { name: string | null };

export type Writer = {
id: APIUser['userId'];
profileImageSrc: APIUser['profileImage'];
name: APIUser['nickname'];
};
74 changes: 0 additions & 74 deletions src/v1/bookGroup/detail/CommentList.tsx

This file was deleted.

22 changes: 22 additions & 0 deletions src/v1/comment/BookCommentList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useMyProfileId } from '@/queries/user/useMyProfileQuery';
import { useBookComments } from '@/queries/book/useBookCommentsQuery';
import { isAuthed } from '@/utils/helpers';

import CommentList from './CommentList';

const BookCommentList = ({ bookId }: { bookId: number }) => {
const { data: comments } = useBookComments(bookId);
const { data: myId } = useMyProfileId({ enabled: isAuthed() });

return (
<CommentList
name={'코멘트'}
comments={comments}
isEditableComment={({ writer }) => writer.id === myId}
emptyText={`아직 코멘트가 없어요.
가장 먼저 코멘트를 남겨보세요!`}
/>
);
};

export default BookCommentList;
29 changes: 29 additions & 0 deletions src/v1/comment/BookGroupCommentList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useBookGroupComments } from '@/queries/group/useBookGroupCommentsQuery';
import { useMyProfileId } from '@/queries/user/useMyProfileQuery';
import { useBookGroup } from '@/queries/group/useBookGroupQuery';
import { isAuthed } from '@/utils/helpers';

import CommentList from './CommentList';

const BookGroupCommentList = ({ groupId }: { groupId: number }) => {
const { data: bookGroupInfo } = useBookGroup(groupId);
const { data: comments } = useBookGroupComments(groupId);
const { data: myId } = useMyProfileId({ enabled: isAuthed() });
const { isPublic, isMember } = bookGroupInfo;

const isHidden = !isPublic && !isMember;

return (
<CommentList
name={'게시글'}
comments={comments}
isEditableComment={({ writer }) => writer.id === myId}
isHidden={isHidden}
hiddenText={`멤버만 볼 수 있어요 🥲`}
emptyText={`아직 게시글이 없어요.
가장 먼저 게시글을 남겨보세요!`}
/>
);
};

export default BookGroupCommentList;
Loading
Loading