85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
import { Badge } from '@/components/badge'
|
|
import { Author, Book, Genre } from '@/payload-types'
|
|
import { Avatar } from '../avatar'
|
|
|
|
type Props = {
|
|
books: Book[]
|
|
}
|
|
|
|
const makeAuthorsLabel = (book: Book) => {
|
|
const authors = book.authors as Author[] // TODO: endure this type safety
|
|
|
|
const translators = authors?.filter((a) => a.role === 'Translator').map((t) => t.lf)
|
|
const editors = authors?.filter((a) => a.role === 'Editor').map((e) => e.lf)
|
|
const actualAuthors = authors
|
|
?.filter((a) => !editors.includes(a.lf) && !translators.includes(a.lf))
|
|
.map((a) => a.lf)
|
|
|
|
return (
|
|
<ul>
|
|
<li>{actualAuthors.join(', ')}</li>
|
|
{!!translators?.length && <li>Translators: {translators.join(', ')}</li>}
|
|
{!!editors?.length && <li>Editors: {editors.join(', ')}</li>}
|
|
</ul>
|
|
)
|
|
}
|
|
|
|
const makeGenreBadges = (book: Book) => {
|
|
return (book.genre as Genre[])?.map((g) => (
|
|
<Badge key={g.name + book.title + book.id} className="ml-0.5">
|
|
{g.name}
|
|
</Badge>
|
|
))
|
|
}
|
|
|
|
export default function BookList(props: Props) {
|
|
const { books } = props
|
|
|
|
return (
|
|
<section id="user-repositories">
|
|
<ul role="list" className="divide-y divide-gray-800">
|
|
{books.map((b) => (
|
|
<li key={b.lcc + (b.title || '')} className="flex justify-between gap-x-6 py-5">
|
|
<div className="flex max-w-9/12 min-w-0 gap-x-4">
|
|
<Avatar
|
|
square
|
|
className="size-12 flex-none bg-gray-800"
|
|
src={
|
|
b.isbn
|
|
? `https://covers.openlibrary.org/b/isbn/${b.isbn}-S.jpg`
|
|
: '/images/book-48.svg'
|
|
}
|
|
/>
|
|
<div className="min-w-0 flex-auto">
|
|
<p className="text-sm/6 font-semibold text-white">
|
|
<span>{b.title}</span>
|
|
<small className="ml-1 italic font-thin">{b.lcc}</small>
|
|
</p>
|
|
<p className="mt-1 truncate text-xs/5 text-gray-400">{makeGenreBadges(b)}</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col items-end">
|
|
<p className="text-sm/6 text-white text-right">{makeAuthorsLabel(b)}</p>
|
|
{
|
|
/*b.lastBorrowed*/ false ? (
|
|
<p className="mt-1 text-xs/5 text-gray-400">
|
|
Last Borrowed{' '}
|
|
<time dateTime={new Date().toUTCString()}>{new Date().toUTCString()}</time>
|
|
</p>
|
|
) : (
|
|
<div className="mt-1 flex items-center gap-x-1.5">
|
|
<div className="flex-none rounded-full bg-emerald-500/20 p-1">
|
|
<div className="size-1.5 rounded-full bg-emerald-500" />
|
|
</div>
|
|
<p className="text-xs/5 text-gray-400">Available</p>
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</section>
|
|
)
|
|
}
|