Files
PageManager/PageManager.Web/src/pages/Metadata/Metadata.tsx
T
2026-03-15 22:31:31 +02:00

90 lines
3.0 KiB
TypeScript

import { useEffect, useMemo, useState } from 'react'
import type { Book } from '../../types'
import { fetchBooks, updateBook } from '../../api/books'
import MetadataForm from '../../components/MetadataForm/MetadataForm'
import s from './Metadata.module.css'
export default function Metadata() {
const [books, setBooks] = useState<Book[]>([])
const [selected, setSelected] = useState<Book | null>(null)
const [query, setQuery] = useState('')
useEffect(() => {
fetchBooks().then(list => {
setBooks(list)
if (list.length > 0) setSelected(list[0])
})
}, [])
const filtered = useMemo(() =>
books.filter(b =>
!query ||
b.title.toLowerCase().includes(query.toLowerCase()) ||
b.authors.some(a => a.name.toLowerCase().includes(query.toLowerCase()))
), [books, query])
function handleSave(patch: Partial<Book>) {
if (!selected) return
updateBook(selected.id, patch).then(updated => {
setBooks(bs => bs.map(b => b.id === updated.id ? updated : b))
setSelected(updated)
})
}
return (
<div className={s.layout}>
<aside className={s.list}>
<div className={s.listHeader}>
<div className={s.search}>
<span className={`material-symbols-outlined ${s.searchIcon}`}>search</span>
<input
className={s.searchInput}
type="search"
placeholder="Filter books…"
value={query}
onChange={e => setQuery(e.target.value)}
/>
</div>
</div>
<ul className={s.bookList}>
{filtered.map(book => (
<li
key={book.id}
className={`${s.bookItem} ${selected?.id === book.id ? s.bookItemActive : ''}`}
onClick={() => setSelected(book)}
>
<div className={s.thumb} style={{ background: book.color }}>
{book.title[0]}
</div>
<div className={s.bookMeta}>
<span className={s.bookTitle}>{book.title}</span>
<span className={s.bookAuthor}>{book.authors.map(a => a.name).join(', ')}</span>
</div>
</li>
))}
</ul>
</aside>
<main className={s.editor}>
{selected ? (
<>
<div className={s.editorHeader}>
<div className={s.editorCover} style={{ background: selected.color }}>
{selected.title[0]}
</div>
<div>
<p className={s.editorTitle}>{selected.title}</p>
<p className={s.editorAuthor}>{selected.authors.map(a => a.name).join(', ')}</p>
</div>
</div>
<MetadataForm key={selected.id} book={selected} onSave={handleSave} />
</>
) : (
<div className={s.empty}>Select a book to edit metadata</div>
)}
</main>
</div>
)
}