feat: ship creator journey v2 and profile updates

This commit is contained in:
2026-04-12 21:42:07 +02:00
parent a2457f4e49
commit d5cff21ea2
335 changed files with 20147 additions and 1545 deletions

View File

@@ -26,6 +26,7 @@
<img
src="{{ $item->thumb_url ?? '' }}"
@if(!empty($item->thumb_srcset)) srcset="{{ $item->thumb_srcset }}" @endif
sizes="(max-width: 768px) 176px, 208px"
alt="{{ $item->name ?? 'Featured artwork' }}"
loading="lazy"
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"

View File

@@ -26,6 +26,7 @@
'profile_url' => $art->profile_url ?? null,
'published_as_type' => $art->published_as_type ?? null,
'publisher' => $art->publisher ?? null,
'maturity' => $art->maturity ?? null,
'category_name' => $art->category_name ?? '',
'category_slug' => $art->category_slug ?? '',
'width' => $art->width ?? null,

View File

@@ -4,10 +4,16 @@
@push('head')
{{-- Preload hero image for faster LCP --}}
@if(!empty($props['hero']['thumb_lg']))
<link rel="preload" as="image" href="{{ $props['hero']['thumb_lg'] }}">
@if(!empty($props['hero']['thumb']) || !empty($props['hero']['thumb_lg']))
<link
rel="preload"
as="image"
href="{{ $props['hero']['thumb_lg'] ?? $props['hero']['thumb'] }}"
@if(!empty($props['hero']['thumb_srcset'])) imagesrcset="{{ $props['hero']['thumb_srcset'] }}" imagesizes="100vw" @endif
fetchpriority="high"
>
@elseif(!empty($props['hero']['thumb']))
<link rel="preload" as="image" href="{{ $props['hero']['thumb'] }}">
<link rel="preload" as="image" href="{{ $props['hero']['thumb'] }}" fetchpriority="high">
@endif
@endpush
@@ -21,17 +27,18 @@
{!! json_encode($props, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) !!}
</script>
<div id="homepage-root" class="min-h-[40vh]">
{{-- Loading skeleton (replaced by React on hydration) --}}
<div class="space-y-10 px-4 pt-10 sm:px-6 lg:px-8">
<div class="h-14 rounded-2xl bg-nova-800/70"></div>
<div class="grid gap-4 lg:grid-cols-4">
<div class="aspect-video rounded-2xl bg-nova-800/70"></div>
<div class="aspect-video rounded-2xl bg-nova-800/70"></div>
<div class="aspect-video rounded-2xl bg-nova-800/70"></div>
<div class="aspect-video rounded-2xl bg-nova-800/70"></div>
</div>
</div>
<div id="homepage-root">
@if(!empty($props['is_logged_in']))
@include('web.home.skeleton-sections', [
'showWelcomeSpacer' => true,
'variants' => ['gallery', 'gallery', 'gallery', 'gallery', 'gallery', 'gallery', 'gallery', 'gallery', 'collections', 'groups', 'categories', 'creators', 'tags', 'creators', 'news', 'cta'],
])
@else
@include('web.home.skeleton-sections', [
'showWelcomeSpacer' => false,
'variants' => ['gallery', 'gallery', 'gallery', 'gallery', 'gallery', 'collections', 'groups', 'categories', 'tags', 'creators', 'news', 'cta'],
])
@endif
</div>
@vite(['resources/js/Pages/Home/HomePage.jsx'])

View File

@@ -2,6 +2,8 @@
$heroArtwork = $artwork ?? null;
$fallbackImage = 'https://files.skinbase.org/default/missing_lg.webp';
$heroImage = $heroArtwork['thumb_lg'] ?? $heroArtwork['thumb'] ?? $fallbackImage;
$heroImageSrcset = $heroArtwork['thumb_srcset'] ?? null;
$heroImageSizes = '100vw';
@endphp
@if (!$heroArtwork)
@@ -15,19 +17,23 @@
Discover. Create. Inspire.
</p>
<div class="mt-4 flex flex-wrap gap-3">
<a href="/discover/trending" class="rounded-xl bg-accent px-5 py-2 text-sm font-semibold text-white shadow-lg transition hover:brightness-110">Explore Trending</a>
<a href="/discover/trending" class="btn-accent-solid rounded-xl px-5 py-2 text-sm font-semibold">Explore Trending</a>
</div>
</div>
</section>
@else
<section class="group relative flex min-h-[62vh] max-h-[420px] w-full items-end overflow-hidden bg-nova-900 md:min-h-[38vh] md:max-h-[460px]">
<img
src="{{ $heroImage }}"
alt="{{ $heroArtwork['title'] ?? 'Featured artwork' }}"
class="absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-[1.02]"
fetchpriority="high"
decoding="async"
/>
<picture>
<img
src="{{ $heroImage }}"
@if($heroImageSrcset) srcset="{{ $heroImageSrcset }}" sizes="{{ $heroImageSizes }}" @endif
alt="{{ $heroArtwork['title'] ?? 'Featured artwork' }}"
class="absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-[1.02]"
fetchpriority="high"
loading="eager"
decoding="sync"
/>
</picture>
<div class="pointer-events-none absolute inset-0 bg-gradient-to-t from-nova-900 via-nova-900/55 to-transparent"></div>
@@ -47,7 +53,7 @@
<div class="mt-4 flex flex-wrap gap-3">
<a
href="/discover/trending"
class="rounded-xl bg-accent px-5 py-2 text-sm font-semibold text-white shadow-lg transition hover:brightness-110"
class="btn-accent-solid rounded-xl px-5 py-2 text-sm font-semibold"
>
Explore Trending
</a>

View File

@@ -0,0 +1,67 @@
@if(!empty($showWelcomeSpacer))
<div class="mt-10 px-4 sm:px-6 lg:px-8" aria-hidden="true">
<div class="h-20 animate-pulse rounded-[28px] border border-white/10 bg-nova-800/70"></div>
</div>
@endif
@foreach(($variants ?? []) as $variant)
@if($variant === 'tags')
<section class="mt-14 px-4 sm:px-6 lg:px-8" aria-hidden="true">
<div class="mb-5 h-8 w-48 animate-pulse rounded-xl bg-nova-800/70"></div>
<div class="flex flex-wrap gap-2">
<div class="h-9 w-24 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-32 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-28 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-36 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-24 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-32 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-28 animate-pulse rounded-full bg-nova-800/70"></div>
<div class="h-9 w-36 animate-pulse rounded-full bg-nova-800/70"></div>
</div>
</section>
@elseif($variant === 'cta')
<section class="mt-14 px-4 sm:px-6 lg:px-8" aria-hidden="true">
<div class="h-40 animate-pulse rounded-[28px] border border-white/10 bg-nova-800/70"></div>
</section>
@else
@php
$showSubtitle = in_array($variant, ['collections', 'groups', 'news'], true);
$gridClass = match ($variant) {
'creators' => 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',
'news' => 'grid-cols-1',
'categories' => 'grid-cols-2 lg:grid-cols-4',
'collections' => 'grid-cols-1 lg:grid-cols-2 xl:grid-cols-3',
'groups' => 'grid-cols-1 sm:grid-cols-2 xl:grid-cols-4',
default => 'grid-cols-2 xl:grid-cols-4',
};
$cardClass = match ($variant) {
'categories' => 'h-28 rounded-2xl',
'news' => 'h-24 rounded-2xl',
'creators' => 'h-64 rounded-2xl',
'collections', 'groups' => 'h-80 rounded-[28px]',
default => 'aspect-[4/3] rounded-2xl',
};
$cardCount = match ($variant) {
'creators' => 6,
'news' => 4,
default => 4,
};
@endphp
<section class="mt-14 px-4 sm:px-6 lg:px-8" aria-hidden="true">
<div class="mb-5 flex items-center justify-between gap-4">
<div>
<div class="h-8 w-48 animate-pulse rounded-xl bg-nova-800/70"></div>
@if($showSubtitle)
<div class="mt-3 h-4 w-80 max-w-full animate-pulse rounded bg-nova-800/60"></div>
@endif
</div>
<div class="hidden h-5 w-24 animate-pulse rounded bg-nova-800/60 sm:block"></div>
</div>
<div class="grid gap-4 {{ $gridClass }}">
@for($i = 0; $i < $cardCount; $i++)
<div class="animate-pulse bg-nova-800/70 {{ $cardClass }}"></div>
@endfor
</div>
</section>
@endif
@endforeach

View File

@@ -70,12 +70,14 @@
<input
id="tags-search"
type="search"
role="combobox"
name="q"
value="{{ $query }}"
placeholder="Search aesthetics, games, styles..."
autocomplete="off"
spellcheck="false"
aria-autocomplete="list"
aria-haspopup="listbox"
aria-expanded="false"
aria-controls="tags-search-suggestions"
data-tags-search-input