feat: artwork page carousels, recommendations, avatars & fixes

- Infinite loop carousels for Similar Artworks & Trending rails
- Mouse wheel horizontal scrolling on both carousels
- Author avatar shown on hover in RailCard (similar + trending)
- Removed "View" badge from RailCard hover overlay
- Added `id` to Meilisearch filterable attributes
- Auto-prepend Scout prefix in meilisearch:configure-index command
- Added author name + avatar to Similar Artworks API response
- Added avatar_url to ArtworkListResource author object
- Added direct /art/{id}/{slug} URL to ArtworkListResource
- Fixed race condition: Similar Artworks no longer briefly shows trending items
- Fixed user_profiles eager load (user_id primary key, not id)
- Bumped /api/art/{id}/similar rate limit to 300/min
- Removed decorative heart icons from tag pills
- Moved ReactionBar under artwork description
This commit is contained in:
2026-02-28 14:05:39 +01:00
parent 80100c7651
commit eee7df1f8c
46 changed files with 2536 additions and 498 deletions

View File

@@ -2,31 +2,12 @@ import React from 'react'
import ArtworkBreadcrumbs from './ArtworkBreadcrumbs'
export default function ArtworkMeta({ artwork }) {
const author = artwork?.user?.name || artwork?.user?.username || 'Artist'
const publishedAt = artwork?.published_at
? new Date(artwork.published_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
: '—'
const width = artwork?.dimensions?.width || 0
const height = artwork?.dimensions?.height || 0
return (
<div className="rounded-xl border border-nova-700 bg-panel p-5">
<h1 className="text-xl font-semibold text-white sm:text-2xl">{artwork?.title}</h1>
<ArtworkBreadcrumbs artwork={artwork} />
<dl className="mt-3 grid grid-cols-1 gap-3 text-sm text-soft sm:grid-cols-2">
<div className="flex items-center justify-between gap-4 rounded-lg bg-nova-900/30 px-3 py-2">
<dt>Author</dt>
<dd className="text-white">{author}</dd>
</div>
<div className="flex items-center justify-between gap-4 rounded-lg bg-nova-900/30 px-3 py-2">
<dt>Upload date</dt>
<dd className="text-white">{publishedAt}</dd>
</div>
<div className="flex items-center justify-between gap-4 rounded-lg bg-nova-900/30 px-3 py-2 sm:col-span-2">
<dt>Resolution</dt>
<dd className="text-white">{width > 0 && height > 0 ? `${width} × ${height}` : '—'}</dd>
</div>
</dl>
<div>
<h1 className="text-2xl font-bold tracking-tight text-white sm:text-3xl">{artwork?.title}</h1>
<div className="mt-3">
<ArtworkBreadcrumbs artwork={artwork} />
</div>
</div>
)
}