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:
@@ -47,6 +47,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={$_("videos.title")} description={$_("videos.description")} />
|
||||
@@ -134,7 +149,7 @@
|
||||
<img
|
||||
src={getAssetUrl(video.image, "preview")}
|
||||
alt={video.title}
|
||||
class="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
|
||||
class="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300 bg-muted"
|
||||
/>
|
||||
|
||||
<!-- Overlay Gradient -->
|
||||
@@ -241,32 +256,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 } })}
|
||||
·
|
||||
{$_("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>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user