From b768a545fa2aae50b9663668894a9b0592d1321b Mon Sep 17 00:00:00 2001 From: jihwooon Date: Wed, 6 Mar 2024 15:31:12 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8F=84=EC=84=9C=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주요 변경 내용 - 도서 상세 페이지를 구현했습니다. - 라우터 설정을 통해 특정 도서 아이디로 상세 페이지 접근 가능하도록 했습니다. - useBook 훅을 사용하여 API 호출 및 데이터 가져오기 구현했습니다. - 도서 정보를 화면에 표시합니다. 관련 변경 사항 - client/src/App.tsx 파일 수정 - client/src/api/books.api.ts 파일 수정 - client/src/components/books/BookItem.tsx 파일 수정 - client/src/hooks/useBook.ts 파일 생성 (새 파일) - client/src/pages/BookDetail.tsx 파일 생성 (새 파일) --- client/src/App.tsx | 19 +++++++++---- client/src/api/books.api.ts | 8 +++++- client/src/components/books/BookItem.tsx | 36 ++++++++++++++---------- client/src/hooks/useBook.ts | 17 +++++++++++ client/src/pages/BookDetail.tsx | 18 ++++++++++++ client/src/pages/Home.tsx | 1 - 6 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 client/src/hooks/useBook.ts create mode 100644 client/src/pages/BookDetail.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index 6182598..b9ca3ec 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,12 +1,13 @@ -import Layout from "./components/layout/Layout"; -import Home from "./pages/Home"; -import { BookStoreThemeProvider } from "./context/themeContext"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; import Error from "./components/common/Error"; -import Signup from "./pages/Signup"; +import Layout from "./components/layout/Layout"; +import { BookStoreThemeProvider } from "./context/themeContext"; +import BookDetail from "./pages/BookDetail"; +import Books from "./pages/Books"; +import Home from "./pages/Home"; import ResetPassword from "./pages/ResetPassword"; import Signin from "./pages/Signin"; -import Books from "./pages/Books"; +import Signup from "./pages/Signup"; const router = createBrowserRouter([ { @@ -50,6 +51,14 @@ const router = createBrowserRouter([ ), }, + { + path: '/book/:bookId', + element: ( + + + + ) + } ]); function App() { diff --git a/client/src/api/books.api.ts b/client/src/api/books.api.ts index 6259e04..fdf3b82 100644 --- a/client/src/api/books.api.ts +++ b/client/src/api/books.api.ts @@ -1,4 +1,4 @@ -import { Book } from "../models/book.model"; +import { Book, BookDetail } from "../models/book.model"; import { Pagination } from "../models/pagination.model"; import { httpClient } from "./http"; @@ -30,3 +30,9 @@ export const fetchBooks = async (params: FetchBooksParams) => { } } } + +export const fetchBook = async (bookId: string) => { + const response = await httpClient.get(`/books/${bookId}`); + + return response.data; +} diff --git a/client/src/components/books/BookItem.tsx b/client/src/components/books/BookItem.tsx index 2bfbb0b..d7dc3de 100644 --- a/client/src/components/books/BookItem.tsx +++ b/client/src/components/books/BookItem.tsx @@ -1,4 +1,5 @@ import { FaHeart } from "react-icons/fa"; +import { Link } from "react-router-dom"; import { styled } from "styled-components"; import { Book } from "../../models/book.model"; import { formatNumber } from "../../utils/format"; @@ -13,27 +14,32 @@ interface Props { const BookItem = ({ book, view }: Props) => { return ( -
- {book.title} -
-
-

{book.title}

-

{book.summary}

-

{book.author}

-

{formatNumber(book.price)}원

-
- - {book.likes} + +
+ {book.title}
-
+
+

{book.title}

+

{book.summary}

+

{book.author}

+

{formatNumber(book.price)}원

+
+ + {book.likes} +
+
+ ); }; const BookItemStyled = styled.div>` - display: flex; - flex-direction: column; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); + a { + display: flex; + flex-direction: ${({ view }) => (view === 'grid') ? "column" : "row"}; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); + text-decoration: none; + } .img { border-radius: ${({ theme }) => theme.borderRadius.default}; diff --git a/client/src/hooks/useBook.ts b/client/src/hooks/useBook.ts new file mode 100644 index 0000000..06f466a --- /dev/null +++ b/client/src/hooks/useBook.ts @@ -0,0 +1,17 @@ +import { useEffect, useState } from "react"; +import { fetchBook } from "../api/books.api"; +import { BookDetail } from "../models/book.model"; + +export const useBook = (bookId: string | undefined) => { + const [book, setBook] = useState(null); + + useEffect(() => { + if (!bookId) return; + + fetchBook(bookId).then((book) => { + setBook(book) + }) + }, [bookId]) + + return { book } +} diff --git a/client/src/pages/BookDetail.tsx b/client/src/pages/BookDetail.tsx new file mode 100644 index 0000000..398ab0d --- /dev/null +++ b/client/src/pages/BookDetail.tsx @@ -0,0 +1,18 @@ +import { useParams } from "react-router-dom"; +import styled from "styled-components"; +import { useBook } from "../hooks/useBook"; + +const BookDetail = () => { + const { bookId } = useParams(); + const { book } = useBook(bookId); + + if (!book) return null; + + return ( +

{book.title}

+ ) +} + +const BookDetailStyle = styled.div`` + +export default BookDetail; diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index 8a847d5..b734603 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -8,7 +8,6 @@ const Home = () => { 제목 테스트 -
detail
) }