Skip to content
This repository has been archived by the owner on Mar 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request #11 from TheDevLuffy/feature/ZENHUB-3
Browse files Browse the repository at this point in the history
[#3] 장서 관리 페이지 생성
  • Loading branch information
TheDevLuffy authored Mar 1, 2020
2 parents 19ea5e3 + 2f81255 commit 11f5862
Show file tree
Hide file tree
Showing 17 changed files with 309 additions and 36 deletions.
32 changes: 27 additions & 5 deletions pages/books/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
import * as React from "react";
import {useEffect, useState} from "react";
import AppBarContainer from "../../src/components/organisms/containers/AppBarContainer";
import ContentContainer from "../../src/components/organisms/containers/ContentContainer";
import {Card} from "react-bootstrap";
import {useRouter} from "next/router";
import {ILibraryBook} from "../../src/models/interfaces";
import BookRentListCard from "../../src/components/organisms/BookRentListCard";
import BookDetailCard from "../../src/components/organisms/BookDetailCard";

const mockLibraryBook: ILibraryBook = {
id: 8,
title: "개발자의 글쓰기 (변수 네이밍부터 릴리스 노트, 장애 보고서, 기술 블로그까지, 프로그래머의 글쓰기 고민 끝!)",
image: "https://bookthumb-phinf.pstatic.net/cover/155/135/15513595.jpg?type=m1&udate=20191213",
author: "김철수",
publisher: "위키북스",
isbn: "1158391749 9791158391744",
description: "오직 개발자를 위한 글쓰기의 모든 것을 담았습니다!이 책은 개발자의 글쓰기 능력을 종합적으로 향상하기 위한 책이다. 코드 안에서는 함수와 변수... 외주 개발을 하는 개발자를 위해 SI 제안서의 기술 부문을 설득력 있게 쓰는 법도 놓치지 않았다. 블로그를 운영하려는 개발자나 IT기업을 위해 기술 블로그를... ",
hasMany: 1,
};

const Index = () => {
const router = useRouter();

const {id} = router.query;
const [libraryBook, setLibraryBook] = useState();

useEffect(() => {
setLibraryBook(mockLibraryBook)
}, [router]);

const addSerialBtnClickHandler = () => {
console.log('add serial edit')
};

return (
<AppBarContainer isLoggedIn={true}>
<ContentContainer>
<Card>
<Card.Header as="h5">장서 상세 정보</Card.Header>
조회 할 책 id - {id}
</Card>
<BookDetailCard libraryBook={libraryBook}/>
<BookRentListCard bookId={id} onClick={addSerialBtnClickHandler}/>
</ContentContainer>
</AppBarContainer>
);
Expand Down
13 changes: 4 additions & 9 deletions pages/books/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import * as React from "react";
import {useState} from "react";
import AppBarContainer from "../../src/components/organisms/containers/AppBarContainer";
import ContentContainer from "../../src/components/organisms/containers/ContentContainer";
import {Card} from "react-bootstrap";
import {ILibraryBook} from "../../src/models/interfaces";
import Divider from "../../src/components/atoms/Divider";
import {useRouter} from "next/router";
import LibraryBookCardFooter from "../../src/components/organisms/LibraryBookCardFooter";
import LibraryBookCardBody from "../../src/components/organisms/LibraryBookCardBody";
import LibraryBookCardHeader from "../../src/components/molecules/LibraryBookCardHeader";
import BookListCardTemplate from "../../src/components/templates/BookListCardTemplate";

const remoteSearchBooks: ILibraryBook[] = [
{
Expand Down Expand Up @@ -135,15 +132,13 @@ const Index = () => {
const selectBookClickHandler = (id: number) => () => {
router.push(`/books/${id}`);
};

return (
<AppBarContainer isLoggedIn={true}>
<ContentContainer>
<Card>
<LibraryBookCardHeader/>
<BookListCardTemplate title="장서 목록" page={page} onPageDown={onPageDown} onPageUp={onPageUp}>
<LibraryBookCardBody books={books} onClick={selectBookClickHandler}/>
<Divider/>
<LibraryBookCardFooter page={page} onPageDown={onPageDown} onPageUp={onPageUp}/>
</Card>
</BookListCardTemplate>
</ContentContainer>
</AppBarContainer>
);
Expand Down
15 changes: 15 additions & 0 deletions src/components/atoms/BookDetailRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from "react";

interface IProps {
title: string;
children: string;
}

const BookDetailRow = ({title, children}: IProps) => (
<div style={{display: 'flex', flexDirection: 'row', fontSize: '18px', padding: '4px'}}>
<div style={{flex: 2, textAlign: 'center', fontWeight: 'bold'}}>{title}</div>
<div style={{flex: 10}}>{children}</div>
</div>
);

export default BookDetailRow;
12 changes: 12 additions & 0 deletions src/components/atoms/BookRentStatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Badge} from "react-bootstrap";
import * as React from "react";

const BookRentStatusBadge = ({rentStatus}: any) => (
<div style={{fontSize: '24px', lineHeight: '24px'}}>
{rentStatus
? <Badge variant="warning">대여중</Badge>
: <Badge variant="success">비치중</Badge>}
</div>
);

export default BookRentStatusBadge;
26 changes: 26 additions & 0 deletions src/components/molecules/BookDetailCardBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {ILibraryBook} from "../../models/interfaces";
import {Image} from "react-bootstrap";
import BookDetailRow from "../atoms/BookDetailRow";
import * as React from "react";


interface IProps {
libraryBook: ILibraryBook;
}

const BookDetailCardBody = ({libraryBook}: IProps) => (
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flex: 2, minHeight: '250px', maxHeight: '250px'}}>
<Image src={libraryBook ? libraryBook.image : null} fluid style={{width: '100%', height: '100%'}}/>
</div>
<div style={{flex: 9, padding: '12px', display: 'flex', flexDirection: 'column'}}>
<BookDetailRow title="제목">{libraryBook ? libraryBook.title : ''}</BookDetailRow>
<BookDetailRow title="저자">{libraryBook ? libraryBook.author : ''}</BookDetailRow>
<BookDetailRow title="출판사">{libraryBook ? libraryBook.publisher : ''}</BookDetailRow>
<BookDetailRow title="ISBN">{libraryBook ? libraryBook.isbn : ''}</BookDetailRow>
<BookDetailRow title="상세정보">{libraryBook ? libraryBook.description : ''}</BookDetailRow>
</div>
</div>
);

export default BookDetailCardBody;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import {useRouter} from "next/router";
import {Button, Card} from "react-bootstrap";
import * as React from "react";

const LibraryBookCardHeader = () => {
interface IProps {
children: string;
}

const BookListCardHeader = ({children}: IProps) => {
const router = useRouter();

const enrollButtonClickHandler = () => {
Expand All @@ -14,7 +18,7 @@ const LibraryBookCardHeader = () => {
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flex: 13, display: 'flex', flexDirection: 'column', justifyContent: 'center'}}>
<div style={{width: 'fit-content'}}>
장서 목록
{children}
</div>
</div>
<div style={{flex: 1}}>
Expand All @@ -25,4 +29,4 @@ const LibraryBookCardHeader = () => {
);
};

export default LibraryBookCardHeader;
export default BookListCardHeader;
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import LibraryBookPageContext from "../../contexts/LibraryBookPageContext";
import BookListPageContext from "../../contexts/BookListPageContext";
import {Button, ButtonGroup} from "react-bootstrap";
import * as React from "react";

const LibraryBookPageButtons = () => {
const BookListPageButtons = () => {
return (
<LibraryBookPageContext.Consumer>
<BookListPageContext.Consumer>
{({page, onPageDown, onPageUp}) => (
<div style={{height: '40px', display: 'flex', flexDirection: 'row', justifyContent: 'center'}}>
<ButtonGroup aria-label="Basic example">
Expand All @@ -14,8 +14,8 @@ const LibraryBookPageButtons = () => {
</ButtonGroup>
</div>
)}
</LibraryBookPageContext.Consumer>
</BookListPageContext.Consumer>
)
};

export default LibraryBookPageButtons;
export default BookListPageButtons;
32 changes: 32 additions & 0 deletions src/components/molecules/BookRentListCardBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {ISerialInfo} from "../../models/interfaces";
import BookSerialElement from "./BookSerialElement";
import * as React from "react";
import {CSSProperties} from "react";

interface IProps {
serials: ISerialInfo[]
}

const style: CSSProperties = {
display: 'flex',
flexDirection: 'column',
minHeight: '250px',
maxHeight: '350px',
height: 'fill-content',
textAlign: 'center',
overflow: 'scroll'
};

const BookRentListCardBody = ({serials}: IProps) => (
<div style={style}>
{serials.map((serial: ISerialInfo, i: number) => (
<BookSerialElement
key={i}
serialNumber={serial.serialNumber}
rentStatus={serial.rentStatus}
rentUser={serial.rentUser}/>
))}
</div>
);

export default BookRentListCardBody;
45 changes: 45 additions & 0 deletions src/components/molecules/BookSerialElement.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as React from "react";
import BookRentStatusBadge from "../atoms/BookRentStatusBadge";
import {Button} from "react-bootstrap";
import Divider from "../atoms/Divider";
import {CSSProperties} from "react";

interface IProps {
serialNumber: number;
rentStatus: boolean;
rentUser: string;
}

const itemStyle: CSSProperties = {
flex: 1,
padding: '4px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center'
};

const BookSerialElement = ({serialNumber, rentStatus, rentUser}: IProps) => (
<div>
<div style={{height: '50px', display: 'flex', flexDirection: 'row', padding: '4px'}}>
<div style={itemStyle}>
<div>{serialNumber}</div>
</div>
<div style={{flex: 2, padding: '4px', display: 'flex', flexDirection: 'column', justifyContent: 'center'}}>
<BookRentStatusBadge rentStatus={rentStatus}/>
</div>
<div style={itemStyle}>
<div>{rentUser ? rentUser : ''}</div>
</div>
<div style={itemStyle}>
<div style={{display: 'flex', flexDirection: 'row', justifyContent: 'center'}}>
<Button variant="primary" size="sm" style={{width: '71.25px'}} disabled={!rentStatus}>반납 요청</Button>
<div style={{width: '16px'}}/>
<Button variant="primary" size="sm" style={{width: '71.25px'}}>삭제</Button>
</div>
</div>
</div>
<Divider/>
</div>
);

export default BookSerialElement;
25 changes: 25 additions & 0 deletions src/components/molecules/CardButtonHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Button, Card} from "react-bootstrap";
import * as React from "react";

interface IProps {
title: string;
buttonName: string;
buttonOnClick?: any;
disabled?: boolean;
}

const CardButtonHeader = ({title, buttonName, buttonOnClick, disabled}: IProps) => (
<Card.Header as="h5">
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flex: 13, display: 'flex', flexDirection: 'column', justifyContent: 'center'}}>
<div style={{width: 'fit-content'}}>{title}</div>
</div>
<div style={{flex: 1, display: 'flex', flexDirection: 'column'}}>
<Button variant="primary" size="sm" onClick={buttonOnClick}
disabled={disabled ? disabled : false}>{buttonName}</Button>
</div>
</div>
</Card.Header>
);

export default CardButtonHeader;
18 changes: 18 additions & 0 deletions src/components/organisms/BookDetailCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {ILibraryBook} from "../../models/interfaces";
import {Card} from "react-bootstrap";
import CardButtonHeader from "../molecules/CardButtonHeader";
import BookDetailCardBody from "../molecules/BookDetailCardBody";
import * as React from "react";

interface IProps {
libraryBook: ILibraryBook;
}

const BookDetailCard = ({libraryBook}: IProps) => (
<Card>
<CardButtonHeader title="장서 상세 정보" buttonName="정보 수정" disabled={true}/>
<BookDetailCardBody libraryBook={libraryBook}/>
</Card>
);

export default BookDetailCard;
12 changes: 12 additions & 0 deletions src/components/organisms/BookListCardFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import BookListPageContext from "../../contexts/BookListPageContext";
import BookListPageButtons from "../molecules/BookListPageButtons";
import * as React from "react";


const BookListCardFooter = ({page, onPageDown, onPageUp}) => (
<BookListPageContext.Provider value={{page, onPageDown, onPageUp}}>
<BookListPageButtons/>
</BookListPageContext.Provider>
);

export default BookListCardFooter;
48 changes: 48 additions & 0 deletions src/components/organisms/BookRentListCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {Card} from "react-bootstrap";
import CardButtonHeader from "../molecules/CardButtonHeader";
import BookRentListCardBody from "../molecules/BookRentListCardBody";
import * as React from "react";
import {ISerialInfo} from "../../models/interfaces";
import {useState} from "react";
import BookListCardFooter from "./BookListCardFooter";
import Divider from "../atoms/Divider";

interface IProps {
bookId: string | string[];
onClick?: any;
}

const mockSerials: ISerialInfo[] = [
{serialNumber: 1, rentStatus: true, rentUser: '루피'},
{serialNumber: 2, rentStatus: false, rentUser: null},
{serialNumber: 3, rentStatus: true, rentUser: '루피'},
];

const BookRentListCard = ({bookId, onClick}: IProps) => {

const [page, setPage] = useState(1);
const [serials, setSerials] = useState<ISerialInfo[]>(mockSerials);

const onPageDown = () => {
if (page <= 1) {
return;
}
setPage(page - 1);
console.log('on Page Down');
};

const onPageUp = () => {
console.log('on page up');
};

return (
<Card style={{marginTop: '20px'}}>
<CardButtonHeader title="시리얼 정보" buttonName="추가" buttonOnClick={onClick}/>
<BookRentListCardBody serials={serials}/>
<Divider/>
<BookListCardFooter page={page} onPageDown={onPageDown} onPageUp={onPageUp}/>
</Card>
);
};

export default BookRentListCard;
Loading

0 comments on commit 11f5862

Please sign in to comment.