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>
)
}