Skip to content

Commit

Permalink
Merge pull request #270 from TeamBookTez/develop
Browse files Browse the repository at this point in the history
v1.1.0 배포
  • Loading branch information
soryeongk authored May 15, 2022
2 parents 6ab3f6e + 9eff785 commit 1166a3d
Show file tree
Hide file tree
Showing 39 changed files with 606 additions and 273 deletions.
4 changes: 0 additions & 4 deletions .husky/pre-commit

This file was deleted.

2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"isdisabled",
"isfilled",
"isopen",
"isqueryempty",
"isrightpath",
"isscroll",
"issingle",
"KAKAO",
"logocolor",
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"typescript": "^4.5.4"
},
"scripts": {
"prepare": "husky install",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
Expand Down Expand Up @@ -68,7 +67,6 @@
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.1.5",
"prettier": "^2.5.1"
}
Expand Down
2 changes: 2 additions & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export { ReactComponent as IcRightArrow } from "./rightArrowIcon.svg";
export { ReactComponent as IcSave } from "./saveIcon.svg";
export { ReactComponent as IcSearch } from "./searchIcon.svg";
export { ReactComponent as IcSight } from "./sightIcon.svg";
export { ReactComponent as IcSignupChecking } from "./signupCheckingIcon.svg";
export { ReactComponent as IcTitleLogo } from "./titleLogoIcon.svg";
export { ReactComponent as IcToastAlert } from "./toastAlertIcon.svg";
export { ReactComponent as IcToBe } from "./toBeIcon.svg";
export { ReactComponent as IcToggle } from "./toggleIcon.svg";
6 changes: 6 additions & 0 deletions src/assets/icons/signupCheckingIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/icons/toastAlertIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions src/components/addBook/AlertToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import styled from "styled-components";

import { IcToastAlert } from "../../assets/icons";
import { StIcCancelWhite } from "../common/styled/NoteModalWrapper";

interface AlertToastProps {
onCloseAlertToast: () => void;
}

export default function AlertToast(props: AlertToastProps) {
const { onCloseAlertToast } = props;

return (
<StSaveWrapper>
<StIconTextWrapper>
<IcToastAlert />
<div>
<StToastH1>이미 추가된 책입니다.</StToastH1>
<StToastSpan>다른 책을 추가해주세요</StToastSpan>
</div>
</StIconTextWrapper>
<StIcCancel onClick={onCloseAlertToast} />
</StSaveWrapper>
);
}

const StSaveWrapper = styled.div`
position: absolute;
top: 6.9rem;
right: 4rem;
z-index: 5;
display: flex;
justify-content: space-between;
align-items: flex-start;
box-shadow: 0.1rem 0.3rem 0.9rem 0.3rem #0000001c;
border-radius: 0.8rem;
padding: 1.3rem 1.9rem;
background-color: ${({ theme }) => theme.colors.white};
width: 38.8rem;
height: 7.9rem;
color: ${({ theme }) => theme.colors.gray200};
`;

const StIconTextWrapper = styled.div`
display: flex;
column-gap: 1.3rem;
`;

const StToastH1 = styled.h1`
margin-bottom: 0.5rem;
${({ theme }) => theme.fonts.body0};
font-weight: 600;
`;

const StToastSpan = styled.span`
${({ theme }) => theme.fonts.h5};
`;

const StIcCancel = styled(StIcCancelWhite)`
position: static;
width: 3.2rem;
height: 3.2rem;
`;
56 changes: 34 additions & 22 deletions src/components/addBook/BookInfoWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import styled from "styled-components";

import { BookInfo } from "../../pages/AddBook";
Expand All @@ -14,26 +14,41 @@ export interface PublishDate {

interface BookInfoWrapperProps {
book: BookInfo;
selectedBookIsbn: string;
onClickBookCard: (isbn: string) => void;
onResetSelectedBookIsbn: () => void;
}

export default function BookInfoWrapper(props: BookInfoWrapperProps) {
const { book } = props;
const { thumbnail, title, authors, datetime, contents } = book;
const [openModal, setOpenModal] = useState<boolean>(false);
const { book, selectedBookIsbn, onClickBookCard, onResetSelectedBookIsbn } = props;
const { isbn, thumbnail, title, authors, datetime, contents } = book;

const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

const publishDate: PublishDate = {
year: datetime.toString().slice(0, 4),
month: datetime.toString().slice(5, 7),
date: datetime.toString().slice(8, 10),
};

const onToggleModal = useCallback(() => {
setOpenModal(!openModal);
}, [openModal]);
const toggleModal = useCallback(() => {
setIsModalOpen(!isModalOpen);
}, [isModalOpen]);

const clickBookCard = () => {
onClickBookCard(book.isbn);
};

useEffect(() => {
if (selectedBookIsbn !== "" && selectedBookIsbn === isbn) {
toggleModal();
onResetSelectedBookIsbn();
}
}, [selectedBookIsbn]);

return (
<>
<StArticle onClick={onToggleModal}>
<StArticle onClick={clickBookCard}>
{thumbnail ? (
<StThumbnail src={thumbnail} alt="책 표지" />
) : (
Expand All @@ -45,28 +60,25 @@ export default function BookInfoWrapper(props: BookInfoWrapperProps) {
<StInfoWrapper>
<InfoTitle>{title}</InfoTitle>
<InfoLabelWrapper>
<InfoLabel>
{authors.length > 2 ? (
<>
{authors[0]}{authors.length - 1}
</>
) : (
<>
{authors[0]} {authors[1]}
</>
)}
</InfoLabel>
<DivideLine></DivideLine>
{authors.length > 0 && (
<>
<InfoLabel>
{authors.length > 2 ? `${authors[0]}${authors.length - 1}명` : `${authors[0]}`}
</InfoLabel>
<DivideLine />
</>
)}
<InfoLabel>
{publishDate.year}{publishDate.month}{publishDate.date}
</InfoLabel>
</InfoLabelWrapper>
<InfoSummary>{escapeHtml(contents)}</InfoSummary>
</StInfoWrapper>
</StArticle>
{openModal && (

{isModalOpen && (
<ModalWrapper>
<ShowModal onToggleModal={onToggleModal} bookInfo={book} publishDate={publishDate} />
<ShowModal onToggleModal={toggleModal} bookInfo={book} publishDate={publishDate} />
</ModalWrapper>
)}
</>
Expand Down
49 changes: 47 additions & 2 deletions src/components/addBook/BookList.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,68 @@
import { useState } from "react";
import styled from "styled-components";

import { BookInfo } from "../../pages/AddBook";
import { checkIsBookExist } from "../../utils/lib/api";
import { useAlertToast } from "../../utils/useHooks";
import AlertToast from "./AlertToast";
import BookEmpty from "./BookEmpty";
import BookInfoWrapper from "./BookInfoWrapper";

interface BookListProps {
isLogin: boolean;
books: BookInfo[];
}

export default function BookList(props: BookListProps) {
const { books } = props;
const { isLogin, books } = props;

// default is false
const [alertToastOpen, setAlertToastOpen] = useState<boolean>(false);
const [selectedBookIsbn, setSelectedBookIsbn] = useState<string>("");

const closeAlertToast = () => {
setAlertToastOpen(false);
};

const resetSelectedBookIsbn = () => {
setSelectedBookIsbn("");
};

const handleClickBookCard = (isbn: string) => {
if (!isLogin) {
setSelectedBookIsbn(isbn);
} else {
checkIsBookExist(isbn).then((result) => {
if (result.isError) {
// 에러 토스트 띄우기 - 모종의 이유로 실패한 경우
return;
} else if (result.isExist) {
// 통신에 성공 - 책이 중복된 경우
setAlertToastOpen(true);
} else {
// 모든 상황을 통과
setSelectedBookIsbn(isbn);
}
});
}
};

useAlertToast(alertToastOpen, () => setAlertToastOpen(false));

if (books.length === 0) return <BookEmpty />;

return (
<StListWrapper>
{books.map((book: BookInfo, idx: number) => (
<BookInfoWrapper key={idx} book={book} />
<BookInfoWrapper
key={idx}
book={book}
selectedBookIsbn={selectedBookIsbn}
onClickBookCard={handleClickBookCard}
onResetSelectedBookIsbn={resetSelectedBookIsbn}
/>
))}
{alertToastOpen ? <AlertToast onCloseAlertToast={closeAlertToast} /> : null}
</StListWrapper>
);
}
Expand Down
35 changes: 2 additions & 33 deletions src/components/addBook/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useViewportScroll } from "framer-motion";
import { useEffect, useState } from "react";
import styled, { css } from "styled-components";

import { IcCancel, IcSearch } from "../../assets/icons";
Expand All @@ -11,23 +9,6 @@ interface SearchBarProps {
}
export default function SearchBar(props: SearchBarProps) {
const { debounceQuery, onDebounceQuery } = props;
const { scrollY } = useViewportScroll();
const [isScroll, setIsScroll] = useState<boolean>(false);
const MAIN_HEADER_HEIGHT = 109;

useEffect(() => {
scrollY.onChange(() => {
if (scrollY.get() > MAIN_HEADER_HEIGHT) {
setIsScroll(true);
} else {
setIsScroll(false);
}
});

return () => {
scrollY.clearListeners();
};
}, [scrollY]);

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const text = e.currentTarget.value;
Expand All @@ -40,7 +21,7 @@ export default function SearchBar(props: SearchBarProps) {
};

return (
<StWrapper isscroll={isScroll}>
<StWrapper>
<SearchBarWrapper isqueryempty={debounceQuery}>
<StIcSearch isqueryempty={debounceQuery} />

Expand All @@ -58,23 +39,11 @@ export default function SearchBar(props: SearchBarProps) {
);
}

const StWrapper = styled.section<{ isscroll: boolean }>`
position: sticky;
top: 0;
const StWrapper = styled.section`
padding-top: 3.1rem;
padding-bottom: 3.5rem;
background-color: ${({ theme }) => theme.colors.white};
${({ isscroll }) =>
isscroll
? css`
box-shadow: 0rem 0.6rem 1rem rgba(0, 0, 0, 0.17);
`
: css`
box-shadow: 0;
`}
`;

const SearchBarWrapper = styled.div<{ isqueryempty: string }>`
Expand Down
1 change: 1 addition & 0 deletions src/components/addBook/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as AddBookDefault } from "./AddBookDefault";
export { default as AlertToast } from "./AlertToast";
export { default as BookEmpty } from "./BookEmpty";
export { default as BookInfoWrapper } from "./BookInfoWrapper";
export { default as BookList } from "./BookList";
Expand Down
Loading

0 comments on commit 1166a3d

Please sign in to comment.