Skip to content

Commit

Permalink
Merge pull request #85 from KGU-C-Lab/refactor/#83
Browse files Browse the repository at this point in the history
도서관 코드 개선 완료
  • Loading branch information
gwansikk authored Apr 2, 2024
2 parents 9576133 + c0da224 commit 927aa2f
Show file tree
Hide file tree
Showing 23 changed files with 288 additions and 166 deletions.
36 changes: 23 additions & 13 deletions apps/member/src/api/book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ import type {
BookLoanRecordConditionType,
BookLoanRecordItem,
} from '@type/book';
import type { BaseResponse, PaginationType } from '@type/api';
import type {
BaseResponse,
PaginationPramsType,
PaginationType,
} from '@type/api';

interface PostBorrowBookArgs extends BookLoanRecordItem {
memberId: string;
}

interface GetBookLoanRecordConditionsPrams extends PaginationPramsType {
bookId?: number;
borrowerId?: string;
isReturned?: boolean;
}
/**
* 도서 목록 조회
*/
Expand All @@ -23,7 +32,6 @@ export const getBooks = async (page: number, size: number) => {

return data;
};

/**
* 도서 상세 조회
*/
Expand All @@ -34,7 +42,6 @@ export const getBookDetail = async (id: number) => {

return data;
};

/**
* 나의 대출내역 조회
*/
Expand All @@ -46,7 +53,6 @@ export const getMyBooks = async (id: string, page: number, size: number) => {

return data.items.filter((book) => book.borrowerId === id);
};

/**
* 도서 대출
*/
Expand All @@ -59,7 +65,6 @@ export const postBorrowBook = async (body: PostBorrowBookArgs) => {

return { memberId: body.memberId, bookId: body.bookId, data };
};

/**
* 도서 반납
*/
Expand All @@ -71,7 +76,6 @@ export const postReturnBook = async (body: BookLoanRecordItem) => {

return { memberId: body.borrowerId, bookId: body.bookId, data };
};

/**
* 도서 연장
*/
Expand All @@ -83,20 +87,26 @@ export const postExtendBook = async (body: BookLoanRecordItem) => {

return { memberId: body.borrowerId, bookId: data };
};

/**
* 도서 대출 내역 검색
* 도서 대출 내역 조회
*/
export const getBookLoanByMemberId = async (
borrowerId: string,
export const getBookLoanRecordConditions = async ({
bookId,
borrowerId,
isReturned,
page = 0,
size = 20,
) => {
const params = { borrowerId, page, size };
}: GetBookLoanRecordConditionsPrams) => {
const { data } = await server.get<
PaginationType<BookLoanRecordConditionType>
>({
url: createCommonPagination(END_POINT.BOOK_LOAN_CONDITIONS, params),
url: createCommonPagination(END_POINT.BOOK_LOAN_CONDITIONS, {
bookId,
borrowerId,
isReturned,
page,
size,
}),
});

return data;
Expand Down
1 change: 1 addition & 0 deletions apps/member/src/assets/svg/yes24.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/member/src/assets/webp/aladin.webp
Binary file not shown.
Binary file added apps/member/src/assets/webp/kyobobook.webp
Binary file not shown.
6 changes: 3 additions & 3 deletions apps/member/src/components/library/BookCard/BookCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ const BookCard = ({

return (
<div
className="flex flex-col group space-y-1 border rounded-lg cursor-pointer"
className="flex flex-col space-y-1 overflow-hidden border rounded-lg cursor-pointer group"
onClick={() => navigate(PATH_FINDER.LIBRARY_DETAIL(id))}
>
<Image
src={imageUrl}
alt={title}
width="w-full"
height="h-[200px]"
className="object-cover border-b rounded-t-lg group-hover:scale-125 transition-transform ease-in-out"
className="object-cover transition-transform ease-in-out border-b group-hover:scale-110"
overflow
/>
<div className="flex flex-col grow justify-between text-sm p-2">
<div className="flex flex-col justify-between p-2 text-sm grow">
<div>
<p className="font-semibold group-hover:underline">{title}</p>
<p className="text-gray-500">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,86 @@
import Section from '@components/common/Section/Section';
import { Link } from 'react-router-dom';
import { Button } from '@clab/design-system';
import Image from '@components/common/Image/Image';
import { Button, DetailsList, Badge, Grid, Tabs } from '@clab/design-system';
import { BOOK_STATE } from '@constants/state';
import { useBookLoanBorrowMutation } from '@hooks/queries/useBookLoanBorrowMutation';
import { useMyProfile } from '@hooks/queries/useMyProfile';
import { useCallback } from 'react';
import { createImageUrl } from '@utils/api';
import { SELECT_DEFAULT_OPTION } from '@constants/select';
import kyoboIcon from '@assets/webp/kyobobook.webp';
import aladinIcon from '@assets/webp/aladin.webp';
import yes24Icon from '@assets/svg/yes24.svg';
import type { BookItem } from '@type/book';

interface BookDetailSectionProps {
data: BookItem;
}

interface BookInfoRowProps {
to?: string;
label: string;
content: string;
}

const BookInfoRow = ({ to, label, content }: BookInfoRowProps) => {
return (
<div className="flex">
<p className="w-20 font-semibold">{label}</p>
{to ? (
<Link to={to} className="content-link">
{content}
</Link>
) : (
<p className="content-text">{content}</p>
)}
</div>
);
};
const tabsOptions = [
{
icon: <img src={kyoboIcon} alt="" className="size-6" />,
value: '교보문고',
},
{
icon: <img src={yes24Icon} alt="" className="size-6" />,
value: '예스24',
},
{
icon: <img src={aladinIcon} alt="" className="rounded-lg size-6" />,
value: '알라딘',
},
];

const BookDetailSection = ({ data }: BookDetailSectionProps) => {
const { data: myInfo } = useMyProfile();
const { bookBorrowMutate } = useBookLoanBorrowMutation();
const { id, borrowerId, category, title, author, publisher, imageUrl } = data;

const onClickBorrow = (bookId: number) => {
bookBorrowMutate({
memberId: myInfo.id,
bookId: bookId,
borrowerId: myInfo.id,
});
};
const handleBorrowClick = useCallback(
(bookId: number) => {
bookBorrowMutate({
memberId: myInfo.id,
bookId: bookId,
borrowerId: myInfo.id,
});
},
[bookBorrowMutate, myInfo.id],
);

return (
<Section>
<div className="flex flex-col gap-2 px-2">
<div className="gap-4 my-4 lg:grid lg:grid-cols-2">
<div className="flex justify-center md:mb-4 lg:m-0 lg:max-w-3xl">
<Image
src={imageUrl}
alt={title}
width="w-[300px]"
className="object-cover shadow-lg"
/>
</div>
<div className="flex flex-col justify-between gap-4">
<div className="space-y-2">
<h1 className="pb-4 text-2xl font-bold break-keep">{title}</h1>
<BookInfoRow label="작가" content={author} />
<BookInfoRow label="출판사" content={publisher} />
<BookInfoRow label="분류" content={category} />
<BookInfoRow
label="대여 상태"
content={
borrowerId ? BOOK_STATE.BORROWED : BOOK_STATE.AVAILABLE
}
/>
</div>
<div className="w-full">
{borrowerId ? (
<p className="pt-12 text-xl font-bold text-center underline decoration-green-700 lg:text-left">
이미 대여된 도서예요! 조금만 기다려주세요 ⏳
</p>
) : (
<Button className="w-full" onClick={() => onClickBorrow(id)}>
대여하기
</Button>
)}
</div>
<Grid gap="lg" className="lg:grid-cols-2">
<Image
src={createImageUrl(imageUrl)}
alt={title}
className="object-cover shadow-lg"
/>
<div className="flex flex-col justify-between gap-4">
<div className="space-y-4">
<h1 className="text-2xl font-bold break-keep">{title}</h1>
<DetailsList>
<DetailsList.Item label="작가">{author}</DetailsList.Item>
<DetailsList.Item label="출판사">{publisher}</DetailsList.Item>
<DetailsList.Item label="분류">{category}</DetailsList.Item>
<DetailsList.Item label="대여 상태">
<Badge color={borrowerId ? 'red' : 'green'}>
{borrowerId ? BOOK_STATE.BORROWED : BOOK_STATE.AVAILABLE}
</Badge>
</DetailsList.Item>
</DetailsList>
<Tabs value={SELECT_DEFAULT_OPTION} options={tabsOptions} />
</div>
<Button
className="w-full"
disabled={!!borrowerId}
onClick={() => handleBorrowClick(id)}
>
{borrowerId
? '이미 대여된 도서예요! 조금만 기다려주세요'
: '대여하기'}
</Button>
</div>
</div>
</Grid>
</Section>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Section from '@components/common/Section/Section';
import { Table, Badge } from '@clab/design-system';
import { useBookLoanRecordConditions } from '@hooks/queries';
import { formattedDate } from '@utils/date';
import { TABLE_HEAD } from '@constants/head';

interface BookLoanHistorySectionProps {
bookId: number;
}

const BookLoanHistorySection = ({ bookId }: BookLoanHistorySectionProps) => {
const { data } = useBookLoanRecordConditions({ bookId });

return (
<Section>
<Section.Header title="대여 내역">
최근에 신청된 대여 내역이에요
</Section.Header>
<Section.Body>
<Table head={TABLE_HEAD.BOOK_LOAN_RECORD}>
{data.items.map(({ borrowerId, borrowedAt, returnedAt }, index) => (
<Table.Row key={index}>
<Table.Cell>{borrowerId}</Table.Cell>
<Table.Cell>{formattedDate(borrowedAt)}</Table.Cell>
<Table.Cell>
{returnedAt ? formattedDate(returnedAt) : '예정'}
</Table.Cell>
<Table.Cell>
<Badge color={returnedAt ? 'green' : 'red'}>
{returnedAt ? '반납완료' : '대여중'}
</Badge>
</Table.Cell>
</Table.Row>
))}
</Table>
</Section.Body>
</Section>
);
};

export default BookLoanHistorySection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Section from '@components/common/Section/Section';
import { BookItem } from '@type/book';
import Image from '@components/common/Image/Image';
import { Link } from 'react-router-dom';
import { PATH_FINDER } from '@constants/path';

interface LibraNewBooksSectionProps {
data: BookItem[];
}

const LibraryNewBooksSection = ({ data }: LibraNewBooksSectionProps) => {
return (
<Section>
<Section.Header title="신규 도서">
최근에 들어온 도서들을 확인해보세요
</Section.Header>
<Section.Body className="flex gap-4">
{data.map(({ id, imageUrl, title, author, publisher }) => (
<Link
key={id}
to={PATH_FINDER.BOOK_DETAIL(id)}
className="relative flex flex-col gap-2 transition-transform group hover:scale-110"
>
<div className="overflow-hidden rounded-lg">
<Image src={imageUrl} alt={title} className="object-cover " />
</div>

<div className="absolute inset-0 transition-all rounded-lg opacity-0 pointer-events-none group-hover:opacity-100 bg-gradient-to-t from-black/60 via-black/30" />
<div className="absolute bottom-0 px-2 text-white transition-all opacity-0 group-hover:-translate-y-5 group-hover:opacity-100">
<p className="font-semibold break-keep">{title}</p>
<p className="text-sm">
{author} | {publisher}
</p>
</div>
</Link>
))}
</Section.Body>
</Section>
);
};

export default LibraryNewBooksSection;
Loading

0 comments on commit 927aa2f

Please sign in to comment.