Skip to content

Commit

Permalink
Merge pull request #111 from MoneyMakersClub/feat/#96
Browse files Browse the repository at this point in the history
Feat/#96 | 발췌 및 감상평
  • Loading branch information
yoonjin-C authored Nov 27, 2024
2 parents 5fbb232 + b2337ce commit 854b74e
Show file tree
Hide file tree
Showing 25 changed files with 568 additions and 143 deletions.
6 changes: 3 additions & 3 deletions bookduck/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ function App() {
<Routes>
<Route path="/selectBook" element={<SelectBookPage />} />
<Route path="/archive" element={<ArchivePage />} />
<Route path="/extract-archive-detail" element={<ArchiveDetail />} />
<Route path="/review-archive-detail" element={<ArchiveDetail />} />
<Route path="/total-archive-detail" element={<ArchiveDetail />} />
<Route path="/excerpt-archive-detail/:id" element={<ArchiveDetail />} />
<Route path="/review-archive-detail/:id" element={<ArchiveDetail />} />
<Route path="/total-archive-detail/:id" element={<ArchiveDetail />} />
<Route path="/recording" element={<RecordingPage />} />
<Route path="/recording/decoration" element={<CardDecorationPage />} />

Expand Down
32 changes: 29 additions & 3 deletions bookduck/src/api/archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,43 @@ import { get, post } from "./example";

export const postExtractReview = async (data) => {
try {
const res = await post("/archive", data);
const res = await post("/archives", data);
console.log("발췌 및 감상평 업로드 성공", res);
return res;
} catch (error) {
console.error("발췌 및 감상평 업로드 실패", error);
}
};

export const postExtractImage = async (data) => {
export const getExtractReview = async (userId, archiveType, page, size) => {
try {
const res = await post(`/archives/excerpts/ocr`, data);
const res = await get(
`/users/${userId}/archives?type=${archiveType}&page=${page}&size=${size}`
);
console.log("발췌 및 감상평 조회 성공", res);
return res;
} catch (error) {
console.error("발췌 및 감상평 조회 실패", error);
}
};

export const getDetailExtractReview = async (id, archiveType) => {
try {
const res = await get(`/archives/${id}?type=${archiveType}`);
console.log("발췌 및 감상평 상세 조회 성공", res);
return res;
} catch (error) {
console.error("발췌 및 감상평 상세 조회 실패", error);
}
};

export const postExtractImage = async (formData) => {
try {
const res = await apiAuth.post(`/archives/excerpts/ocr`, formData, {
headers: {
"Content-Type": "multipart/formdata",
},
});
console.log("발췌 이미지 추출 성공", res);
return res;
} catch (error) {
Expand Down
50 changes: 32 additions & 18 deletions bookduck/src/components/LibraryPage/BookListPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const BookListPage = ({ view }) => {
const [statusVisible, setStatusVisible] = useState(false);
const statusArr = ["읽고 싶어요", "읽고 있어요", "다 읽었어요", "중단했어요"];
const [isCancel, setCancel] = useState(true);
const [currentState, setCurrentState] = useState("읽고 싶어요");
const [sortedBookList, setSortedBookList] = useState([]);
const [selectedBookId, setSelectedId] = useState();
const [currentState, setCurrentState] = useState({});

const getSortKey = (sort) => {
switch (sort) {
Expand All @@ -46,20 +46,20 @@ const BookListPage = ({ view }) => {
}
};

// const getReadingStatus = (status) => {
// switch (status) {
// case "NOT_STARTED":
// return "읽고 싶어요";
// case "READING,":
// return "읽고 있어요";
// case "FINISHED":
// return "다 읽었어요";
// case "STOPPED":
// return "중단했어요";
// default:
// return "읽고 싶어요";
// }
// };
const getReadingStatus = (status) => {
switch (status) {
case "NOT_STARTED":
return "읽고 싶어요";
case "READING,":
return "읽고 있어요";
case "FINISHED":
return "다 읽었어요";
case "STOPPED":
return "중단했어요";
default:
return "읽고 싶어요";
}
};

const getReadingStatusKey = (status) => {
switch (status) {
Expand All @@ -85,6 +85,16 @@ const BookListPage = ({ view }) => {
queryFn: () => getTotalBook(getSortKey(sort)),
});

useEffect(() => {
if (bookListData) {
const initialState = bookListData.bookList.reduce((acc, book) => {
acc[book.userBookId] = book.readStatus;
return acc;
}, {});
setCurrentState(initialState);
}
}, [bookListData]);

const handleSortChange = (newSort) => {
setSort(newSort);
setVisible(false);
Expand Down Expand Up @@ -123,6 +133,10 @@ const BookListPage = ({ view }) => {
};

const handleStatusChange = async (status) => {
const initialState = bookListData.bookList.reduce((acc, book) => {
acc[book.userBookId] = book.readStatus;
return acc;
}, {});
setCurrentState(status);
const res = await patchBookStatus(
selectedBookId,
Expand Down Expand Up @@ -168,7 +182,7 @@ const BookListPage = ({ view }) => {
handleStatusClick={() => handleStatusClick(book.userBookId)}
edit={true}
bottomSheet={true}
status={currentState}
status={getReadingStatus(currentState[book.userBookId])}
bookTitle={book.title}
author={book.authors}
bookImg={book.imgPath}
Expand All @@ -178,10 +192,10 @@ const BookListPage = ({ view }) => {
: sortedBookList &&
sortedBookList.map((book) => (
<BookListView
handleStatusClick={handleStatusClick}
handleStatusClick={() => handleStatusClick(book.userBookId)}
edit={true}
bottomSheet={true}
status={currentState}
status={getReadingStatus(currentState[book.userBookId])}
bookTitle={book.title}
author={book.authors}
bookImg={book.imgPath}
Expand Down
127 changes: 127 additions & 0 deletions bookduck/src/components/RecordingPage/ArchiveDetailComponent.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { useState } from "react";
import BottomSheetModal from "../common/BottomSheetModal";
import BottomSheetMenuComponent from "../common/BottomSheetMenuComponent";
import { useParams } from "react-router-dom";
import { getDetailExtractReview } from "../../api/archive";
import { useQuery } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import { getDetailExtractReview } from "../../api/archive";
import heart_gray from "../../assets/recordingPage/heart-gray.svg";
import share_gray from "../../assets/recordingPage/share-gray.svg";
import kakao from "../../assets/recordingPage/kakao.svg";
import instagram from "../../assets/recordingPage/instagram.svg";
import x from "../../assets/recordingPage/x.svg";
import gallery from "../../assets/recordingPage/gallery.svg";
import link from "../../assets/recordingPage/link.svg";

const ArchiveDetailComponent = () => {
const [bottomSheetShow, setBottomSheetShow] = useState(false);
const [visible, setVisible] = useState(false);

const handleCancleClick = () => {
setVisible(false);
setTimeout(() => {
setBottomSheetShow(false);
}, 200);
};

console.log(archiveDetailData);

const formattedDate = (date) => {
return date.split("T")[0].replace(/-/g, ".");
};

const {
data: archiveDetailData,
isError,
error,
} = useQuery({
queryKey: ["archiveDetailData"],
queryFn: () => getDetailExtractReview(id, "EXCERPT"),
});

const typeState =
archiveDetailData.excerpt && archiveDetailData.review
? "ALL"
: archiveDetailData.excerpt
? "EXCERPT"
: "REVIEW";

return (
<div>
<div className="w-[22.5825rem] px-5 py-6 rounded-[0.88rem] bg-gray-10 shadow-custom ">
<div className="flex flex-col gap-5 ">
<div className="flex justify-between">
<div className="text-c1 text-gray-400">
{formattedDate(archiveDetailData.excerpt.createdTime)} (
{archiveDetailData.excerpt.modifiedTime &&
formattedDate(archiveDetailData.excerpt.modifiedTime)}{" "}
수정) /
{archiveDetailData.excerpt.visibility === "PUBLIC"
? "공개"
: "비공개"}
</div>
<div className="text-b2 text-gray-400">
{archiveDetailData.excerpt.pageNumber}p
</div>
</div>
<div className="text-b2 text-gray-800 ">
{archiveDetailData.excerpt.excerptContent}
</div>
<div className=" flex gap-4 justify-end">
<img className="cursor-pointer" src={heart_gray} alt="heart_gray" />
<img
className="cursor-pointer"
src={share_gray}
alt="share_gray"
onClick={() => {
setBottomSheetShow(true);
}}
/>
</div>
</div>
</div>
<BottomSheetModal
bottomSheetShow={bottomSheetShow}
setBottomSheetShow={setBottomSheetShow}
visible={visible}
setVisible={setVisible}
>
<div className="flex flex-col">
<div className="flex justify-between items-center">
<span className="text-st font-semibold">내보내기</span>
<span
className="text-b1 text-gray-500 cursor-pointer"
onClick={handleCancleClick}
>
취소
</span>
</div>
<div className="flex flex-col my-4 px-1">
<BottomSheetMenuComponent
img={kakao}
text="카카오톡"
isExported={true}
/>
<BottomSheetMenuComponent
img={instagram}
text="인스타그램 스토리"
isExported={true}
/>
<BottomSheetMenuComponent img={x} text="X" isExported={true} />
<BottomSheetMenuComponent
img={gallery}
text="이미지 저장"
isExported={true}
/>
<BottomSheetMenuComponent
img={link}
text="URL 복사"
isExported={true}
/>
</div>
</div>
</BottomSheetModal>
</div>
);
};
8 changes: 6 additions & 2 deletions bookduck/src/components/RecordingPage/Archiving.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import { useNavigate } from "react-router-dom";
import BookListView from "../common/BookListView";
import { useQuery } from "@tanstack/react-query";
import { getSortedTotalBook } from "../../api/library";
import useBookInfoStore from "../../store/useBookInfoStore";

const Archiving = () => {
const navigate = useNavigate();
const { setBookInfo } = useBookInfoStore();

const {
data: sortedBookListData = { bookList: [] },
Expand All @@ -15,7 +17,9 @@ const Archiving = () => {
queryFn: () => getSortedTotalBook(["READING"], "latest"),
});

const handleRecording = () => {
const handleRecording = (bookInfo) => {
console.log(bookInfo);
setBookInfo(bookInfo);
navigate("/recording");
};
return (
Expand All @@ -24,7 +28,7 @@ const Archiving = () => {
sortedBookListData.bookList.map((book) => (
<BookListView
edit={false}
handleOnClick={handleRecording}
handleOnClick={() => handleRecording(book)}
bookTitle={book.title}
author={book.authors}
bookImg={book.imgPath}
Expand Down
16 changes: 11 additions & 5 deletions bookduck/src/components/RecordingPage/AuthorComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import img_template from "../../assets/recordingPage/img-template.svg";
const AuthorComponent = () => {
const AuthorComponent = ({ archiveDetailData }) => {
return (
<>
<div className="w-[22.5625rem] px-4 py-[0.62rem] rounded-[0.5rem] bg-gray-50">
<div className="flex gap-[0.88rem]">
<div className="w-[3.0625rem] h-[4.375rem]">
<img src={img_template} alt="img_template" />
<div>
<img
className="w-[3.0625rem] h-[4.375rem]"
src={archiveDetailData.imgPath}
alt="img_template"
/>
</div>
<div className="flex flex-col gap-[0.2rem] justify-center">
<div className="text-b2 text-gray-800 font-semibold">
안녕하세요
{archiveDetailData.title}
</div>
<div className="text-c1 text-gray-500">
{archiveDetailData.author}
</div>
<div className="text-c1 text-gray-500">지은이 / 출판사 / 2024</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 854b74e

Please sign in to comment.