Extract grid component from artist view

This commit is contained in:
Claudio Ortolina
2025-01-02 23:32:05 +00:00
parent 0ba39dd411
commit 7cd1e8e944
4 changed files with 83 additions and 100 deletions
@@ -0,0 +1,60 @@
defmodule MusicLibraryWeb.ArtistLive.RecordComponents do
use MusicLibraryWeb, :live_component
alias MusicLibrary.Records
attr :records, :list, required: true
attr :title, :string, required: true
attr :id, :string, required: true
attr :record_path, :any, required: true
def grid(assigns) do
~H"""
<div class="mt-4">
<h2 class="flex items-end font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
{@title}
<span class="ml-2">
<span class="sr-only">
{gettext("Number of records")}
</span>
<.round_badge text={Enum.count(@records)} />
</span>
</h2>
<%!-- TODO: replace with OSS version --%>
<ul
id={@id}
role="list"
class="mt-4 grid grid-cols-3 gap-x-4 gap-y-8 sm:grid-cols-4 sm:gap-x-6 lg:grid-cols-6 xl:gap-x-8"
>
<li :for={record <- @records} class="relative">
<div class="group overflow-hidden rounded-lg bg-zinc-100 focus-within:ring-2 focus-within:ring-zinc-500 focus-within:ring-offset-2 focus-within:ring-offset-zinc-100">
<img
alt={record.title}
src={~p"/covers/#{record.id}?vsn=#{record.cover_hash}"}
class="pointer-events-none aspect-square object-cover group-hover:opacity-75"
/>
<button
type="button"
class="absolute inset-0 focus:outline-none"
phx-click={JS.navigate(@record_path.(record))}
>
<span class="sr-only">{gettext("View details")}</span>
</button>
</div>
<p class="pointer-events-none mt-2 block truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
{record.title}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
)}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_release(record.release)}
</p>
</li>
</ul>
</div>
"""
end
end
@@ -1,5 +1,6 @@
defmodule MusicLibraryWeb.ArtistLive.Show do
use MusicLibraryWeb, :live_view
import MusicLibraryWeb.ArtistLive.RecordComponents
alias MusicLibrary.{Artists, Records}
@@ -59,95 +59,19 @@
</details>
</.async_result>
<div :if={@artist_records.collection !== []} class="mt-4">
<h2 class="flex items-end font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
{gettext("Collection")}
<span class="ml-2">
<span class="sr-only">
{gettext("Number of albums")}
</span>
<.round_badge text={Enum.count(@artist_records.collection)} />
</span>
</h2>
<%!-- TODO: replace with OSS version --%>
<ul
id="collection"
role="list"
class="mt-4 grid grid-cols-3 gap-x-4 gap-y-8 sm:grid-cols-4 sm:gap-x-6 lg:grid-cols-6 xl:gap-x-8"
>
<li :for={record <- @artist_records.collection} class="relative">
<div class="group overflow-hidden rounded-lg bg-zinc-100 focus-within:ring-2 focus-within:ring-zinc-500 focus-within:ring-offset-2 focus-within:ring-offset-zinc-100">
<img
alt={record.title}
src={~p"/covers/#{record.id}?vsn=#{record.cover_hash}"}
class="pointer-events-none aspect-square object-cover group-hover:opacity-75"
/>
<button
type="button"
class="absolute inset-0 focus:outline-none"
phx-click={JS.navigate(~p"/collection/#{record}")}
>
<span class="sr-only">{gettext("View details")}</span>
</button>
</div>
<p class="pointer-events-none mt-2 block truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
{record.title}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
)}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_release(record.release)}
</p>
</li>
</ul>
</div>
<.grid
:if={Enum.any?(@artist_records.collection)}
title={gettext("Collection")}
id="collection"
records={@artist_records.collection}
record_path={fn record -> ~p"/collection/#{record}" end}
/>
<div :if={@artist_records.wishlist !== []} class="mt-4">
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
{gettext("Wishlist")}
<span>
<span class="sr-only">
{gettext("Number of albums")}
</span>
<.round_badge text={Enum.count(@artist_records.wishlist)} />
</span>
</h2>
<%!-- TODO: replace with OSS version --%>
<ul
id="wishlist"
role="list"
class="mt-4 grid grid-cols-3 gap-x-4 gap-y-8 sm:grid-cols-4 sm:gap-x-6 lg:grid-cols-6 xl:gap-x-8"
>
<li :for={record <- @artist_records.wishlist} class="relative">
<div class="group overflow-hidden rounded-lg bg-zinc-100 focus-within:ring-2 focus-within:ring-zing-500 focus-within:ring-offset-2 focus-within:ring-offset-zinc-100">
<img
alt={record.title}
src={~p"/covers/#{record.id}?vsn=#{record.cover_hash}"}
class="pointer-events-none aspect-square object-cover group-hover:opacity-75"
/>
<button
type="button"
class="absolute inset-0 focus:outline-none"
phx-click={JS.navigate(~p"/wishlist/#{record}")}
>
<span class="sr-only">{gettext("View details")}</span>
</button>
</div>
<p class="pointer-events-none mt-2 block truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
{record.title}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
)}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
{Records.Record.format_release(record.release)}
</p>
</li>
</ul>
</div>
<.grid
:if={Enum.any?(@artist_records.wishlist)}
title={gettext("Wishlist")}
id="wishlist"
records={@artist_records.wishlist}
record_path={fn record -> ~p"/wishlist/#{record}" end}
/>
</div>