feat: improve UX across all listing pages and homepage

- Make model/video cards fully clickable on homepage, models, videos, magazine, and tags pages
- Replace inline blob divs with SexyBackground component on magazine and play pages
- Replace magazine hero section with PageHero component for consistency
- Remove redundant action buttons from cards (cards are now the link targets)
- Fix nested anchor/button invalid HTML in magazine featured article
- Convert inner overlay anchors to aria-hidden divs to avoid nested <a> elements
- Add bg-muted skeleton placeholder to all card images
- Update magazine pagination to smart numbered style with ellipsis (matching videos/models)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 18:41:39 +01:00
parent 1a2fab3e37
commit 291f72381f
5 changed files with 306 additions and 326 deletions

View File

@@ -44,6 +44,21 @@
}
const totalPages = $derived(Math.ceil(data.total / data.limit));
const pageNumbers = $derived(() => {
const pages: (number | -1)[] = [];
if (totalPages <= 7) {
for (let i = 1; i <= totalPages; i++) pages.push(i);
} else {
pages.push(1);
if (data.page > 3) pages.push(-1);
for (let i = Math.max(2, data.page - 1); i <= Math.min(totalPages - 1, data.page + 1); i++)
pages.push(i);
if (data.page < totalPages - 2) pages.push(-1);
pages.push(totalPages);
}
return pages;
});
</script>
<Meta title={$_("models.title")} description={$_("models.description")} />
@@ -97,7 +112,7 @@
<img
src={getAssetUrl(model.avatar, "preview")}
alt={model.artist_name}
class="w-full aspect-square object-cover group-hover:scale-105 transition-transform duration-300"
class="w-full aspect-square object-cover group-hover:scale-105 transition-transform duration-300 bg-muted"
/>
<!-- Online Status -->
@@ -183,31 +198,40 @@
<!-- Pagination -->
{#if totalPages > 1}
<div class="flex items-center justify-between mt-10">
<span class="text-sm text-muted-foreground">
{$_("common.page_of", { values: { page: data.page, total: totalPages } })}
&nbsp;·&nbsp;
{$_("common.total_results", { values: { total: data.total } })}
</span>
<div class="flex gap-2">
<div class="flex flex-col items-center gap-3 mt-10">
<div class="flex items-center gap-1">
<Button
variant="outline"
size="sm"
disabled={data.page <= 1}
onclick={() => goToPage(data.page - 1)}
class="border-primary/20 hover:bg-primary/10"
>
{$_("common.previous")}
</Button>
>{$_("common.previous")}</Button>
{#each pageNumbers() as p}
{#if p === -1}
<span class="px-2 text-muted-foreground select-none"></span>
{:else}
<Button
variant={p === data.page ? "default" : "outline"}
size="sm"
onclick={() => goToPage(p)}
class={p === data.page
? "bg-gradient-to-r from-primary to-accent min-w-9"
: "border-primary/20 hover:bg-primary/10 min-w-9"}
>{p}</Button>
{/if}
{/each}
<Button
variant="outline"
size="sm"
disabled={data.page >= totalPages}
onclick={() => goToPage(data.page + 1)}
class="border-primary/20 hover:bg-primary/10"
>
{$_("common.next")}
</Button>
>{$_("common.next")}</Button>
</div>
<p class="text-sm text-muted-foreground">
{$_("common.total_results", { values: { total: data.total } })}
</p>
</div>
</div>
{/if}