diff --git a/src/app/(home)/books/library/page.tsx b/src/app/(home)/books/library/page.tsx index f8995f9..587d54d 100644 --- a/src/app/(home)/books/library/page.tsx +++ b/src/app/(home)/books/library/page.tsx @@ -84,6 +84,12 @@ const Booklibrary: React.FC = () => { ) : ( diff --git a/src/components/books/library/BookCover.tsx b/src/components/books/library/BookCover.tsx index b8bea65..e446ed5 100644 --- a/src/components/books/library/BookCover.tsx +++ b/src/components/books/library/BookCover.tsx @@ -1,10 +1,8 @@ "use client" -import { useJwt } from "react-jwt" -import useUserFetch from "@/hooks/fetch-hooks/useUserFetch" -import { useAppSelector } from "@/store/lib/hooks" -import { config } from "@/configs/config" import Image from "next/image" +import { useState } from "react" +import BookRatingsBox from "./BookRatingsBox" type Props = { title: string @@ -25,89 +23,50 @@ const BookCover: React.FC = ({ isSingleBook, imageURL, }) => { - const token = useAppSelector((state) => state.token.tokenState) - const { decodedToken }: { decodedToken?: { username: string; _id: string } } = - useJwt(token) - const username = decodedToken?.username + const [isLoading, setIsLoading] = useState(true) - const { userData, loadingUsers, error } = useUserFetch( - `${config.API_URL}/users`, - null, - ) - - const findUser = (id) => { - const user = userData?.find((user) => user._id === id) - return user ? user.username : "user not found" - } - - const raterArr2 = raterArr?.map((id) => findUser(id)) - - let raterObj: object = {} - const findBookScore = () => { - if (raterArr2) { - for (let i = 0; i < raterArr2.length; i++) { - raterObj[raterArr2[i]] = ratingArr[i] - findUser(raterObj[raterArr[i]]) - } - raterObj = Object.entries(raterObj) - return raterObj - } - } - findBookScore() return ( <>
- {imageURL.length ? ( -
+ {isLoading && ( +
+

{title}

+

+ (Image pending) +

+
+ )} + {imageURL && ( +
{title} setIsLoading(false)} />
- ) : ( -
-

{title}

-

- (Image pending) -

-
)} -
-

Book Club Brothers

- - {Array.isArray(raterObj) && !loadingUsers ? ( - raterObj.map(([name, value]) => ( -
  • - {name}:{" "} - {hideScores && username !== name ? "?" : value.toFixed(2)} -
  • - )) - ) : error ? ( -
  • {error?.message}
  • - ) : ( -
  • Score Pending...
  • - )} - -
  • - Group Rating:{" "} - {totalScore - ? hideScores - ? "?" - : Math.floor(totalScore * 100) / 100 - : "Pending..."} -
  • -
    +
    diff --git a/src/components/books/library/BookImageCover.tsx b/src/components/books/library/BookImageCover.tsx index da25c6a..4d2a897 100644 --- a/src/components/books/library/BookImageCover.tsx +++ b/src/components/books/library/BookImageCover.tsx @@ -1,21 +1,53 @@ import Image from "next/image" +import BookRatingsBox from "./BookRatingsBox" type Props = { title?: string imageURL: string + totalScore: number + ratingArr: number[] | number + raterArr: string[] + hideScores: boolean + isSingleBook?: boolean } -const BookImageCover: React.FC = ({ title, imageURL }) => { +const BookImageCover: React.FC = ({ + title, + imageURL, + totalScore, + ratingArr, + raterArr, + hideScores, + isSingleBook, +}) => { return ( - <> - {title} - +
    +
    + {title} +
    +
    + +
    +
    ) } diff --git a/src/components/books/library/BookRatingsBox.tsx b/src/components/books/library/BookRatingsBox.tsx new file mode 100644 index 0000000..c5f6ba9 --- /dev/null +++ b/src/components/books/library/BookRatingsBox.tsx @@ -0,0 +1,74 @@ +import { config } from "@/configs/config" +import useUserFetch from "@/hooks/fetch-hooks/useUserFetch" +import { useAppSelector } from "@/store/lib/hooks" +import React, { memo, useMemo } from "react" +import { useJwt } from "react-jwt" + +type Props = { + totalScore: number + ratingArr: number[] | number + raterArr: string[] + hideScores: boolean +} + +const BookRatingsBox = ({ + totalScore, + ratingArr, + raterArr, + hideScores, +}: Props) => { + const token = useAppSelector((state) => state.token.tokenState) + const { decodedToken }: { decodedToken?: { username: string; _id: string } } = + useJwt(token) + const username = decodedToken?.username + + const { userData, loadingUsers, error } = useUserFetch( + `${config.API_URL}/users`, + null, + ) + + const formattedRatings = useMemo(() => { + if (!userData || !raterArr || !Array.isArray(ratingArr)) return [] + + const userLookup = userData.reduce( + (acc, user) => { + acc[user._id] = user.username + return acc + }, + {} as Record, + ) + + return raterArr.map((id, index) => ({ + name: userLookup[id] || "User not found", + score: Array.isArray(ratingArr) ? ratingArr[index] : 0, + })) + }, [userData, raterArr, ratingArr]) + return ( +
    +

    Book Club Brothers

    + + {!loadingUsers && formattedRatings.length > 0 ? ( + formattedRatings.map(({ name, score }) => ( +
  • + {name}: {hideScores && username !== name ? "?" : score.toFixed(2)} +
  • + )) + ) : error ? ( +
  • {error?.message}
  • + ) : ( +
  • Score Pending...
  • + )} + +
  • + Group Rating:{" "} + {totalScore + ? hideScores + ? "?" + : Math.floor(totalScore * 100) / 100 + : "Pending..."} +
  • +
    + ) +} + +export default BookRatingsBox diff --git a/src/components/books/library/single-book/AdminViewLeftSide.tsx b/src/components/books/library/single-book/AdminViewLeftSide.tsx index 3e9af31..da039c7 100644 --- a/src/components/books/library/single-book/AdminViewLeftSide.tsx +++ b/src/components/books/library/single-book/AdminViewLeftSide.tsx @@ -12,6 +12,7 @@ import Profile from "@/components/misc/profile/Profile" import useSingleUserFetch from "@/hooks/fetch-hooks/useSingleUserFetch" import Image from "next/image" import { config } from "@/configs/config" +import BookImageCover from "../BookImageCover" type Props = { bookData: Book @@ -49,12 +50,16 @@ const AdminViewSingleBook: React.FC = ({ bookData, bookId }) => {
    {bookData?.reviewImageURL ? ( - book_review_image ) : ( {
    {bookData?.reviewImageURL ? ( - book_review_image ) : ( = ({ bookData, error, userData }) => { + const [isLoading, setIsLoading] = useState(true) const index = useAppSelector((state) => state.randomise.index) const showRandom = useAppSelector((state) => state.randomise.showRandom) const { decodedToken } = useAuth() @@ -28,16 +29,21 @@ const RandomSectionRight: React.FC = ({ bookData, error, userData }) => { return (
    - {bookData && bookData[index] ? ( - {bookData[index]?.title} - ) : null} + {bookData && bookData[index] && ( + <> + {bookData[index]?.title} setIsLoading(false)} + /> +
    + + )} {!bookData ? ( <>
    diff --git a/src/components/brothers/dashboard/BrotherBanner.tsx b/src/components/brothers/dashboard/BrotherBanner.tsx index 08cb19e..071aae0 100644 --- a/src/components/brothers/dashboard/BrotherBanner.tsx +++ b/src/components/brothers/dashboard/BrotherBanner.tsx @@ -78,7 +78,15 @@ const BrotherBanner: React.FC = ({ user, readBooks }) => {
    {findMinBook?.reviewImageURL ? ( - + ) : ( = ({ user, readBooks }) => {
    {findMaxBook?.reviewImageURL ? ( - + ) : ( = ({ id }) => { try { const formData = new FormData() formData.append("picture", image, image?.name) - await axios.post(`${config.API_URL}/books/${id}`, formData, { + await axios.post(`${config.API_URL}books/${id}`, formData, { headers: { Authorization: `Bearer ${token}`, }, @@ -71,7 +71,7 @@ const EditImage: React.FC = ({ id }) => { setLoadings((prevLoadings) => { const newLoadings = [...prevLoadings] newLoadings[index] = false - document.location.reload() + // document.location.reload() return newLoadings }) }, 4000) @@ -84,6 +84,7 @@ const EditImage: React.FC = ({ id }) => { name="picture_upload_form" initialValues={{ fileList: [] }} > + {/* */} = ({ id }) => {
    - - - false} - > -
    - -
    Upload
    -
    -
    -
    -
    + {/* */}