Skip to content

Commit

Permalink
Merge pull request #114 from KGU-C-Lab/refactor/#112
Browse files Browse the repository at this point in the history
도서관 API 변경에 따른 리펙토링 완료
  • Loading branch information
gwansikk authored Apr 26, 2024
2 parents c15aa7b + 7fcafe3 commit 83e0d5f
Show file tree
Hide file tree
Showing 28 changed files with 393 additions and 187 deletions.
78 changes: 40 additions & 38 deletions apps/member/src/api/book.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { END_POINT } from '@constants/api';
import { createCommonPagination } from '@utils/api';
import { createCommonPagination, createPath } from '@utils/api';

import type {
BaseResponse,
PaginationPramsType,
PaginationType,
WithPaginationPrams,
} from '@type/api';
Expand All @@ -15,92 +14,87 @@ import type {

import { server } from './server';

export interface BorrowerBookInfo {
export interface BookLoanRequestData {
bookId: number;
borrowerId: string;
}

export interface GetBookLoanRecordConditionsPrams extends PaginationPramsType {
export interface BookLoanRecordSearchOptions extends WithPaginationPrams {
bookId?: number;
borrowerId?: string;
isReturned?: boolean;
}
/**
* 도서 목록 조회
*/
export const getBooks = async (page: number, size: number) => {
const params = { page, size };
export async function getBooks(page: number, size: number) {
const { data } = await server.get<PaginationType<BookItem>>({
url: createCommonPagination(END_POINT.BOOK, params),
url: createCommonPagination(END_POINT.BOOK, { page, size }),
});

return data;
};
}
/**
* 도서 상세 조회
*/
export const getBookDetail = async (id: number) => {
export async function getBookDetail(id: number) {
const { data } = await server.get<BaseResponse<BookItem>>({
url: END_POINT.BOOK_DETAIL(id),
});

return data;
};
}
/**
* 나의 대출내역 조회
*/
export const getMyBooks = async (id: string, page: number, size: number) => {
const params = { page, size };
export async function getMyBooks(id: string, page: number, size: number) {
const { data } = await server.get<PaginationType<BookItem>>({
url: createCommonPagination(END_POINT.BOOK, params),
url: createCommonPagination(END_POINT.BOOK, { page, size }),
});

return data.items.filter((book) => book.borrowerId === id);
};
}
/**
* 도서 대출
*/
export const postBorrowBook = async (body: BorrowerBookInfo) => {
const borrowUrl = END_POINT.BOOK_LOAN_BORROW;
const { data } = await server.post<BorrowerBookInfo, BaseResponse<number>>({
url: borrowUrl,
export async function postBorrowBook(body: BookLoanRequestData) {
return server.post<BookLoanRequestData, BaseResponse<number>>({
url: END_POINT.BOOK_LOAN_BORROW,
body,
});

return data;
};
}
/**
* 도서 반납
*/
export const postReturnBook = async (body: BorrowerBookInfo) => {
const { data } = await server.post<BorrowerBookInfo, BaseResponse<number>>({
url: END_POINT.BOOK_LOAN_RETURN,
body,
});
export async function postReturnBook(body: BookLoanRequestData) {
const { data } = await server.post<BookLoanRequestData, BaseResponse<number>>(
{
url: END_POINT.BOOK_LOAN_RETURN,
body,
},
);

return data;
};
}
/**
* 도서 연장
*/
export const postExtendBook = async (body: BorrowerBookInfo) => {
const { data } = await server.post<BorrowerBookInfo, BaseResponse<number>>({
export function postExtendBook(body: BookLoanRequestData) {
return server.post<BookLoanRequestData, BaseResponse<number>>({
url: END_POINT.BOOK_LOAN_EXTEND,
body,
});

return data;
};
}
/**
* 도서 대출 내역 조회
*/
export const getBookLoanRecordConditions = async ({
export async function getBookLoanRecordConditions({
bookId,
borrowerId,
isReturned,
page = 0,
size = 20,
}: GetBookLoanRecordConditionsPrams) => {
}: BookLoanRecordSearchOptions) {
const { data } = await server.get<
PaginationType<BookLoanRecordConditionType>
>({
Expand All @@ -114,14 +108,14 @@ export const getBookLoanRecordConditions = async ({
});

return data;
};
}
/**
* 도서 연체자 조회
*/
export const getBookLoanRecordOverdue = async ({
export async function getBookLoanRecordOverdue({
page,
size,
}: WithPaginationPrams) => {
}: WithPaginationPrams) {
const { data } = await server.get<
PaginationType<BookLoanRecordOverDueResponse>
>({
Expand All @@ -132,4 +126,12 @@ export const getBookLoanRecordOverdue = async ({
});

return data;
};
}
/**
* 도서 대출 승인
*/
export function patchBookLoanRecordApprove(id: number) {
return server.patch<null, BaseResponse<number>>({
url: createPath(END_POINT.BOOK_LOAN_RECORD_APPROVE, id),
});
}
13 changes: 9 additions & 4 deletions apps/member/src/components/common/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { Fragment } from 'react';
import { GrNext } from 'react-icons/gr';
import { Link } from 'react-router-dom';

interface HeaderProps {
title: string | string[];
path?: string | string[];
children?: React.ReactNode;
}

const Header = ({ title, children }: HeaderProps) => {
const Header = ({ title, path, children }: HeaderProps) => {
const RenderTitle = () => {
if (Array.isArray(title)) {
// 배열일 경우, 제목이 여러 개일 경우
return (
<div className="flex items-center text-xl font-bold">
{title.map((name, index) => (
<Fragment key={index}>
<span className="cursor-pointer rounded-lg px-2 transition-colors hover:bg-gray-100">
<Fragment key={name}>
<Link
to={path?.[index] || ''}
className="rounded-lg px-2 transition-colors hover:bg-gray-100"
>
{name}
</span>
</Link>
{index !== title.length - 1 && <GrNext />}
</Fragment>
))}
Expand Down
54 changes: 26 additions & 28 deletions apps/member/src/components/common/Image/Image.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,57 @@
import { SyntheticEvent, useState } from 'react';
import { ComponentPropsWithRef, SyntheticEvent, useState } from 'react';

import { NOT_FOUND_IMG } from '@constants/path';
import classNames from 'classnames';
import { cn } from '@utils/string';

interface ImageProps {
src?: string;
alt: string;
interface ImageProps extends ComponentPropsWithRef<'img'> {
width?: string;
height?: string;
className?: string;
onClick?: () => void;
overflow?: boolean;
}

type Status = 'loading' | 'error' | 'loaded';

const Image = ({
src,
alt,
width,
height,
src,
overflow,
className,
onClick,
overflow,
...rest
}: ImageProps) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);

if (!src) src = NOT_FOUND_IMG;
const [status, setStatus] = useState<Status>('loading');

const _width = width ? width : 'w-full';
const _height = height ? height : 'h-full';
const _width = width ?? 'w-full';
const _height = height ?? 'h-full';

const handleError = (e: SyntheticEvent<HTMLImageElement>) => {
e.currentTarget.src = NOT_FOUND_IMG;
setError(true);
setLoading(false);
setStatus('error');
};

return (
<div
className={classNames(_width, _height, {
className={cn(_width, _height, {
'overflow-hidden': overflow,
})}
onClick={onClick}
>
<img
className={classNames('h-full w-full', className, {
'animate-pulse bg-gray-200': loading,
'bg-gray-50': error,
'cursor-pointer': onClick,
})}
src={src}
alt={alt}
onClick={onClick}
onLoad={() => setLoading(false)}
className={cn(
{
'animate-pulse bg-gray-200': status === 'loading',
'bg-gray-50': status === 'error',
},
_width,
_height,
className,
)}
src={src ?? NOT_FOUND_IMG}
onLoad={() => setStatus('loaded')}
onError={handleError}
loading="lazy"
{...rest}
/>
</div>
);
Expand Down
18 changes: 8 additions & 10 deletions apps/member/src/components/common/Nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ const Nav = () => {
const navigate = useNavigate();
const { openModal } = useModal();

const isSelected = (path: string) => {
return location.pathname.endsWith(path);
};
const pathName = location.pathname;

const handleMenubarItemClick = useCallback(
(path: string) => {
Expand All @@ -40,44 +38,44 @@ const Nav = () => {
</Link>
<Menubar gap="xl" className="text-sm">
<MenubarItem
selected={isSelected(PATH.MAIN)}
selected={pathName === PATH.MAIN}
onClick={() => handleMenubarItemClick(PATH.MAIN)}
>
</MenubarItem>
<MenubarItem
selected={isSelected(PATH.CALENDER)}
selected={pathName.startsWith(PATH.CALENDER)}
onClick={() => handleMenubarItemClick(PATH.CALENDER)}
>
일정
</MenubarItem>
<MenubarItem
selected={isSelected(PATH.ACTIVITY)}
selected={pathName.startsWith(PATH.ACTIVITY)}
onClick={() => handleMenubarItemClick(PATH.ACTIVITY)}
>
활동
</MenubarItem>
<MenubarItem
selected={isSelected(PATH.COMMUNITY)}
selected={pathName.startsWith(PATH.COMMUNITY)}
onClick={() => handleMenubarItemClick(PATH.COMMUNITY)}
>
커뮤니티
</MenubarItem>
<MenubarItem
selected={isSelected(PATH.LIBRARY)}
selected={pathName.startsWith(PATH.LIBRARY)}
onClick={() => handleMenubarItemClick(PATH.LIBRARY)}
>
도서관
</MenubarItem>
<MenubarItem
selected={isSelected(PATH.SUPPORT)}
selected={pathName.startsWith(PATH.SUPPORT)}
onClick={() => handleMenubarItemClick(PATH.SUPPORT)}
>
회비
</MenubarItem>
{MODE !== 'production' && (
<MenubarItem
selected={isSelected(PATH.MANAGE)}
selected={pathName.startsWith(PATH.MANAGE)}
onClick={() => handleMenubarItemClick(PATH.MANAGE)}
>
관리
Expand Down
Loading

0 comments on commit 83e0d5f

Please sign in to comment.