From 08c919d173e9997f5e5e2c94d6ea47e2798f2555 Mon Sep 17 00:00:00 2001 From: Shaw Date: Mon, 6 Nov 2023 22:30:35 +0900 Subject: [PATCH] =?UTF-8?q?[#410]=20[=EB=B6=81=EC=B9=B4=EC=9D=B4=EB=B8=8C]?= =?UTF-8?q?=20=EB=B6=81=EC=B9=B4=EC=9D=B4=EB=B8=8C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20(=EB=B9=84=ED=9A=8C=EC=9B=90)=20(#425)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 책장 컴포넌트 작성 * feat: 책장에 있는 책 컴포넌트 작성 * feat: 책장 컴포넌트 스토리 작성 * fix: 책장 컴포넌트에서 CLS 현상이 발생하지 않도록 수정 * feat: 책장에 있는 책 그림자 추가 * fix: remove icon wrapper element * feat: Add a bookshelf shortcut icon * feat: '인기 책장' 문구 추가 * fix: 책장 local image 사용하도록 수정 * Update src/ui/BookArchive/BookArchiveForUnAuth.tsx Co-authored-by: kyuran kim <57716832+gxxrxn@users.noreply.github.com> --------- Co-authored-by: gxxrxn Co-authored-by: kyuran kim <57716832+gxxrxn@users.noreply.github.com> --- public/icons/arrow-right.svg | 2 +- .../Base/Bookshelf/Bookshelf.stories.tsx | 43 ++++++++++++ src/ui/BookArchive/BookArchiveForUnAuth.tsx | 25 +++---- src/ui/Bookshelf/Book.tsx | 67 +++++++++++++++++++ src/ui/Bookshelf/index.tsx | 44 ++++++++++++ src/ui/InteractiveBook/index.tsx | 8 +-- 6 files changed, 169 insertions(+), 20 deletions(-) create mode 100644 src/stories/Base/Bookshelf/Bookshelf.stories.tsx create mode 100644 src/ui/Bookshelf/Book.tsx create mode 100644 src/ui/Bookshelf/index.tsx diff --git a/public/icons/arrow-right.svg b/public/icons/arrow-right.svg index 44200abb..e8dde4cf 100644 --- a/public/icons/arrow-right.svg +++ b/public/icons/arrow-right.svg @@ -1,3 +1,3 @@ - + diff --git a/src/stories/Base/Bookshelf/Bookshelf.stories.tsx b/src/stories/Base/Bookshelf/Bookshelf.stories.tsx new file mode 100644 index 00000000..b678492c --- /dev/null +++ b/src/stories/Base/Bookshelf/Bookshelf.stories.tsx @@ -0,0 +1,43 @@ +import Bookshelf from '@/ui/Bookshelf'; +import { Meta, StoryObj } from '@storybook/react'; + +const meta: Meta = { + title: 'Bookshelf/Bookshelf', + component: Bookshelf, + tags: ['autodocs'], +}; + +export default meta; + +type Story = StoryObj; + +// TODO: 스토리북에서 이미지를 불러올 때 발생하는 CORS 이슈 해결 +export const Default: Story = { + args: { + bookshelfId: 9, + bookshelfName: '백민종님의 책장', + books: [ + { + bookId: 3, + title: '리액트를 다루는 기술', + imageUrl: '/images/book-cover/book1.jpeg', + }, + { + bookId: 11, + title: '모던 자바스크립트 Deep Dive', + imageUrl: '/images/book-cover/book2.jpeg', + }, + { + bookId: 22, + title: '이펙티브 타입스크립트', + imageUrl: '/images/book-cover/book3.jpeg', + }, + { + bookId: 23, + title: '리팩터링 2판', + imageUrl: '/images/book-cover/book4.jpeg', + }, + ], + likeCount: 3, + }, +}; diff --git a/src/ui/BookArchive/BookArchiveForUnAuth.tsx b/src/ui/BookArchive/BookArchiveForUnAuth.tsx index 1ee0eab5..f8abdb94 100644 --- a/src/ui/BookArchive/BookArchiveForUnAuth.tsx +++ b/src/ui/BookArchive/BookArchiveForUnAuth.tsx @@ -1,6 +1,6 @@ import useUnAuthRecommendedBookshelfQuery from '@/queries/recommend/useUnAuthRecommendedBookshelfQuery'; -import { Flex, Skeleton, VStack } from '@chakra-ui/react'; -import { RecommendedBookshelf } from '../Recommended'; +import { Skeleton, VStack } from '@chakra-ui/react'; +import Bookshelf from '../Bookshelf'; const BookArchiveForUnAuth = () => { const { data, isSuccess, isLoading } = useUnAuthRecommendedBookshelfQuery(); @@ -17,19 +17,14 @@ const BookArchiveForUnAuth = () => { if (!isSuccess) return null; return ( - - {data.bookshelfResponses.map( - ({ bookshelfId, bookshelfName, books, likeCount }) => ( - - ) - )} - +
+
🔥 인기 책장
+
+ {data.bookshelfResponses.map(bookshelf => ( + + ))} +
+
); }; diff --git a/src/ui/Bookshelf/Book.tsx b/src/ui/Bookshelf/Book.tsx new file mode 100644 index 00000000..4bb2cdec --- /dev/null +++ b/src/ui/Bookshelf/Book.tsx @@ -0,0 +1,67 @@ +'use client'; + +import { APIBook } from '@/types/book'; +import ColorThief from 'colorthief'; +import Image from 'next/image'; +import Link from 'next/link'; +import { useState } from 'react'; + +const BookInBookshelf = ({ + imageUrl, + bookId, +}: Pick) => { + const [bookSpineColor, setBookSpineColor] = useState(); + + const handleOnLoadImage = (image: HTMLImageElement) => { + const colorThief = new ColorThief(); + const colorHex = colorThief + .getPalette(image, 2)[0] + .map(x => x.toString(16).padStart(2, '0')) + .join(''); + setBookSpineColor(`#${colorHex}`); + }; + + return ( +
+
+
+ + book cover + +
+ ); +}; + +export default BookInBookshelf; diff --git a/src/ui/Bookshelf/index.tsx b/src/ui/Bookshelf/index.tsx new file mode 100644 index 00000000..54df6a42 --- /dev/null +++ b/src/ui/Bookshelf/index.tsx @@ -0,0 +1,44 @@ +import { APIBookshelf } from '@/types/bookshelf'; +import { IconArrowRight, IconHeart } from '@public/icons'; +import Link from 'next/link'; +import Badge from '../Base/Badge'; +import BookInBookshelf from './Book'; + +const Bookshelf = ({ + bookshelfId, + bookshelfName, + books, + likeCount, +}: APIBookshelf) => { + return ( +
+
+
+
+
+
+
+
+
{bookshelfName}
+ + + +
+ +
+ +
{likeCount}
+
+
+
+
+ {books.map(book => ( + + ))} +
+
+
+ ); +}; + +export default Bookshelf; diff --git a/src/ui/InteractiveBook/index.tsx b/src/ui/InteractiveBook/index.tsx index ad4585aa..59ac340f 100644 --- a/src/ui/InteractiveBook/index.tsx +++ b/src/ui/InteractiveBook/index.tsx @@ -44,7 +44,7 @@ const InteractiveBook = ({ imageUrl, bookId }: InteractiveBookProps) => { cursor={bookId ? 'pointer' : 'auto'} > { h="1rem" pos="absolute" bottom={0} - transform={`translateZ(-3rem)`} + transform={`translateZ(-2.5rem)`} boxShadow="1px -4px 20px 3px" /> { quality={100} />