feat(artwork): sidebar layout, icon actions, original download URL fix

- ArtworkDownloadController: fix resolveDownloadUrl() to use correct CDN
  path: original/{h1}/{h2}/{hash}.{file_ext} (was wrong originals/h1/h2/h3/orig.webp)
  Wrap incrementDownloads() in try/catch so Redis failure can't break the response

- ArtworkPage: move ArtworkAuthor from left column to right sidebar
  Sidebar now stacks: Author → Actions → Awards (sticky top-24)
  Mobile block follows same order above main content

- ArtworkActions: replace four stacked text buttons with a compact 4-col icon grid
  Like (heart, rose when active), Save (star, amber when active),
  Share (network icon), Report (flag icon, red on hover)
  Download remains full-width orange CTA

- ArtworkAuthor: add icons to Profile (person) and Follow buttons
  Follow shows circle-check icon; Following state shows user-plus icon
This commit is contained in:
2026-02-27 11:31:32 +01:00
parent 4f9b43bbba
commit 09eadf9003
5 changed files with 190 additions and 70 deletions

View File

@@ -67,17 +67,15 @@ function ArtworkPage({ artwork: initialArtwork, related: initialRelated, present
onNext={navState.navigateNext}
/>
<div className="mt-6 lg:hidden">
<div className="mt-6 space-y-4 lg:hidden">
<ArtworkAuthor artwork={artwork} presentSq={presentSq} />
<ArtworkActions artwork={artwork} canonicalUrl={canonicalUrl} mobilePriority />
<div className="mt-4">
<ArtworkAwards artwork={artwork} initialAwards={initialAwards} isAuthenticated={isAuthenticated} />
</div>
<ArtworkAwards artwork={artwork} initialAwards={initialAwards} isAuthenticated={isAuthenticated} />
</div>
<div className="mt-8 grid grid-cols-1 gap-8 lg:grid-cols-3">
<div className="space-y-6 lg:col-span-2">
<ArtworkMeta artwork={artwork} />
<ArtworkAuthor artwork={artwork} presentSq={presentSq} />
<ArtworkStats artwork={artwork} />
<ArtworkTags artwork={artwork} />
<ArtworkDescription artwork={artwork} />
@@ -91,11 +89,10 @@ function ArtworkPage({ artwork: initialArtwork, related: initialRelated, present
</div>
<aside className="hidden space-y-6 lg:block">
<div className="sticky top-24">
<div className="sticky top-24 space-y-4">
<ArtworkAuthor artwork={artwork} presentSq={presentSq} />
<ArtworkActions artwork={artwork} canonicalUrl={canonicalUrl} />
<div className="mt-4">
<ArtworkAwards artwork={artwork} initialAwards={initialAwards} isAuthenticated={isAuthenticated} />
</div>
<ArtworkAwards artwork={artwork} initialAwards={initialAwards} isAuthenticated={isAuthenticated} />
</div>
</aside>
</div>