diff --git a/apps/member/src/components/common/ErrorSection/ErrorSection.tsx b/apps/member/src/components/common/ErrorSection/ErrorSection.tsx index b182cef5..08a9e0c4 100644 --- a/apps/member/src/components/common/ErrorSection/ErrorSection.tsx +++ b/apps/member/src/components/common/ErrorSection/ErrorSection.tsx @@ -1,25 +1,35 @@ +import { useNavigate } from 'react-router-dom'; + import { Button } from '@clab-platforms/design-system'; import { HighPriorityColor } from '@clab-platforms/icon'; +import Content from '../Content/Content'; +import { Section } from '../Section'; + interface Props { reset: () => void; } const ErrorSection = ({ reset }: Props) => { + const navigate = useNavigate(); + return ( -
- -
-

- 불편을 드려 죄송합니다. 오류가 발생했어요. 😭 -

-
-
-

만약 같은 문제가 지속적으로 발생할 경우 문의 해주시기 바랍니다.

-

감사합니다.

-
- -
+ +
+ +
+

해당 페이지에 접근할 수 없습니다.

+
+
+

만약 같은 문제가 지속적으로 발생할 경우 문의 해주시기 바랍니다.

+

감사합니다.

+
+
+ + +
+
+
); }; diff --git a/apps/member/src/components/library/BookLoanConditionStatusBadge/BookLoanConditionStatusBadge.tsx b/apps/member/src/components/library/BookLoanConditionStatusBadge.tsx similarity index 100% rename from apps/member/src/components/library/BookLoanConditionStatusBadge/BookLoanConditionStatusBadge.tsx rename to apps/member/src/components/library/BookLoanConditionStatusBadge.tsx diff --git a/apps/member/src/components/library/LibraryBooksSection/LibraryBooksSection.tsx b/apps/member/src/components/library/LibraryBooksSection/LibraryBooksSection.tsx deleted file mode 100644 index 4735c37d..00000000 --- a/apps/member/src/components/library/LibraryBooksSection/LibraryBooksSection.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import Pagination from '@components/common/Pagination/Pagination'; -import { Section } from '@components/common/Section'; - -import { usePagination } from '@hooks/common/usePagination'; -import { useBooks } from '@hooks/queries/book'; - -import BookCard from '../BookCard/BookCard'; - -const LibraryBooksSection = () => { - const { page, size, handlePageChange } = usePagination({ defaultSize: 16 }); - - const { data } = useBooks(page, size); - - return ( -
- - -
- {data.items.map(({ id, ...rest }) => ( - - ))} -
- -
-
- ); -}; -export default LibraryBooksSection; diff --git a/apps/member/src/components/manage/ManageLibrarySection/ManageLibrarySection.tsx b/apps/member/src/components/manage/ManageLibrarySection/ManageLibrarySection.tsx index 2199c867..374ac469 100644 --- a/apps/member/src/components/manage/ManageLibrarySection/ManageLibrarySection.tsx +++ b/apps/member/src/components/manage/ManageLibrarySection/ManageLibrarySection.tsx @@ -5,7 +5,7 @@ import { Menubar, Table } from '@clab-platforms/design-system'; import ActionButton from '@components/common/ActionButton/ActionButton'; import Pagination from '@components/common/Pagination/Pagination'; import { Section } from '@components/common/Section'; -import BookLoanConditionStatusBadge from '@components/library/BookLoanConditionStatusBadge/BookLoanConditionStatusBadge'; +import BookLoanConditionStatusBadge from '@components/library/BookLoanConditionStatusBadge'; import { MemberInfoModal } from '@components/modal'; import { TABLE_HEAD } from '@constants/head'; diff --git a/apps/member/src/hooks/queries/book-loan/index.ts b/apps/member/src/hooks/queries/book-loan/index.ts index d187aec1..8e1153a7 100644 --- a/apps/member/src/hooks/queries/book-loan/index.ts +++ b/apps/member/src/hooks/queries/book-loan/index.ts @@ -1,4 +1,3 @@ -export * from './useBookLoanBorrowMutation'; export * from './useBookLoanExtendMutation'; export * from './useBookLoanRecordApproveMutation'; export * from './useBookLoanRecordConditions'; diff --git a/apps/member/src/hooks/queries/book/index.ts b/apps/member/src/hooks/queries/book/index.ts deleted file mode 100644 index 9ec63b0f..00000000 --- a/apps/member/src/hooks/queries/book/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useBooks'; -export * from './useBookDetails'; diff --git a/apps/member/src/hooks/queries/index.ts b/apps/member/src/hooks/queries/index.ts index 9c680560..1eebb001 100644 --- a/apps/member/src/hooks/queries/index.ts +++ b/apps/member/src/hooks/queries/index.ts @@ -1,7 +1,6 @@ export * from './activity'; export * from './blog'; export * from './board'; -export * from './book'; export * from './book-loan'; export * from './comment'; export * from './my'; diff --git a/apps/member/src/pages/LibraryDetailPage/LibraryDetailPage.tsx b/apps/member/src/pages/LibraryDetailPage/LibraryDetailPage.tsx deleted file mode 100644 index 66f56ade..00000000 --- a/apps/member/src/pages/LibraryDetailPage/LibraryDetailPage.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { useParams } from 'react-router-dom'; - -import Content from '@components/common/Content/Content'; -import Header from '@components/common/Header/Header'; -import BookDetailSection from '@components/library/BookDetailSection/BookDetailSection'; -import BookLoanHistorySection from '@components/library/BookLoanHistorySection/BookLoanHistorySection'; - -import { LIBRARY_MESSAGE } from '@constants/message'; -import { PATH, PATH_NAME } from '@constants/path'; -import { useBookDetails } from '@hooks/queries/book'; - -const LibraryDetailPage = () => { - const { id } = useParams<{ id: string }>(); - - if (!id) throw new Error(LIBRARY_MESSAGE.NO_BOOK); - - const { data } = useBookDetails(+id); - - if (!data?.id) throw new Error(LIBRARY_MESSAGE.NO_BOOK); - - return ( - -
- - - - ); -}; - -export default LibraryDetailPage; diff --git a/apps/member/src/components/library/BookDetailSection/BookDetailSection.tsx b/apps/member/src/pages/LibraryDetailPage/components/BookDetailSection.tsx similarity index 87% rename from apps/member/src/components/library/BookDetailSection/BookDetailSection.tsx rename to apps/member/src/pages/LibraryDetailPage/components/BookDetailSection.tsx index cd4ce1ea..36e1c544 100644 --- a/apps/member/src/components/library/BookDetailSection/BookDetailSection.tsx +++ b/apps/member/src/pages/LibraryDetailPage/components/BookDetailSection.tsx @@ -12,7 +12,8 @@ import Section from '@components/common/Section/Section'; import { BOOK_STORE_URL } from '@constants/path'; import { SELECT_DEFAULT_OPTION } from '@constants/select'; import { BOOK_STATE } from '@constants/state'; -import { useBookLoanBorrowMutation, useMyProfile } from '@hooks/queries'; +import { useMyProfile } from '@hooks/queries'; +import { useBookDetails } from '@pages/LibraryPage/hooks/useBookDetails'; import { createImageUrl } from '@utils/api'; import { bookReviewParser, toBookstore } from '@utils/string'; @@ -20,13 +21,11 @@ import yes24Icon from '@assets/svg/yes24.svg'; import aladinIcon from '@assets/webp/aladin.webp'; import kyoboIcon from '@assets/webp/kyobobook.webp'; -import type { BookItem, BookstoreKorean } from '@type/book'; +import type { BookstoreKorean } from '@type/book'; -interface BookDetailSectionProps { - data: BookItem; -} +import { useBookLoanBorrowMutation } from '../hooks/useBookLoanBorrowMutation'; -const options = [ +const OPTIONS = [ { icon: 교보문고, value: '교보문고', @@ -41,9 +40,15 @@ const options = [ }, ] as const; -const BookDetailSection = ({ data }: BookDetailSectionProps) => { +interface Props { + paramsId: string; +} + +export function DetailsSection({ paramsId }: Props) { + const { data: bookDetails } = useBookDetails(+paramsId); const { data: myInfo } = useMyProfile(); const { bookBorrowMutate } = useBookLoanBorrowMutation(); + const { id, borrowerId, @@ -53,7 +58,7 @@ const BookDetailSection = ({ data }: BookDetailSectionProps) => { publisher, imageUrl, reviewLinks, - } = data; + } = bookDetails; const handleBorrowClick = (bookId: number) => { bookBorrowMutate({ @@ -100,7 +105,7 @@ const BookDetailSection = ({ data }: BookDetailSectionProps) => { @@ -110,6 +115,4 @@ const BookDetailSection = ({ data }: BookDetailSectionProps) => { ); -}; - -export default BookDetailSection; +} diff --git a/apps/member/src/components/library/BookLoanHistorySection/BookLoanHistorySection.tsx b/apps/member/src/pages/LibraryDetailPage/components/BookLoanHistorySection.tsx similarity index 77% rename from apps/member/src/components/library/BookLoanHistorySection/BookLoanHistorySection.tsx rename to apps/member/src/pages/LibraryDetailPage/components/BookLoanHistorySection.tsx index e61db752..c5e57323 100644 --- a/apps/member/src/components/library/BookLoanHistorySection/BookLoanHistorySection.tsx +++ b/apps/member/src/pages/LibraryDetailPage/components/BookLoanHistorySection.tsx @@ -1,20 +1,21 @@ import { Table } from '@clab-platforms/design-system'; import Section from '@components/common/Section/Section'; +import BookLoanConditionStatusBadge from '@components/library/BookLoanConditionStatusBadge'; import { TABLE_HEAD } from '@constants/head'; import { useBookLoanRecordConditions } from '@hooks/queries'; +import { useBookDetails } from '@pages/LibraryPage/hooks/useBookDetails'; import { formattedDate } from '@utils/date'; import { formatMemberName } from '@utils/string'; -import BookLoanConditionStatusBadge from '../BookLoanConditionStatusBadge/BookLoanConditionStatusBadge'; - -interface BookLoanHistorySectionProps { - id: number; +interface Props { + paramsId: string; } -const BookLoanHistorySection = ({ id }: BookLoanHistorySectionProps) => { - const { data } = useBookLoanRecordConditions({ bookId: id }); +export function LoanHistorySection({ paramsId }: Props) { + const { data: bookDetails } = useBookDetails(+paramsId); + const { data } = useBookLoanRecordConditions({ bookId: bookDetails.id }); return (
@@ -46,6 +47,4 @@ const BookLoanHistorySection = ({ id }: BookLoanHistorySectionProps) => {
); -}; - -export default BookLoanHistorySection; +} diff --git a/apps/member/src/hooks/queries/book-loan/useBookLoanBorrowMutation.ts b/apps/member/src/pages/LibraryDetailPage/hooks/useBookLoanBorrowMutation.ts similarity index 100% rename from apps/member/src/hooks/queries/book-loan/useBookLoanBorrowMutation.ts rename to apps/member/src/pages/LibraryDetailPage/hooks/useBookLoanBorrowMutation.ts diff --git a/apps/member/src/pages/LibraryDetailPage/index.tsx b/apps/member/src/pages/LibraryDetailPage/index.tsx new file mode 100644 index 00000000..ced7441f --- /dev/null +++ b/apps/member/src/pages/LibraryDetailPage/index.tsx @@ -0,0 +1,45 @@ +import { Suspense } from 'react'; +import { useParams } from 'react-router-dom'; + +import { QueryErrorResetBoundary } from '@tanstack/react-query'; + +import Content from '@components/common/Content/Content'; +import ErrorSection from '@components/common/ErrorSection/ErrorSection'; +import Header from '@components/common/Header/Header'; + +import { LIBRARY_MESSAGE } from '@constants/message'; +import { PATH, PATH_NAME } from '@constants/path'; +import { ErrorBoundary } from '@suspensive/react'; + +import { DetailsSection } from './components/BookDetailSection'; +import { LoanHistorySection } from './components/BookLoanHistorySection'; + +export default function LibraryDetailPage() { + const { id } = useParams<{ id: string }>(); + + if (!id) { + throw new Error(LIBRARY_MESSAGE.NO_BOOK); + } + + return ( + + {({ reset }) => ( + } + > + +
+ + + + + + + + + + )} + + ); +} diff --git a/apps/member/src/pages/LibraryPage/LibraryPage.tsx b/apps/member/src/pages/LibraryPage/LibraryPage.tsx deleted file mode 100644 index 321c2ea9..00000000 --- a/apps/member/src/pages/LibraryPage/LibraryPage.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { Suspense } from 'react'; -import { useNavigate } from 'react-router-dom'; - -import { Button } from '@clab-platforms/design-system'; - -import Content from '@components/common/Content/Content'; -import Header from '@components/common/Header/Header'; -import LibraryBooksSection from '@components/library/LibraryBooksSection/LibraryBooksSection'; -import LibraryNewBooksSection from '@components/library/LibraryNewBooksSection/LibraryNewBooksSection'; - -import { PATH } from '@constants/path'; - -const LibraryPage = () => { - const navigate = useNavigate(); - - return ( - -
- -
- - - - - - -
- ); -}; - -export default LibraryPage; diff --git a/apps/member/src/components/library/BookCard/BookCard.tsx b/apps/member/src/pages/LibraryPage/components/BookExplorerSection.tsx similarity index 58% rename from apps/member/src/components/library/BookCard/BookCard.tsx rename to apps/member/src/pages/LibraryPage/components/BookExplorerSection.tsx index ccc875f3..e94a3b9a 100644 --- a/apps/member/src/components/library/BookCard/BookCard.tsx +++ b/apps/member/src/pages/LibraryPage/components/BookExplorerSection.tsx @@ -1,14 +1,48 @@ -import { useNavigate } from 'react-router-dom'; +import { Link } from 'react-router-dom'; import { cn } from '@clab-platforms/utils'; import Image from '@components/common/Image/Image'; +import Pagination from '@components/common/Pagination/Pagination'; +import { Section } from '@components/common/Section'; import { PATH_FINDER } from '@constants/path'; import { BOOK_STATE } from '@constants/state'; +import { usePagination } from '@hooks/common/usePagination'; import type { BookItem } from '@type/book'; +import { useBooks } from '../hooks/useBooks'; + +export default function BookExplorerSection() { + const { page, size, handlePageChange } = usePagination({ defaultSize: 16 }); + + const { data } = useBooks({ page, size }); + + return ( +
+ + +
+ {data.items.map(({ id, ...props }) => ( + + ))} +
+ +
+
+ ); +} + interface BookCardProps extends BookItem {} const BookCard = ({ @@ -19,12 +53,10 @@ const BookCard = ({ publisher, borrowerId, }: BookCardProps) => { - const navigate = useNavigate(); - return ( -
navigate(PATH_FINDER.LIBRARY_DETAIL(id))} >
- + ); }; - -export default BookCard; diff --git a/apps/member/src/components/library/LibraryNewBooksSection/LibraryNewBooksSection.tsx b/apps/member/src/pages/LibraryPage/components/NewBooksSection.tsx similarity index 90% rename from apps/member/src/components/library/LibraryNewBooksSection/LibraryNewBooksSection.tsx rename to apps/member/src/pages/LibraryPage/components/NewBooksSection.tsx index db5d60b4..74792054 100644 --- a/apps/member/src/components/library/LibraryNewBooksSection/LibraryNewBooksSection.tsx +++ b/apps/member/src/pages/LibraryPage/components/NewBooksSection.tsx @@ -4,10 +4,14 @@ import Image from '@components/common/Image/Image'; import Section from '@components/common/Section/Section'; import { PATH_FINDER } from '@constants/path'; -import { useBooks } from '@hooks/queries/book'; -const LibraryNewBooksSection = () => { - const { data } = useBooks(0, 4); +import { useBooks } from '../hooks/useBooks'; + +export default function NewBooksSection() { + const { data } = useBooks({ + page: 0, + size: 4, + }); return (
@@ -40,6 +44,4 @@ const LibraryNewBooksSection = () => {
); -}; - -export default LibraryNewBooksSection; +} diff --git a/apps/member/src/hooks/queries/book/useBookDetails.ts b/apps/member/src/pages/LibraryPage/hooks/useBookDetails.ts similarity index 100% rename from apps/member/src/hooks/queries/book/useBookDetails.ts rename to apps/member/src/pages/LibraryPage/hooks/useBookDetails.ts diff --git a/apps/member/src/hooks/queries/book/useBooks.ts b/apps/member/src/pages/LibraryPage/hooks/useBooks.ts similarity index 62% rename from apps/member/src/hooks/queries/book/useBooks.ts rename to apps/member/src/pages/LibraryPage/hooks/useBooks.ts index 5a8485ae..99dba283 100644 --- a/apps/member/src/hooks/queries/book/useBooks.ts +++ b/apps/member/src/pages/LibraryPage/hooks/useBooks.ts @@ -3,10 +3,14 @@ import { useSuspenseQuery } from '@tanstack/react-query'; import { getBooks } from '@api/book'; import { BOOK_QUERY_KEY } from '@constants/key'; +import { WithPaginationParams } from '@type/api'; + +export interface UseBooksOptions extends WithPaginationParams {} + /** * 도서 목록을 조회합니다. */ -export const useBooks = (page = 0, size = 6) => { +export const useBooks = ({ page = 0, size = 20 }: UseBooksOptions) => { return useSuspenseQuery({ queryFn: () => getBooks(page, size), queryKey: BOOK_QUERY_KEY.PAGE({ page, size }), diff --git a/apps/member/src/pages/LibraryPage/index.tsx b/apps/member/src/pages/LibraryPage/index.tsx new file mode 100644 index 00000000..a3b84701 --- /dev/null +++ b/apps/member/src/pages/LibraryPage/index.tsx @@ -0,0 +1,47 @@ +import { Suspense } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { QueryErrorResetBoundary } from '@tanstack/react-query'; + +import { Button } from '@clab-platforms/design-system'; + +import Content from '@components/common/Content/Content'; +import ErrorSection from '@components/common/ErrorSection/ErrorSection'; +import Header from '@components/common/Header/Header'; + +import { PATH } from '@constants/path'; +import { ErrorBoundary } from '@suspensive/react'; + +import BookExplorerSection from './components/BookExplorerSection'; +import NewBooksSection from './components/NewBooksSection'; + +export default function LibraryPage() { + const navigate = useNavigate(); + + return ( + + {({ reset }) => ( + } + > + +
+ +
+ + + + + + + + +
+
+ )} +
+ ); +} diff --git a/apps/member/src/pages/MyPage/components/HistorySection.tsx b/apps/member/src/pages/MyPage/components/HistorySection.tsx index 0c5d380c..8563ce18 100644 --- a/apps/member/src/pages/MyPage/components/HistorySection.tsx +++ b/apps/member/src/pages/MyPage/components/HistorySection.tsx @@ -3,7 +3,7 @@ import { useMemo } from 'react'; import EmptyBox from '@components/common/EmptyBox/EmptyBox'; import ListButton from '@components/common/ListButton/ListButton'; import Section from '@components/common/Section/Section'; -import BookLoanConditionStatusBadge from '@components/library/BookLoanConditionStatusBadge/BookLoanConditionStatusBadge'; +import BookLoanConditionStatusBadge from '@components/library/BookLoanConditionStatusBadge'; import { MY_MESSAGE } from '@constants/message'; import { MODAL_TITLE } from '@constants/modal'; diff --git a/apps/member/src/pages/Routes.tsx b/apps/member/src/pages/Routes.tsx index 446aec45..23025692 100644 --- a/apps/member/src/pages/Routes.tsx +++ b/apps/member/src/pages/Routes.tsx @@ -36,14 +36,12 @@ const GroupConfigPage = lazy( const GroupCreatePage = lazy( () => import('@pages/GroupCreatePage/GroupCreatePage'), ); -const LibraryPage = lazy(() => import('@pages/LibraryPage/LibraryPage')); -const LibraryDetailPage = lazy( - () => import('@pages/LibraryDetailPage/LibraryDetailPage'), -); +const LibraryPage = lazy(() => import('@pages/LibraryPage')); +const LibraryDetailPage = lazy(() => import('@pages/LibraryDetailPage')); const MyPage = lazy(() => import('@pages/MyPage')); const SupportPage = lazy(() => import('@pages/SupportPage')); const CalendarPage = lazy(() => import('@pages/CalendarPage/CalendarPage')); -const LoginPage = lazy(() => import('@pages/LoginPage/LoginPage')); +const LoginPage = lazy(() => import('@pages/LoginPage')); const AuthPage = lazy(() => import('@pages/AuthPage/AuthPage')); const BlogPage = lazy(() => import('@pages/BlogPage/BlogPage')); const ManagePage = lazy(() => import('@pages/ManagePage/ManagePage'));