Skip to content

Commit

Permalink
도서 상세 페이지 구현 및 정보 확장
Browse files Browse the repository at this point in the history
변경 사항
- 도서 상세 페이지에서 보여지는 정보를 확장했습니다.
- 도서 카테고리, 출간일, 가격 등의 정보를 추가했습니다.
- dayjs 라이브러리를 추가하여 날짜 포맷팅 기능을 구현했습니다.
- 서버 도메인 모델에서 Book 클래스에 categoryName 속성을 추가했습니다.
- findWithCategory 함수를 수정하여 카테고리 이름 정보를 함께 조회하도록 했습니다.

관련 변경 사항
- client/package.json 파일 수정
- client/package-lock.json 파일 수정
- client/src/api/http.ts 파일 수정
- client/src/pages/BookDetail.tsx 파일 수정
- client/src/utils/format.ts 파일 수정
- server/src/books/domain/book.ts 파일 수정
- server/src/books/domain/books.repository.ts 파일 수정
  • Loading branch information
jihwooon committed Mar 6, 2024
1 parent e1318fc commit e57f53a
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 6 deletions.
6 changes: 6 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@types/react-dom": "^18.2.19",
"@types/react-router-dom": "^5.3.3",
"axios": "^1.6.7",
"dayjs": "^1.11.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.50.1",
Expand Down
2 changes: 1 addition & 1 deletion client/src/api/http.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios, { AxiosRequestConfig } from 'axios'
import axios, { AxiosRequestConfig } from 'axios';
import { getToken, removeToken } from '../store/authStore';

const BASE_URL = "http://localhost:8080";
Expand Down
111 changes: 108 additions & 3 deletions client/src/pages/BookDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
import { useParams } from "react-router-dom";
import { Link, useParams } from "react-router-dom";
import styled from "styled-components";
import Title from "../components/common/Title";
import { useBook } from "../hooks/useBook";
import { BookDetail as IBookDetail } from "../models/book.model";
import { formatDate, formatNumber } from "../utils/format";
import { getImgSrc } from "../utils/image";

const bookInfoList = [
{
label: "카테고리",
key: "categoryName",
filter: (book: IBookDetail) => (
<Link to={`/books?category_id=${book.categoryId}`}>
{book.categoryName}
</Link>
)
},
{
label: "포맷",
key: "form"
},
{
label: "페이지",
key: "pages"
},
{
label: "ISBN",
key: "isbn"
},
{
label: "출간일",
key: "pubDate",
filter: (book: IBookDetail) => {
return formatDate(book.pubDate)
}
},
{
label: "가격",
key: "price",
filter: (book: IBookDetail) => {
return `${formatNumber(book.price)} 원`
}
}
]

const BookDetail = () => {
const { bookId } = useParams();
Expand All @@ -9,10 +51,73 @@ const BookDetail = () => {
if (!book) return null;

return (
<BookDetailStyle><h1>{book.title}</h1></BookDetailStyle>
<BookDetailStyle>
<header className="header">
<div className="img">
<img src={getImgSrc(book.imgId)} alt={book.title}/>
</div>
<div className="info">
<Title size="large" color="text">
{book.title}
</Title>
{
bookInfoList.map((item) => (
<dl>
<dt>{item.label}</dt>
<dd>{item.filter ? item.filter(book) : book
[item.key as keyof IBookDetail]}</dd>
</dl>
))
}
<p className="summary">{book.summary}</p>

<div className="like">
Like
</div>

<div className="add-cart">
Cart
</div>
</div>
</header>
</BookDetailStyle>
)
}

const BookDetailStyle = styled.div``
const BookDetailStyle = styled.div`
.header {
display: flex;
align-items: start;
gap: 24px;
padding: 0 0 24px 0;
.img {
flex: 1;
img {
width: 100%;
height: auto;
}
}
.info {
flex: 1;
display: flex;
flex-direction: column;
gap: 12px;
dl {
display: flex;
margin: 0;
dt {
width: 80px;
color: ${({ theme }) => theme.color.secondary}
}
a {
color: ${({ theme }) => theme.color.primary}
}
}
}
}
`

export default BookDetail;
8 changes: 7 additions & 1 deletion client/src/utils/format.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import dayjs from 'dayjs';

export const formatNumber = (number: number) => {
return number.toLocaleString();
}
}

export const formatDate = (date: string, format?: string) => {
return dayjs(date).format(format ? format : "YYYY년 MM월 DD일")
}
9 changes: 9 additions & 0 deletions server/src/books/domain/book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export default class Book {

private categoryId: number;

private categoryName: string;

private form: string;

private isbn: string;
Expand All @@ -32,6 +34,7 @@ export default class Book {
title = '',
imgId = 0,
categoryId = 0,
categoryName = '',
form = '',
isbn = '',
summary = '',
Expand All @@ -47,6 +50,7 @@ export default class Book {
title?: string;
imgId?: number;
categoryId?: number;
categoryName?: string;
form?: string;
isbn?: string;
summary?: string;
Expand All @@ -62,6 +66,7 @@ export default class Book {
this.title = title;
this.imgId = imgId;
this.categoryId = categoryId;
this.categoryName = categoryName;
this.form = form;
this.isbn = isbn;
this.summary = summary;
Expand Down Expand Up @@ -90,6 +95,10 @@ export default class Book {
return this.categoryId;
}

getCategoryName() {
return this.categoryName;
}

getForm() {
return this.form;
}
Expand Down
3 changes: 2 additions & 1 deletion server/src/books/domain/books.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const findAll = async (
export const findWithCategory = async (userId: number, bookId: number): Promise<Book> => {
const [rows] = await doQuery((connection) =>
connection.execute<RowDataPacket[]>(
`SELECT b.id, b.title, b.category_id, b.form, b.isbn, b.summary, b.detail, b.author, b.pages, b.contents, b.price, b.pub_date,
`SELECT b.id, b.title, b.category_id, c.name as category_name, b.form, b.isbn, b.summary, b.detail, b.author, b.pages, b.contents, b.price, b.pub_date,
(SELECT count(*) FROM likes WHERE b.id = liked_book_id) as Likes,
(SELECT EXISTS(SELECT * FROM likes WHERE user_id = ? AND liked_book_id)) as liked
FROM books b
Expand All @@ -79,6 +79,7 @@ export const findWithCategory = async (userId: number, bookId: number): Promise<
form: row.form,
isbn: row.isbn,
categoryId: row.category_id,
categoryName: row.category_name,
summary: row.summary,
detail: row.detail,
author: row.author,
Expand Down

0 comments on commit e57f53a

Please sign in to comment.