Archived
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18n-lite";
|
|
import styles from "./FinishedBooksShelf.module.css";
|
|
|
|
interface ShelfBook {
|
|
id: number;
|
|
title: string;
|
|
author: string;
|
|
cover_image: string | null;
|
|
format: string;
|
|
genre: string;
|
|
}
|
|
|
|
interface FinishedBooksShelfProps {
|
|
books: ShelfBook[];
|
|
defaultExpanded?: boolean;
|
|
onOpenBook: (book: ShelfBook) => void;
|
|
onContextMenu: (e: React.MouseEvent, book: ShelfBook) => void;
|
|
}
|
|
|
|
export function FinishedBooksShelf({
|
|
books,
|
|
defaultExpanded = false,
|
|
onOpenBook,
|
|
onContextMenu,
|
|
}: FinishedBooksShelfProps) {
|
|
const { t } = useTranslation();
|
|
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
|
|
useEffect(() => {
|
|
if (defaultExpanded) setExpanded(true);
|
|
}, [defaultExpanded]);
|
|
|
|
if (books.length === 0) return null;
|
|
|
|
return (
|
|
<div
|
|
className={`${styles.shelf} ${expanded ? styles.shelfExpanded : styles.shelfCollapsed}`}
|
|
aria-label={t("library.finishedSection")}
|
|
>
|
|
<button
|
|
type="button"
|
|
className={styles.shelfHandle}
|
|
onClick={() => setExpanded((v) => !v)}
|
|
aria-expanded={expanded}
|
|
>
|
|
<span className={styles.shelfHandleTitle}>{t("library.finishedSection")}</span>
|
|
<span className={styles.shelfHandleCount}>
|
|
{t("library.finishedCount", { count: String(books.length) })}
|
|
</span>
|
|
<span className={styles.shelfChevron} aria-hidden>
|
|
{expanded ? "▾" : "▴"}
|
|
</span>
|
|
</button>
|
|
{expanded && (
|
|
<div className={styles.shelfBody}>
|
|
<div className={styles.shelfGrid}>
|
|
{books.map((book) => (
|
|
<div
|
|
key={book.id}
|
|
role="button"
|
|
tabIndex={0}
|
|
className={styles.shelfCard}
|
|
onClick={() => onOpenBook(book)}
|
|
onKeyDown={(e) => {
|
|
if (e.key === "Enter" || e.key === " ") {
|
|
e.preventDefault();
|
|
onOpenBook(book);
|
|
}
|
|
}}
|
|
onContextMenu={(e) => onContextMenu(e, book)}
|
|
>
|
|
<div className={styles.shelfCover}>
|
|
{book.cover_image ? (
|
|
<img src={book.cover_image} alt="" />
|
|
) : (
|
|
<span className={styles.shelfCoverPlaceholder}>📖</span>
|
|
)}
|
|
<span className={styles.shelfBadge}>{t("library.readingStatus.finished")}</span>
|
|
</div>
|
|
<div className={styles.shelfMeta}>
|
|
<p className={styles.shelfTitle}>{book.title}</p>
|
|
<p className={styles.shelfAuthor}>{book.author}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|