feat: library grid with rip/format filters, search and artist index
This commit is contained in:
30
web/src/components/CoverGrid.tsx
Normal file
30
web/src/components/CoverGrid.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import type { Item } from '../types.js'
|
||||
import Cover from './Cover.js'
|
||||
|
||||
export default function CoverGrid({ items }: { items: Item[] }) {
|
||||
return (
|
||||
<div className="grid grid-cols-3 gap-3 sm:grid-cols-4 md:grid-cols-5">
|
||||
{items.map((item) => (
|
||||
<Link
|
||||
key={item.id}
|
||||
to={`/item/${item.id}`}
|
||||
aria-label={`${item.artist} — ${item.title}`}
|
||||
className="group"
|
||||
>
|
||||
<div className="relative">
|
||||
<Cover src={item.artworkUrl} alt="" className="aspect-square w-full" />
|
||||
<span
|
||||
aria-label={item.ripStatus === 'ripped' ? 'ripped' : 'not ripped'}
|
||||
className={`absolute right-1.5 top-1.5 size-3 rounded-full ring-2 ring-neutral-950 ${
|
||||
item.ripStatus === 'ripped' ? 'bg-emerald-400' : 'bg-amber-500'
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
<p className="mt-1 truncate text-xs font-medium">{item.title}</p>
|
||||
<p className="truncate text-xs text-neutral-500">{item.artist}</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user