Skip to content

Commit

Permalink
Merge pull request #118 from KGU-C-Lab/refactor/#117
Browse files Browse the repository at this point in the history
도서관 사용자 피드백 개선 (OPEN-BETA)
  • Loading branch information
gwansikk authored May 3, 2024
2 parents 6f0e777 + 45e1d17 commit a5a808e
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 103 deletions.
24 changes: 13 additions & 11 deletions apps/member/src/components/library/BookCard/BookCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Image from '@components/common/Image/Image';

import { PATH_FINDER } from '@constants/path';
import { BOOK_STATE } from '@constants/state';
import classNames from 'classnames';
import { cn } from '@utils/string';

import type { BookItem } from '@type/book';

Expand All @@ -28,29 +28,31 @@ const BookCard = ({
<Image
src={imageUrl}
alt={title}
width="w-full"
height="h-[200px]"
className="border-b object-cover transition-transform ease-in-out group-hover:scale-110"
overflow
/>
<div className="flex grow flex-col justify-between p-2 text-sm">
<div>
<p className="font-semibold group-hover:underline">{title}</p>
<p className="text-gray-500">
{author} | {publisher}
<div className="break-keep">
<p className="line-clamp-2 font-semibold group-hover:underline">
{title}
</p>
<div className="text-gray-500">
<p className="line-clamp-1">{author}</p>
<p className="line-clamp-1">{publisher}</p>
</div>
</div>
<div className="mt-2 flex items-center gap-1">
<span
className={classNames(
'h-1.5 w-1.5 rounded-full',
borrowerId ? 'bg-green-600' : 'bg-pink-600',
className={cn(
'size-1.5 rounded-full',
borrowerId ? 'bg-pink-600' : 'bg-green-600',
)}
/>
<span
className={classNames(
className={cn(
'text-xs',
borrowerId ? 'text-green-600' : 'text-pink-600',
borrowerId ? 'text-pink-600' : 'text-green-600',
)}
>
{borrowerId ? BOOK_STATE.BORROWED : BOOK_STATE.AVAILABLE}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ const BookDetailSection = ({ data }: BookDetailSectionProps) => {
<Section>
<Grid gap="lg" className="lg:grid-cols-2">
<Image
width="p-4"
src={createImageUrl(imageUrl)}
alt={title}
className="object-cover drop-shadow-lg"
width="w-[420px]"
height="h-[520px]"
className="object-cover p-4 drop-shadow-lg"
/>
<div className="flex flex-col justify-between gap-4">
<div className="space-y-4">
Expand All @@ -94,17 +95,16 @@ const BookDetailSection = ({ data }: BookDetailSectionProps) => {
</Badge>
</DetailsList.Item>
</DetailsList>
<Tabs
value={SELECT_DEFAULT_OPTION}
options={options}
onChange={handleTabsChange}
/>
<div>
<label className="mb-1 ml-1 text-xs">온라인 서점 바로가기</label>
<Tabs
value={SELECT_DEFAULT_OPTION}
options={options}
onChange={handleTabsChange}
/>
</div>
</div>
<Button disabled={!!borrowerId} onClick={() => handleBorrowClick(id)}>
{borrowerId
? '이미 대여된 도서예요! 조금만 기다려주세요'
: '대여하기'}
</Button>
<Button onClick={() => handleBorrowClick(id)}>대여 신청하기</Button>
</div>
</Grid>
</Section>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Badge, BadgeColorType } from '@clab/design-system';

import { BOOK_STATE } from '@constants/state';

import type { BookLoanRecordConditionType } from '@type/book';

interface BookLoanConditionStatusBadgeProps
Expand All @@ -9,7 +11,11 @@ const BookLoanConditionStatusBadge = ({
borrowedAt,
returnedAt,
}: BookLoanConditionStatusBadgeProps) => {
const text = !borrowedAt ? '대기' : !returnedAt ? '대여중' : '반납완료';
const text = !borrowedAt
? BOOK_STATE.WAIT
: !returnedAt
? BOOK_STATE.BORROWED
: BOOK_STATE.RETURN;
const color: BadgeColorType = !borrowedAt
? 'red'
: !returnedAt
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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(16);

const { data } = useBooks(page, size);

return (
<Section>
<Section.Header
title="둘러보기"
description="소장 도서를 둘러볼 수 있어요"
/>
<Section.Body>
<div className="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4">
{data.items.map(({ id, ...rest }) => (
<BookCard key={id} id={id} {...rest} />
))}
</div>
<Pagination
className="mt-4 justify-center"
totalItems={data.totalItems}
postLimit={size}
onChange={handlePageChange}
page={page}
/>
</Section.Body>
</Section>
);
};
export default LibraryBooksSection;
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,32 @@ 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';

import { BookItem } from '@type/book';
const LibraryNewBooksSection = () => {
const { data } = useBooks(0, 4);

interface LibraNewBooksSectionProps {
data: BookItem[];
}

const LibraryNewBooksSection = ({ data }: LibraNewBooksSectionProps) => {
return (
<Section>
<Section.Header
title="신규 도서"
description="최근에 들어온 도서들을 확인해보세요"
/>
<Section.Body className="flex gap-4">
{data.map(({ id, imageUrl, title, author, publisher }) => (
<Section.Body className="grid grid-cols-2 gap-4 md:grid-cols-4">
{data.items.map(({ id, imageUrl, title, author, publisher }) => (
<Link
key={id}
to={PATH_FINDER.BOOK_DETAIL(id)}
className="group relative flex flex-col gap-2 rounded-lg border shadow-lg"
className="group relative flex flex-col gap-2 overflow-hidden rounded-lg border"
>
<Image
src={imageUrl}
alt={title}
width="w-[200px]"
className="rounded-lg object-cover"
overflow
className="rounded-lg object-cover transition-transform group-hover:scale-105"
/>
<div className="pointer-events-none absolute inset-0 rounded-lg bg-gradient-to-t from-black/60 via-black/30 opacity-0 transition-all group-hover:opacity-100" />
<div className="absolute bottom-0 px-2 text-white opacity-0 transition-all group-hover:-translate-y-5 group-hover:opacity-100">
<p className="break-keep font-semibold">{title}</p>
<div className="pointer-events-none absolute inset-0 rounded-lg bg-gradient-to-t from-black/60 via-black/30 opacity-0 group-hover:opacity-100" />
<div className="absolute bottom-0 px-2 text-white opacity-0 transition-transform group-hover:-translate-y-2.5 group-hover:opacity-100">
<p className="line-clamp-2 break-keep font-semibold">{title}</p>
<p className="text-sm">
{author} | {publisher}
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useCallback } from 'react';

import { Badge } from '@clab/design-system';

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 { MY_MESSAGE } from '@constants/message';
import { PATH_FINDER } from '@constants/path';
Expand Down Expand Up @@ -67,14 +66,17 @@ const MyHistorySection = ({ title, data }: MyHistorySectionProps) => {
return (
<ListButton key={index} to={PATH_FINDER.BOOK_DETAIL(bookId)}>
<p className="grow space-x-2 truncate pr-4">
<Badge color={returnedAt ? 'green' : 'yellow'}>
{returnedAt ? '반납완료' : '대출중'}
</Badge>
<BookLoanConditionStatusBadge
borrowedAt={borrowedAt}
returnedAt={returnedAt}
/>
<span>{bookTitle}</span>
</p>
<p className="text-clab-main-light">
{toYYMMDD(borrowedAt ?? '')}
</p>
{returnedAt && (
<p className="text-clab-main-light">
{toYYMMDD(returnedAt)}
</p>
)}
</ListButton>
);
}
Expand Down
4 changes: 3 additions & 1 deletion apps/member/src/constants/state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export const BOOK_STATE = {
BORROWED: '대여중',
WAIT: '대기',
AVAILABLE: '대여가능',
BORROWED: '대여중',
RETURN: '반납완료',
} as const;

export const DATE_FORMAT = {
Expand Down
21 changes: 12 additions & 9 deletions apps/member/src/hooks/common/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,32 @@ import { useLocation, useNavigate } from 'react-router-dom';

/**
* 페이지네이션을 위한 페이지 조작 훅입니다.
* Pagination Component와 같이 사용합니다.
*/
export const usePagination = (defaultSize: number = 20) => {
const navigate = useNavigate();
const location = useLocation();
const searchParams = new URLSearchParams(location.search);

const getPage = useCallback(() => {
const searchParams = new URLSearchParams(location.search);
return parseInt(searchParams.get('page') ?? '1', 10) - 1;
}, [location.search]);

const [pagination, setPagination] = useState({
page: parseInt(searchParams.get('page') ?? '1') - 1,
page: getPage(),
size: defaultSize,
});

// 페이지 변경 핸들러
const handlePageChange = useCallback(
(page: number) => {
navigate(`?page=${page}`, { replace: false });
navigate('?page=' + page);
},
[navigate],
);

useEffect(() => {
const page = parseInt(searchParams.get('page') ?? '1', 10) - 1;
setPagination((prev) => ({ ...prev, page }));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location.search]);
setPagination((prev) => ({ ...prev, page: getPage() }));
}, [getPage]);

return { page: pagination.page, size: pagination.size, handlePageChange };
return { ...pagination, handlePageChange };
};
2 changes: 2 additions & 0 deletions apps/member/src/hooks/queries/book/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './useBooks';
export * from './useBookDetails';
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { useSuspenseQuery } from '@tanstack/react-query';
import { getBooks } from '@api/book';
import { QUERY_KEY } from '@constants/key';

/**
* 도서 목록을 조회합니다.
*/
export const useBooks = (page = 0, size = 6) => {
return useSuspenseQuery({
queryKey: [QUERY_KEY.BOOK, page, size],
queryKey: [QUERY_KEY.BOOK, { page, size }],
queryFn: () => getBooks(page, size),
});
};
1 change: 1 addition & 0 deletions apps/member/src/hooks/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export * from './useScheduleDeleteMutation';
export * from './useUserInfoMutation';
export * from './useActivityGroupMemberMy';
export * from './book-loan-record';
export * from './book';
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import BookLoanHistorySection from '@components/library/BookLoanHistorySection/B

import { LIBRARY_MESSAGE } from '@constants/message';
import { PATH } from '@constants/path';
import { useBookDetails } from '@hooks/queries/useBookDetails';
import { useBookDetails } from '@hooks/queries/book';

const LibraryDetailPage = () => {
const { id } = useParams<{ id: string }>();
Expand Down
34 changes: 8 additions & 26 deletions apps/member/src/pages/LibraryPage/LibraryPage.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import { Suspense } from 'react';
import { useNavigate } from 'react-router-dom';

import { Button } from '@clab/design-system';

import Content from '@components/common/Content/Content';
import Header from '@components/common/Header/Header';
import Pagination from '@components/common/Pagination/Pagination';
import Section from '@components/common/Section/Section';
import LibraryBookList from '@components/library/LibraryBookList/LibraryBookList';
import LibraryBooksSection from '@components/library/LibraryBooksSection/LibraryBooksSection';
import LibraryNewBooksSection from '@components/library/LibraryNewBooksSection/LibraryNewBooksSection';

import { PATH } from '@constants/path';
import { usePagination } from '@hooks/common/usePagination';
import { useBooks } from '@hooks/queries/useBooks';

const LibraryPage = () => {
const navigate = useNavigate();
const { page, size, handlePageChange } = usePagination();

const { data: newBookData } = useBooks(0, 4);
const { data: bookData } = useBooks(page, size);

return (
<Content>
Expand All @@ -27,23 +20,12 @@ const LibraryPage = () => {
희망도서 신청하기
</Button>
</Header>
<LibraryNewBooksSection data={newBookData.items} />
<Section>
<Section.Header
title="둘러보기"
description="소장 도서를 둘러볼 수 있어요"
/>
<Section.Body>
<LibraryBookList data={bookData.items} />
<Pagination
className="mt-4 justify-center"
totalItems={bookData.totalItems}
postLimit={size}
onChange={handlePageChange}
page={page}
/>
</Section.Body>
</Section>
<Suspense>
<LibraryNewBooksSection />
</Suspense>
<Suspense>
<LibraryBooksSection />
</Suspense>
</Content>
);
};
Expand Down

0 comments on commit a5a808e

Please sign in to comment.