Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 사서 대출권수 변경 #620

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2a1079f
WIP
hyeunkim42 Sep 14, 2024
6655d5e
wip: Rending Confirm에서 사서가 자신의 책을 대출할 때 4권까지 대출 허용
hyeunkim42 Sep 14, 2024
426c95f
fix: 책을 2권 초과하여 선택하는 경우 삭제 대상만 리스트에 남아있는 버그 수정
hyeunkim42 Sep 19, 2024
1c10729
wip: 임시로 4권 선택 가능하도록 수정해둔 상태
hyeunkim42 Sep 19, 2024
6ea9ec7
fix: 사서인지 확인하는 변수를 prop이 아닌 userAtom으로 판단하도록 변경
hyeunkim42 Sep 19, 2024
afbbcbe
fix: 사서 본인의 대출인지 확인하는 방식을 prop에서 Atom으로 변경
hyeunkim42 Sep 19, 2024
b612710
feat: 대출 유저 선택 후, 사서라면 사서 표시 추가
mixsung Sep 20, 2024
0b344a3
feat: 사서 본인의 대출 시, 4권까지 가능하도록 lendingLimit 설정
mixsung Sep 20, 2024
a24613f
feat: 사서 본인의 대출에 따라 바뀌는 대출현황(/2권 -> /4권)
mixsung Sep 20, 2024
8e0e2ee
refactor: 대출확인모달의 선택 도서 간 경계 및 비고란 명확한 표시 추가
mixsung Sep 20, 2024
db632ed
fix: penalty 표시에 괄호 안닫히던 bug 수정
hyeunkim42 Sep 20, 2024
e56f1ff
fix: 책 비고 작성시 2~4번째 책 비고란 묶여있던 거 각각 작성되도록 수정
hyeunkim42 Sep 21, 2024
5de1deb
fix: 이전 커밋 적용 된 뒤 "대출하기" 버튼 안눌리던 현상 수정
hyeunkim42 Sep 21, 2024
314ccc3
fix: 유저의 role을 enum으로 변경 후 적용
mixsung Sep 23, 2024
ed99a11
fix: Rent 비즈니스 로직 변경(대출권수)을 JSDoc으로 명시
mixsung Sep 23, 2024
702403f
fix: lendingLimit 함수화 및 constant 적용
mixsung Sep 23, 2024
c53f6fe
fix: 변수 이름 수정, lending limit 함수 사용
hyeunkim42 Sep 23, 2024
bd2e37b
fix: lendingLimit 함수화 적용
mixsung Sep 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10,518 changes: 10,518 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/asset/css/BookInformationWithCover.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.book-info__wrapper {
display: flex;
min-width: 3rem;
border: 0.1rem solid #a4a4a4;
border-radius: 1rem;
padding: 1rem;
margin: 1rem;
}

.book-info__cover {
Expand Down Expand Up @@ -33,4 +37,4 @@
width: 100%;
height: auto;
}
}
}
12 changes: 11 additions & 1 deletion src/asset/css/RentInquireBoxBook.css
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@
text-overflow: ellipsis;
}

.rent__inquire-box-user__role {
align-items: center;
justify-content: center;
border: 0.3rem solid #545454;
border-radius: 1rem;
padding: 0.2rem 0.5rem;
background-color: #545454;
margin-right: 0.6rem;
}

.book__info__factor {
margin-right: 4rem;
overflow: hidden;
Expand Down Expand Up @@ -185,4 +195,4 @@
.rent__inquire-box-book__add-button {
height: 8rem;
}
}
}
7 changes: 6 additions & 1 deletion src/asset/css/TextareaWithLabel.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@
box-sizing: border-box;
height: 10rem;
display: block;
background-color: #f2f2f2;
padding: 1rem;
border-radius: 1rem;
}

@media screen and (max-width: 767px) {
.textarea__wrapper {
font-size: 1.4rem;
}

.textarea__label {
margin: 0.4rem 0;
}

.textarea__textarea {
height: 5rem;
}
}
}
27 changes: 16 additions & 11 deletions src/component/rent/Rent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@ import RentModalConfirm from "./RentModalConfirm";
import LoginIcon from "../../asset/img/login_icon_white.svg";
import BookIcon from "../../asset/img/admin_icon.svg";
import "../../asset/css/Rent.css";
import { useRecoilValue } from "recoil";
import { userAtom } from "~/atom/userAtom";

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/**
* `Rent` 컴포넌트는 도서 대출 기능을 제공하는 페이지입니다.
* @description
*
* 유의점:
* - 사서의 대출권수 4권으로 설정. 사서 본인의 대출건만 4권으로 적용
*
* 상태:
* - `selectedUser`: 대출해줄 사용자 정보
* - `selectedBooks`: 대출해줄 도서 목록
*
* :
* - `useModal`: 모달 열기 닫기 기능 제공
* - `useRecoilValue`: Recoil 상태 관리 라이브러리에서 현재 사용자 정보 가져오기
*
* @returns {JSX.Element} 도서 대출 페이지를 렌더링하는 JSX 요소
*/

JSDoc을 통해 다른 파일에서도 비지니스 로직(사서만 4권)을 확인할 수 있도록 수정하면 유지보수하기 용이할 듯 합니다.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영했습니다!

const Rent = () => {
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [selectedBooks, setSelectedBooks] = useState<Book[]>([]);

const { Modal, setOpen: openModal, setClose: closeModal } = useModal();
const user = useRecoilValue(userAtom);
// 사서의 대출권수 4권으로 설정. 사서 본인의 대출건만 4권으로 적용
const lendingLimit = (user.isAdmin && user.id === selectedUser?.id) ? 4 : 2;

return (
<main>
Expand All @@ -42,18 +47,18 @@ const Rent = () => {
/>
{selectedBooks.length > 0
? selectedBooks.map((book, index) => (
<RentInquireBoxBook
key={book.bookId}
book={book}
shape={
selectedBooks.length === 2 && index === 0 ? "none" : "two"
}
selectedBooks={selectedBooks}
setSelectedBooks={setSelectedBooks}
/>
))
<RentInquireBoxBook
key={book.bookId}
book={book}
shape={
(selectedBooks.length - index) === 1 ? "two" : "none"
}
selectedBooks={selectedBooks}
setSelectedBooks={setSelectedBooks}
/>
))
: null}
{selectedBooks.length < 2 ? (
{selectedBooks.length < lendingLimit ? (
<RentInquireBoxBook
book={null}
shape={selectedBooks.length === 0 ? "two" : "four"}
Expand Down
23 changes: 17 additions & 6 deletions src/component/rent/RentConfirm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Book, User } from "../../type";
import { useRecoilValue } from "recoil";
import { userAtom } from "~/atom/userAtom";
import "../../asset/css/RentConfirm.css";

type Props = {
Expand All @@ -8,21 +10,30 @@ type Props = {
};

const RentConfirm = ({ selectedUser, selectedBooks, openModal }: Props) => {
const librarian = useRecoilValue(userAtom);

const lendingLimit = (librarian && librarian.id === selectedUser?.id ? 4 : 2) - (selectedUser?.lendings.length || 0);

const isLendable =
selectedUser &&
!selectedUser.isPenalty &&
selectedBooks.length > 0 &&
2 - selectedUser.lendings.length >= selectedBooks.length;
lendingLimit >= selectedBooks.length;
return (
<section className="rent__confirm-button">
<div className="rent__confirm-button__text font-16 color-a4">
{selectedUser && selectedBooks.length > 0
? `${
? (
`${
selectedUser.nickname ? selectedUser.nickname : selectedUser.email
}님에게 ${selectedBooks[0].title}${
selectedBooks[1] ? `, ${selectedBooks[1].title}` : ``
}를 대출합니다.`
: "정보를 입력해주세요."}
}님에게 ${selectedBooks.map((book, idx) => {
if (idx !== 0)
return (' ' + book.title)
else
return (book.title)
})}
를 대출합니다.`
): "정보를 입력해주세요."}
</div>
<button
className={`rent__confirm-button__button ${
Expand Down
2 changes: 1 addition & 1 deletion src/component/rent/RentInquireBoxBook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const InquireBoxBook = ({
const deleteBook = () => {
if (setSelectedBooks && book) {
setSelectedBooks(
selectedBooks.splice(1 - selectedBooks.indexOf(book), 1),
selectedBooks.filter(selectedBook => selectedBook !== book),
);
}
};
Expand Down
33 changes: 19 additions & 14 deletions src/component/rent/RentInquireBoxUser.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useModal } from "../../hook/useModal";
import { dateFormat } from "../../util/date";
import { User } from "../../type";
import { useRecoilValue } from "recoil";
import { userAtom } from "~/atom/userAtom";
import RentModalUser from "./RentModalUser";
import Image from "../utils/Image";
import DeleteButton from "../../asset/img/x_button.svg";
Expand All @@ -14,6 +16,8 @@ type Props = {
const InquireBoxUser = ({ selectedUser, setSelectedUser }: Props) => {
const { setOpen, setClose, Modal } = useModal();

const librarian = useRecoilValue(userAtom);

const deleteUser = () => {
if (setSelectedUser) {
setSelectedUser(null);
Expand All @@ -22,18 +26,19 @@ const InquireBoxUser = ({ selectedUser, setSelectedUser }: Props) => {

const displayPenalty = () => {
if (!selectedUser) return "";

let penalty = "";
if (
new Date(selectedUser.penaltyEndDate).setHours(0, 0, 0, 0) >=
new Date().setHours(0, 0, 0, 0) ||
selectedUser.overDueDay > 0
)
penalty += "대출제한 (연체";
if (selectedUser.lendings.length >= 2) {
if (penalty !== "") penalty += ", 2권 이상 대출";
else penalty += "대출제한 (2권 이상 대출";
selectedUser.isPenalty && (penalty += "대출제한 (연체");

// 제한 권수 판단
const lendingLimit = librarian && librarian.id === selectedUser.id ? 4 : 2;
Copy link
Member

@YeonSeong-Lee YeonSeong-Lee Sep 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

34번 라인같은 코드가 많이 보이는데 함수도 빼면 가독성이 더 좋을거 같아요. util함수 같은 느낌으로다가 constant 폴더에 넣으면 적합하다고 생각합니다.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constant의 status.js에 함수화 시켜서 넣어봤습니다. 해당 함수에 객체를 인자로 넘기는데, 객체의 요소(isAdmin이나 id)가 undefined 같은 빈 값으로 들어오는 것도 고려해야 좋은지 고민이 됩니다.


if (selectedUser.lendings.length >= lendingLimit) {
if (selectedUser.isPenalty)penalty += `, ${lendingLimit}권 이상 대출`;
else penalty += `대출제한 (${lendingLimit}권 이상 대출`;
}
if (penalty !== "") penalty += ")";
if (selectedUser.isPenalty || selectedUser.lendings.length >= lendingLimit)
penalty += ")";
return penalty;
};

Expand All @@ -47,7 +52,8 @@ const InquireBoxUser = ({ selectedUser, setSelectedUser }: Props) => {
? selectedUser.nickname
: selectedUser.email}
</div>
<div className="font-16 color-red"> {displayPenalty()} </div>
{selectedUser.role === 2 ? <div className="rent__inquire-box-user__role color-ff font-16-bold">사서</div> : null}
<div className="font-16 color-red">{displayPenalty()}</div>
<button
className="rent__inquire-box-user__undo-button color-a4"
type="button"
Expand Down Expand Up @@ -84,9 +90,8 @@ const InquireBoxUser = ({ selectedUser, setSelectedUser }: Props) => {
{`${index + 1}. ${item.title}`}
</div>
<div className="user__book-info__description color-54">
<span>{`예약순위 : ${
item.ranking ? `${item.ranking}순위` : "-"
}`}</span>
<span>{`예약순위 : ${item.ranking ? `${item.ranking}순위` : "-"
}`}</span>
{item.endAt ? (
<span className="user__reservations-info">
예약 혜택 종료일 : {item.endAt}
Expand Down
30 changes: 17 additions & 13 deletions src/component/rent/RentModalConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ const RentModalConfirm = ({
setSelectedBooks,
closeModal,
}: Props) => {
const [first, setFirst] = useState("");
const [second, setSecond] = useState("");
const [remarks, setRemarks] = useState<string[]>([]);

const { requestLending } = usePostLendingsMultiple({
selectedBooks,
Expand All @@ -35,12 +34,19 @@ const RentModalConfirm = ({

const postData: FormEventHandler = e => {
e.preventDefault();
requestLending([first, second]);
requestLending(remarks);
};

const isRentable =
selectedBooks.length > 1
? first.length > 0 && second.length > 0
: first.length > 0;
? remarks.slice(0, selectedBooks.length).every(remark => remark.length > 0)
: remarks[0]?.length > 0;

const handleRemarkChange = (index: number, value: string) => {
const updatedRemarks = [...remarks];
updatedRemarks[index] = value;
setRemarks(updatedRemarks);
};

return (
<form className="rent-modal">
Expand All @@ -53,7 +59,7 @@ const RentModalConfirm = ({
? selectedUser.nickname
: selectedUser.email}
</p>
<p className="font-16 color-54">{`현재 대출권수 ( ${selectedUser.lendings.length} / 2 )`}</p>
<p className="font-16 color-54">{`현재 대출권수 ( ${selectedUser.lendings.length} / ${selectedUser.role === 2 ? '4' : '2'} )`}</p>
mixsung marked this conversation as resolved.
Show resolved Hide resolved
</div>
)}
</div>
Expand All @@ -64,7 +70,7 @@ const RentModalConfirm = ({
return (
<div
key={selectBook.bookId}
className={`rent-modal__book-info ${isFirst && "second-book"}`}
className={`rent-modal__book-info ${index}`}
>
<BookInformationWithCover
bookCoverAlt={selectBook.title}
Expand All @@ -80,12 +86,10 @@ const RentModalConfirm = ({
wrapperClassName="rent-modal__remark"
topLabelText="비고"
textareaPlaceHolder="비고를 입력해주세요. (책 상태 등)"
textareaValue={isFirst ? first : second}
setTextareaValue={isFirst ? setFirst : setSecond}
isTextareaFocusedOnMount={isFirst}
isVisibleBottomMessage={
isFirst ? !first.length : !second.length
}
textareaValue={remarks[index]}
setTextareaValue={(value:string)=>handleRemarkChange(index, value)}
isTextareaFocusedOnMount={index===0}
isVisibleBottomMessage={!remarks[index]?.length}
bottomMessageText="비고를 입력해주세요"
bottomMessageColor="red"
/>
Expand Down
36 changes: 26 additions & 10 deletions src/component/rent/RentModalUserList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { User } from "../../type";
import "../../asset/css/RentModalUserList.css";
import { useRecoilValue } from "recoil";
import { userAtom } from "~/atom/userAtom";

type Props = {
setSelectedUser: (user: User) => void;
Expand All @@ -8,24 +10,38 @@ type Props = {
};

const UserList = ({ user, setSelectedUser, closeModal }: Props) => {

const librarian = useRecoilValue(userAtom);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const librarian = useRecoilValue(userAtom);
const currentUser= useRecoilValue(userAtom);

librarian 는 사서유저를 뜻하는데, 맥락상 사서유저보다는 현재유저가 더 적합한거 같습니다.

librarian으로 하는 특별한 이유가 있나요?!


const isOverDue = (selectedUser: User) => {
if (
new Date(selectedUser.penaltyEndDate).setHours(0, 0, 0, 0) >=
new Date().setHours(0, 0, 0, 0) ||
selectedUser.overDueDay > 0
) return true;
else return false;
}

const seletUser = () => {
user.isPenalty = isOverDue(user) ? true : false;
setSelectedUser(user);
closeModal();
};

const displayPenalty = () => {
let penalty = "";
if (
new Date(user.penaltyEndDate).setHours(0, 0, 0, 0) >=
new Date().setHours(0, 0, 0, 0) ||
user.overDueDay > 0
)
penalty += "대출 불가 (연체";
if (user.lendings.length >= 2) {
if (penalty !== "") penalty += ", 2권 이상 대출";
else penalty += "대출 불가 (2권 이상 대출";
user.isPenalty && (penalty += "대출 불가 (연체");

const lendingLimit = librarian.id === user.id ? 4 : 2;

if (user.lendings.length >= lendingLimit) {
if (user.isPenalty) penalty += `, ${lendingLimit}권 이상 대출`;
else penalty += `대출 불가 (${lendingLimit}권 이상 대출`;
}
if (penalty !== "") penalty += ")";

if (user.isPenalty || user.lendings.length >= lendingLimit)
penalty += ")";

return penalty;
};

Expand Down
Loading
Loading