+
+
-
-
-
-
-
+ {Array.from({ length: 5 }, (_, index) => {
+ let starSrc = starNo;
+ if (data?.rating > index) {
+ starSrc = data?.rating >= index + 1 ? starYes : starHalf;
+ }
+ return
;
+ })}
+
+ {data?.oneLineContent}
+
+
+
+ {userId === data.userId ? (
+ 나의 한줄평
+ ) : (
+
+ {data?.userNickname}
+
+ )}
+ {formattedDate}
+
+
+
handleLikeClick(data.oneLineId)}
+ />
+
+ {likeCount}
+
-
유저 닉네임
- 타유저가 작성한 한줄평이 들어갈 자리입니다.
);
};
diff --git a/bookduck/src/components/CharacterPage/LevelModal.jsx b/bookduck/src/components/CharacterPage/LevelModal.jsx
new file mode 100644
index 0000000..4629d78
--- /dev/null
+++ b/bookduck/src/components/CharacterPage/LevelModal.jsx
@@ -0,0 +1,30 @@
+const LevelModal = ({ onClick }) => {
+ return (
+
+
+
+
+ 레벨업을 위한 팁!
+
+
+ 1. 독서기록 작성하기
+ 2. 별점과 한줄평 꼭 남기기
+ 3. 완독 후 ‘다 읽었어요’로 저장하기
+
+
+ 💡 레벨업 팁을 참고하여 경험치를 쌓아보세요!
+
+
+
+
+
+
+
+ );
+};
+export default LevelModal;
diff --git a/bookduck/src/components/CharacterPage/UserDuck.jsx b/bookduck/src/components/CharacterPage/UserDuck.jsx
index 9d2a7a1..e527281 100644
--- a/bookduck/src/components/CharacterPage/UserDuck.jsx
+++ b/bookduck/src/components/CharacterPage/UserDuck.jsx
@@ -4,12 +4,20 @@ import { useLoader } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
+// 기본 오리캐릭터 불러오기
const DuckModel = () => {
const gltf = useLoader(GLTFLoader, "/assets/characterPage/duck.glb");
-
return
;
};
+// 아이템 목록 불러오기
+const HairBand = () => {
+ const gltf = useLoader(GLTFLoader, "/assets/items/hairband.glb");
+ return (
+
+ );
+};
+
const UserDuck = () => {
return (
@@ -17,6 +25,7 @@ const UserDuck = () => {
+ {/*
*/}
{
+ return (
+
+
+
+ 여덟글자잖아요오님은
+
+ 문학에 진심인 문학덕!
+
+
+
+
+
+ #슬픈 #아름다운 #귀여운
+
+
+ );
+};
+export default ExportCharacter;
diff --git a/bookduck/src/components/StatisticsPage/MonthlyReading.jsx b/bookduck/src/components/StatisticsPage/MonthlyReading.jsx
index 2e467bf..c0e2ac6 100644
--- a/bookduck/src/components/StatisticsPage/MonthlyReading.jsx
+++ b/bookduck/src/components/StatisticsPage/MonthlyReading.jsx
@@ -1,11 +1,12 @@
import StatisticsHeader from "./StatisticsHeader";
import BookRecord from "./BookRecord";
-const MonthlyReading = () => {
+const MonthlyReading = ({ userData }) => {
return (
- {/* 하반기도 만들어야함 */}
-
+
@@ -14,14 +15,25 @@ const MonthlyReading = () => {
-
- 1월
- 2월
- 3월
- 4월
- 5월
- 6월
-
+ {userData.isFirstHalf ? (
+
+ 1월
+ 2월
+ 3월
+ 4월
+ 5월
+ 6월
+
+ ) : (
+
+ 7월
+ 8월
+ 9월
+ 10월
+ 11월
+ 12월
+
+ )}
);
diff --git a/bookduck/src/components/StatisticsPage/MyKeyword.jsx b/bookduck/src/components/StatisticsPage/MyKeyword.jsx
index abdfbaf..82e7792 100644
--- a/bookduck/src/components/StatisticsPage/MyKeyword.jsx
+++ b/bookduck/src/components/StatisticsPage/MyKeyword.jsx
@@ -3,41 +3,62 @@ import rectangle2 from "../../assets/statisticsPage/rectangle2.svg";
import rectangle3 from "../../assets/statisticsPage/rectangle3.svg";
import rectangle4 from "../../assets/statisticsPage/rectangle4.svg";
import rectangle5 from "../../assets/statisticsPage/rectangle5.svg";
+import rectangle6 from "../../assets/statisticsPage/rectangle6.svg";
+import rectangle7 from "../../assets/statisticsPage/rectangle7.svg";
+import rectangle8 from "../../assets/statisticsPage/rectangle8.svg";
const MyKeyword = () => {
return (
내 기록 키워드예요
-
+
슬픈
- 아름다운
+ 아름
- 귀여운
+ 귀여운운
+
+ 아름다운
+
+
+ 아름다운
+
+
+ 아름다운
+
);
diff --git a/bookduck/src/components/StatisticsPage/PreferredAuthor.jsx b/bookduck/src/components/StatisticsPage/PreferredAuthor.jsx
index 1917431..29954a5 100644
--- a/bookduck/src/components/StatisticsPage/PreferredAuthor.jsx
+++ b/bookduck/src/components/StatisticsPage/PreferredAuthor.jsx
@@ -1,25 +1,40 @@
-import book_cover from "../../assets/common/book-cover.svg";
+// import book_cover from "../../assets/common/book-cover.svg";
-const PreferredAuthor = () => {
- const images = [book_cover, book_cover, book_cover];
+const PreferredAuthor = ({ author, imgPath }) => {
+ // const images = [book_cover, book_cover, book_cover];
+ const images = imgPath;
+ console.log(images);
return (
-
- 선호하는 작가예요
-
- 어스트 허밍웨이
-
-
-
- {images.map((cover, index) => (
-
- ))}
-
+ {/* 정보가 없으면 정보 부족 문구 띄움 */}
+ {author && images ? (
+ <>
+
+ 선호하는 작가예요
+
+ {author}
+
+
+
+ {images.map((cover, index) => (
+
+ ))}
+
+ >
+ ) : (
+
+ 선호하는 작가예요
+
+ 북덕이 분석하기에
+
정보가 부족해요
+
+
+ )}
);
};
diff --git a/bookduck/src/components/StatisticsPage/PreferredGenre.jsx b/bookduck/src/components/StatisticsPage/PreferredGenre.jsx
index a346a81..eb91c18 100644
--- a/bookduck/src/components/StatisticsPage/PreferredGenre.jsx
+++ b/bookduck/src/components/StatisticsPage/PreferredGenre.jsx
@@ -1,32 +1,46 @@
import StatisticsHeader from "./StatisticsHeader";
-
-const PreferredGenre = () => {
- const categories = [
- { id: 1, name: "로맨스", count: "7권" },
- { id: 2, name: "경제, 경영", count: "5권" },
- { id: 3, name: "소설", count: "3권" },
- ];
+const PreferredGenre = ({ userData }) => {
+ // const categories = [
+ // { id: 1, name: "로맨스", count: "7권" },
+ // { id: 2, name: "경제, 경영", count: "5권" },
+ // { id: 3, name: "소설", count: "3권" },
+ // ];
+ const categories = userData || [];
return (
-
-
- 선호하는 장르
TOP3를
- 알려드릴게요
+
+ {categories.length > 0 ? (
+
+
+ 선호하는 장르 TOP3를
+ 알려드릴게요
+
+
+ {categories.map((category, index) => (
+
+ {index + 1}
+ {category.genreName}
+ {category.bookCount}
+
+ ))}
+
-
- {categories.map((category, index) => (
-
- {category.id}
- {category.name}
- {category.count}
-
- ))}
+ ) : (
+
+
+ 선호하는 장르 TOP3를
+ 알려드릴게요
+
+
+ 북덕이 분석하기에
+
정보가 부족해요
+
-
+ )}
);
};
diff --git a/bookduck/src/components/StatisticsPage/UserCard.jsx b/bookduck/src/components/StatisticsPage/UserCard.jsx
index 0651d7d..067ac43 100644
--- a/bookduck/src/components/StatisticsPage/UserCard.jsx
+++ b/bookduck/src/components/StatisticsPage/UserCard.jsx
@@ -1,11 +1,11 @@
import right from "../../assets/statisticsPage/right.svg";
import UserDuck from "../CharacterPage/UserDuck";
-const UserCard = () => {
+const UserCard = ({ nickname }) => {
return (
- 여덟글자잖아요오님은
+ {nickname}님은
문학에 진심인 문학덕!
diff --git a/bookduck/src/components/common/Divider2.jsx b/bookduck/src/components/common/Divider2.jsx
index b995df8..abefd7b 100644
--- a/bookduck/src/components/common/Divider2.jsx
+++ b/bookduck/src/components/common/Divider2.jsx
@@ -1,4 +1,4 @@
const Divider2 = () => {
- return
;
+ return
;
};
export default Divider2;
diff --git a/bookduck/src/pages/BookInfoPage/BookInfoPage.jsx b/bookduck/src/pages/BookInfoPage/BookInfoPage.jsx
index c06f6c5..6403ecb 100644
--- a/bookduck/src/pages/BookInfoPage/BookInfoPage.jsx
+++ b/bookduck/src/pages/BookInfoPage/BookInfoPage.jsx
@@ -1,4 +1,5 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
+import { useParams } from "react-router-dom";
import Header3 from "../../components/common/Header3";
import BookInfo from "../../components/BookInfoPage/BookInfo";
import TabBarComponent from "../../components/common/TabBarComponent";
@@ -6,16 +7,41 @@ import InfoView from "../../components/BookInfoPage/InfoView";
import ArchiveView from "../../components/BookInfoPage/ArchiveView";
import FloatingRecordButton from "../../components/common/FloatingRecordButton";
import MyComment from "../../components/BookInfoPage/MyComment";
+import { getBookInfo, getOneLineRatingsInfo } from "../../api/bookinfo";
+
const BookInfoPage = () => {
+ const { bookinfoId } = useParams();
const [activeTab, setActiveTab] = useState("책 정보");
+ const [RatingListData, setRatingListData] = useState(null);
+ const [bookData, setBookData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const res = await getBookInfo({ bookinfoId });
+ const res2 = await getOneLineRatingsInfo({ bookinfoId });
+ console.log("조회성공: ", res);
+ setBookData(res);
+ setRatingListData(res2);
+ console.log("조회2 성공: ", res2);
+ } catch (err) {
+ console.error("오류 발생: ", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+
return (
- {activeTab === "책 정보" &&
}
+ {activeTab === "책 정보" && (
+
+ )}
{activeTab === "기록" &&
}
diff --git a/bookduck/src/pages/BookInfoPage/UserCommentPage.jsx b/bookduck/src/pages/BookInfoPage/UserCommentPage.jsx
index 67efb02..2809805 100644
--- a/bookduck/src/pages/BookInfoPage/UserCommentPage.jsx
+++ b/bookduck/src/pages/BookInfoPage/UserCommentPage.jsx
@@ -1,22 +1,22 @@
+import { useLocation } from "react-router-dom";
import Header3 from "../../components/common/Header3";
import UserComment from "../../components/BookInfoPage/UserComment";
import Divider2 from "../../components/common/Divider2";
const UserCommentPage = () => {
+ const { state } = useLocation();
+ const ratingList = state?.ratingList || [];
return (
-
+
-
-
-
-
-
-
-
-
-
-
+ {ratingList.length > 0 &&
+ ratingList.map((oneLine, index) => (
+
+ ))}
diff --git a/bookduck/src/pages/CharacterPage/CharacterPage.jsx b/bookduck/src/pages/CharacterPage/CharacterPage.jsx
index 654d5c4..84254b7 100644
--- a/bookduck/src/pages/CharacterPage/CharacterPage.jsx
+++ b/bookduck/src/pages/CharacterPage/CharacterPage.jsx
@@ -1,11 +1,14 @@
+import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import polygon from "../../assets/characterPage/polygon.svg";
-import bookIcon from "../../assets/characterPage/book.svg";
-import reviewIcon from "../../assets/characterPage/review.svg";
import right from "../../assets/characterPage/right.svg";
+import help from "../../assets/characterPage/help-circle.svg";
import UserDuck from "../../components/CharacterPage/UserDuck";
import CharacterHeader from "../../components/CharacterPage/CharacterHeader";
import BottomNavbar from "../../components/common/BottomNavbar";
+import LevelModal from "../../components/CharacterPage/LevelModal";
+import { getUserId } from "../../api/oauth";
+import { getUserInfo, getUserLevelInfo } from "../../api/character";
const CharacterPage = () => {
const navigate = useNavigate();
@@ -13,71 +16,92 @@ const CharacterPage = () => {
const handleBadgeClick = () => {
navigate("/myBadge");
};
+ const [isModalOpen, setIsModalOpen] = useState(false);
+
+ const toggleModal = () => {
+ setIsModalOpen(!isModalOpen);
+ };
+
+ const [userData, setUserData] = useState(null);
+ const [userInfo, setUserInfo] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const userId = getUserId();
+ const res = await getUserLevelInfo(userId);
+ const res2 = await getUserInfo(userId);
+ console.log("조회성공: ", res);
+ setUserData(res);
+ setUserInfo(res2);
+ } catch (err) {
+ console.error("오류 발생: ", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+ if (loading) {
+ return
;
+ }
+ const expProgress =
+ userData?.expInCurrentLevel === 0
+ ? 0
+ : Math.round(
+ (userData?.expInCurrentLevel / userData?.expToNextLevel) * 100
+ );
return (
-
+
캐릭터 말풍선
-
{/* 유저 정보 */}
-
-
-
레벨1
-
유저 닉네임
+
+
+
+
+ 레벨{userData?.level}
+
+
{userInfo?.nickname}
+
+
+ 레벨업
+
+
+ {isModalOpen &&
}
-
- {/* 레벨업미션 컴포넌트 분리 고려중..*/}
-
-
레벨업 미션
-
- {/* 레벨업 미션 detail */}
-
-
-
-
-
-
- 다 읽었어요 10권 달성하기
-
-
- 3/10
-
-
-
-
-
-
-
- 독서기록 10개 작성하기
-
-
- 1/10
+
+
{expProgress}%
+
{/* 나의 배지 */}
나의 배지
- {/* 네비바 들어갈 자리 */}
);
diff --git a/bookduck/src/pages/StatisticsPage/CharacterExportPage.jsx b/bookduck/src/pages/StatisticsPage/CharacterExportPage.jsx
new file mode 100644
index 0000000..ffa5390
--- /dev/null
+++ b/bookduck/src/pages/StatisticsPage/CharacterExportPage.jsx
@@ -0,0 +1,17 @@
+import Header3 from "../../components/common/Header3";
+import ExportCharacter from "../../components/StatisticsPage/ExportCharacter";
+
+const CharacterExportPage = () => {
+ return (
+
+ );
+};
+export default CharacterExportPage;
diff --git a/bookduck/src/pages/StatisticsPage/StatisticsPage.jsx b/bookduck/src/pages/StatisticsPage/StatisticsPage.jsx
index e096150..e86a8e3 100644
--- a/bookduck/src/pages/StatisticsPage/StatisticsPage.jsx
+++ b/bookduck/src/pages/StatisticsPage/StatisticsPage.jsx
@@ -1,3 +1,4 @@
+import { useEffect, useState } from "react";
import Header3 from "../../components/common/Header3";
import RecordCalender from "../../components/StatisticsPage/RecordCalender";
import Divider2 from "../../components/common/Divider2";
@@ -7,31 +8,67 @@ import PreferredAuthor from "../../components/StatisticsPage/PreferredAuthor";
import PreferredGenre from "../../components/StatisticsPage/PreferredGenre";
import MonthlyReading from "../../components/StatisticsPage/MonthlyReading";
import UserCard from "../../components/StatisticsPage/UserCard";
+import { getUserStatisticsInfo } from "../../api/statistics";
+import { getUserId } from "../../api/oauth";
const StatisticsPage = () => {
+ const [userData, setUserData] = useState(null);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const userId = getUserId();
+ // const userId = 1;
+
+ const res = await getUserStatisticsInfo(userId);
+ console.log("조회성공: ", res);
+ setUserData(res);
+ } catch (err) {
+ console.error("오류 발생: ", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+ if (loading) {
+ return
;
+ }
return (
-
+
- 이번달 기록은 총 16개!
+ {userData?.isFirstHalf ? "상반기" : "하반기"} 기록은 총{" "}
+
+ {userData.excerptCount + userData.bookRecordCount}
+
+ 개!
-
-
-
+
+
+
-
-
+
+
{/* 같은 작가의 작품을 최소 2권 이상을 읽어야 ‘선호하는 작가' 카드가 보임 */}
-
+
- 북덕은 언제나 여덟글자잖아요오님의
+ 북덕은 언제나 {userData?.nickname}님의
독서를 응원합니다!
diff --git a/bookduck/tailwind.config.js b/bookduck/tailwind.config.js
index ca49887..671cd59 100644
--- a/bookduck/tailwind.config.js
+++ b/bookduck/tailwind.config.js
@@ -63,7 +63,7 @@ export default {
},
fontSize: {
t1: ["1.5rem", { lineHeight: "2.25rem" }], //24px
- t2: ["1.25rem", { lineHeight: "1.75rem" }], //20px /26px
+ t2: ["1.25rem", { lineHeight: "1.75rem" }], //20px /28px
st: ["1.125rem", { lineHeight: "1.5rem" }], //18px / 24px
b1: ["1rem", { lineHeight: "1.5rem" }], //16px / 24px
b2: ["0.875rem", { lineHeight: "1.5rem" }], //14px /24px