import {useContext, useEffect, useState} from "react"; import System from "@/lib/models/System"; import {AlertContext} from "@/context/AlertContext"; import {BookContext} from "@/context/BookContext"; import SearchBook from "./SearchBook"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {faBook, faDownload, faGear, faTrash} from "@fortawesome/free-solid-svg-icons"; import {SessionContext} from "@/context/SessionContext"; import Book, {BookListProps, BookProps} from "@/lib/models/Book"; import BookCard from "@/components/book/BookCard"; import BookCardSkeleton from "@/components/book/BookCardSkeleton"; import GuideTour, {GuideStep} from "@/components/GuideTour"; import User from "@/lib/models/User"; import {useTranslations} from "next-intl"; import {LangContext, LangContextProps} from "@/context/LangContext"; export default function BookList() { const {session, setSession} = useContext(SessionContext); const accessToken: string = session?.accessToken || ''; const {errorMessage} = useContext(AlertContext); const {setBook} = useContext(BookContext); const t = useTranslations(); const {lang} = useContext(LangContext) const [searchQuery, setSearchQuery] = useState(''); const [groupedBooks, setGroupedBooks] = useState>({}); const [isLoadingBooks, setIsLoadingBooks] = useState(true); const [bookGuide, setBookGuide] = useState(false); const bookGuideSteps: GuideStep[] = [ { id: 0, targetSelector: '[data-guide="book-category"]', position: 'left', highlightRadius: -200, title: `${t("bookList.guideStep0Title")} ${session.user?.name}`, content: (

{t("bookList.guideStep0Content")}

), }, { id: 1, targetSelector: '[data-guide="book-card"]', position: 'left', title: t("bookList.guideStep1Title"), content: (

{t("bookList.guideStep1Content")}

), }, { id: 2, targetSelector: '[data-guide="bottom-book-card"]', position: 'left', title: t("bookList.guideStep2Title"), content: (

{t("bookList.guideStep2ContentGear")}

{t("bookList.guideStep2ContentDownload")}

{t("bookList.guideStep2ContentTrash")}

), }, ] useEffect((): void => { if (groupedBooks && Object.keys(groupedBooks).length > 0 && User.guideTourDone(session.user?.guideTour || [], 'new-first-book')) { setBookGuide(true); } }, [groupedBooks]); useEffect((): void => { getBooks().then() }, [session.user?.books]); useEffect((): void => { if (accessToken) getBooks().then(); }, [accessToken]); async function handleFirstBookGuide(): Promise { try { const response: boolean = await System.authPostToServer( 'logs/tour', {plateforme: 'web', tour: 'new-first-book'}, session.accessToken, lang ); if (response) { setSession(User.setNewGuideTour(session, 'new-first-book')); setBookGuide(false); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookList.errorBookCreate")); } } } async function getBooks(): Promise { setIsLoadingBooks(true); try { const bookResponse: BookListProps[] = await System.authGetQueryToServer('books', accessToken, lang); if (bookResponse) { const booksByType: Record = bookResponse.reduce((groups: Record, book: BookListProps): Record => { const imageDataUrl: string = book.coverImage ? 'data:image/jpeg;base64,' + book.coverImage : ''; const categoryLabel: string = Book.getBookTypeLabel(book.type); const transformedBook: BookProps = { bookId: book.id, type: categoryLabel, title: book.title, subTitle: book.subTitle, summary: book.summary, serie: book.serieId, publicationDate: book.desiredReleaseDate, desiredWordCount: book.desiredWordCount, totalWordCount: 0, coverImage: imageDataUrl, }; if (!groups[t(categoryLabel)]) { groups[t(categoryLabel)] = []; } groups[t(categoryLabel)].push(transformedBook); return groups; }, {}); setGroupedBooks(booksByType); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookList.errorBooksFetch")); } } finally { setIsLoadingBooks(false); } } const filteredGroupedBooks: Record = Object.entries(groupedBooks).reduce( (acc: Record, [category, books]: [string, BookProps[]]): Record => { const filteredBooks: BookProps[] = books.filter((book: BookProps): boolean => book.title.toLowerCase().includes(searchQuery.toLowerCase()) ); if (filteredBooks.length > 0) { acc[category] = filteredBooks; } return acc; }, {} ); async function getBook(bookId: string): Promise { try { const bookResponse: BookListProps = await System.authGetQueryToServer( `book/basic-information`, accessToken, lang, {id: bookId} ); if (!bookResponse) { errorMessage(t("bookList.errorBookDetails")); return; } if (setBook) { setBook({ bookId: bookId, title: bookResponse?.title || '', subTitle: bookResponse?.subTitle || '', summary: bookResponse?.summary || '', type: bookResponse?.type || '', serie: bookResponse?.serieId, publicationDate: bookResponse?.desiredReleaseDate || '', desiredWordCount: bookResponse?.desiredWordCount || 0, totalWordCount: 0, coverImage: bookResponse?.coverImage ? 'data:image/jpeg;base64,' + bookResponse.coverImage : '', }); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("bookList.errorUnknown")); } } } return (
{session?.user && (
)}
{ isLoadingBooks ? ( <>

{t("bookList.library")}

{t("bookList.booksAreMirrors")}

{Array.from({length: 6}).map((_, id: number) => (
))}
) : Object.entries(filteredGroupedBooks).length > 0 ? ( <>

{t("bookList.library")}

{t("bookList.booksAreMirrors")}

{Object.entries(filteredGroupedBooks).map(([category, books], index) => (

{category}

{books.length} {t("bookList.works")}
{ books.map((book: BookProps, idx) => (
)) }
))} ) : (

{t("bookList.welcomeWritingWorkshop")}

{t("bookList.whitePageText")}

)}
{ bookGuide && setBookGuide(false)}/> }
); }