Files
minstrel/web/src/routes/library/liked/+page.svelte
T
bvandeusen 4412a4af0c feat(web): update nav (Home/Artists/Albums); retire ArtistRow
Add Artists and Albums nav entries, rename root label from Library to
Home. Migrate all three ArtistRow call sites (search, search/artists,
library/liked) to ArtistCard with grid wrapper; delete ArtistRow
component and its test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 20:27:53 -04:00

100 lines
3.5 KiB
Svelte

<script lang="ts">
import {
createLikedTracksInfiniteQuery,
createLikedAlbumsInfiniteQuery,
createLikedArtistsInfiniteQuery
} from '$lib/api/likes';
import ArtistCard from '$lib/components/ArtistCard.svelte';
import AlbumCard from '$lib/components/AlbumCard.svelte';
import TrackRow from '$lib/components/TrackRow.svelte';
const artistsStore = $derived(createLikedArtistsInfiniteQuery());
const albumsStore = $derived(createLikedAlbumsInfiniteQuery());
const tracksStore = $derived(createLikedTracksInfiniteQuery());
const artistsQuery = $derived($artistsStore);
const albumsQuery = $derived($albumsStore);
const tracksQuery = $derived($tracksStore);
const artists = $derived(artistsQuery?.data?.pages?.flatMap((p) => p.items) ?? []);
const albums = $derived(albumsQuery?.data?.pages?.flatMap((p) => p.items) ?? []);
const tracks = $derived(tracksQuery?.data?.pages?.flatMap((p) => p.items) ?? []);
const artistsTotal = $derived(artistsQuery?.data?.pages?.[0]?.total ?? 0);
const albumsTotal = $derived(albumsQuery?.data?.pages?.[0]?.total ?? 0);
const tracksTotal = $derived(tracksQuery?.data?.pages?.[0]?.total ?? 0);
</script>
<div class="space-y-6">
<h1 class="text-2xl font-semibold">Liked</h1>
<section>
<h2 class="mb-2 text-lg font-semibold">Artists</h2>
{#if artistsTotal === 0}
<p class="text-text-secondary">No liked artists yet.</p>
{:else}
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5">
{#each artists as a (a.id)}
<ArtistCard artist={a} />
{/each}
</div>
{#if artistsQuery?.hasNextPage}
<button
type="button"
class="mt-2 w-full rounded bg-surface py-2 text-sm hover:bg-surface-hover disabled:opacity-60"
disabled={artistsQuery.isFetchingNextPage}
onclick={() => artistsQuery.fetchNextPage()}
>
{artistsQuery.isFetchingNextPage ? 'Loading…' : 'Load more'}
</button>
{/if}
{/if}
</section>
<section>
<h2 class="mb-2 text-lg font-semibold">Albums</h2>
{#if albumsTotal === 0}
<p class="text-text-secondary">No liked albums yet.</p>
{:else}
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5">
{#each albums as al (al.id)}
<AlbumCard album={al} />
{/each}
</div>
{#if albumsQuery?.hasNextPage}
<button
type="button"
class="mt-2 w-full rounded bg-surface py-2 text-sm hover:bg-surface-hover disabled:opacity-60"
disabled={albumsQuery.isFetchingNextPage}
onclick={() => albumsQuery.fetchNextPage()}
>
{albumsQuery.isFetchingNextPage ? 'Loading…' : 'Load more'}
</button>
{/if}
{/if}
</section>
<section>
<h2 class="mb-2 text-lg font-semibold">Tracks</h2>
{#if tracksTotal === 0}
<p class="text-text-secondary">No liked tracks yet.</p>
{:else}
<div class="overflow-hidden rounded border border-border">
{#each tracks as t, i (t.id)}
<TrackRow tracks={tracks} index={i} />
{/each}
</div>
{#if tracksQuery?.hasNextPage}
<button
type="button"
class="mt-2 w-full rounded bg-surface py-2 text-sm hover:bg-surface-hover disabled:opacity-60"
disabled={tracksQuery.isFetchingNextPage}
onclick={() => tracksQuery.fetchNextPage()}
>
{tracksQuery.isFetchingNextPage ? 'Loading…' : 'Load more'}
</button>
{/if}
{/if}
</section>
</div>