prepared and gallery fixes

This commit is contained in:
2026-02-19 08:36:32 +01:00
parent 8935065af1
commit c30fa5a392
36 changed files with 1437 additions and 104 deletions

View File

@@ -30,4 +30,4 @@
</ul>
</div>
@endsection
@endsection

View File

@@ -0,0 +1,63 @@
@extends('layouts.nova')
@php
use Carbon\Carbon;
use Illuminate\Support\Str;
@endphp
@section('content')
<div class="legacy-page">
<div class="mb-6">
<h1 class="text-2xl font-semibold text-white">Forum</h1>
<p class="mt-1 text-sm text-zinc-300">Browse forum sections and latest activity.</p>
</div>
<div class="overflow-hidden rounded-lg border border-white/10 bg-zinc-900/70">
<div class="border-b border-white/10 px-4 py-3 text-sm font-semibold text-zinc-100">Forum Sections</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-white/10 text-sm">
<thead class="bg-zinc-800/60 text-zinc-300">
<tr>
<th class="px-4 py-3 text-left font-medium">Section</th>
<th class="px-4 py-3 text-center font-medium">Posts</th>
<th class="px-4 py-3 text-center font-medium">Topics</th>
<th class="px-4 py-3 text-right font-medium">Last Update</th>
</tr>
</thead>
<tbody class="divide-y divide-white/10 text-zinc-100">
@forelse (($topics ?? []) as $topic)
@php
$topicId = (int) ($topic->topic_id ?? $topic->id ?? 0);
$topicTitle = $topic->topic ?? $topic->title ?? $topic->name ?? 'Untitled';
$topicSlug = Str::slug($topicTitle);
$topicUrl = $topicId > 0 ? route('legacy.forum.topic', ['topic_id' => $topicId, 'slug' => $topicSlug]) : '#';
@endphp
<tr class="hover:bg-white/5">
<td class="px-4 py-3 align-top">
<a class="font-medium text-sky-300 hover:text-sky-200" href="{{ $topicUrl }}">{{ $topicTitle }}</a>
@if (!empty($topic->discuss))
<div class="mt-1 text-xs text-zinc-400">{!! Str::limit(strip_tags((string) $topic->discuss), 180) !!}</div>
@endif
</td>
<td class="px-4 py-3 text-center text-zinc-300">{{ $topic->num_posts ?? 0 }}</td>
<td class="px-4 py-3 text-center text-zinc-300">{{ $topic->num_subtopics ?? 0 }}</td>
<td class="px-4 py-3 text-right text-zinc-400">
@if (!empty($topic->last_update))
{{ Carbon::parse($topic->last_update)->format('d.m.Y H:i') }}
@else
-
@endif
</td>
</tr>
@empty
<tr>
<td colspan="4" class="px-4 py-6 text-center text-zinc-400">No forum sections available.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,69 @@
@extends('layouts.nova')
@php
use Carbon\Carbon;
use Illuminate\Support\Str;
@endphp
@section('content')
@php
$headerTitle = data_get($topic ?? null, 'topic')
?? data_get($topic ?? null, 'title')
?? data_get($thread ?? null, 'title')
?? 'Thread';
$headerDesc = data_get($topic ?? null, 'discuss')
?? data_get($thread ?? null, 'content');
@endphp
<div class="legacy-page">
<div class="mb-6">
<a href="{{ route('legacy.forum.index') }}" class="text-sm text-sky-300 hover:text-sky-200"> Back to forum</a>
<h1 class="mt-2 text-2xl font-semibold text-white">{{ $headerTitle }}</h1>
@if (!empty($headerDesc))
<p class="mt-1 text-sm text-zinc-300">{!! Str::limit(strip_tags((string) $headerDesc), 260) !!}</p>
@endif
</div>
<div class="space-y-4">
@forelse (($posts ?? []) as $post)
@php
$authorName = $post->uname ?? data_get($post, 'user.name') ?? 'Anonymous';
$authorId = $post->user_id ?? data_get($post, 'user.id');
$postBody = $post->message ?? $post->content ?? '';
$postedAt = $post->post_date ?? $post->created_at ?? null;
@endphp
<article class="overflow-hidden rounded-lg border border-white/10 bg-zinc-900/70">
<header class="flex items-center justify-between border-b border-white/10 px-4 py-3">
<div class="text-sm font-semibold text-zinc-100">{{ $authorName }}</div>
<div class="text-xs text-zinc-400">
@if (!empty($postedAt))
{{ Carbon::parse($postedAt)->format('d.m.Y H:i') }}
@endif
</div>
</header>
<div class="px-4 py-4">
<div class="prose prose-invert max-w-none text-sm leading-6">
{!! $postBody !!}
</div>
@if (!empty($authorId))
<div class="mt-4 text-xs text-zinc-500">
User ID: {{ $authorId }}
</div>
@endif
</div>
</article>
@empty
<div class="rounded-lg border border-white/10 bg-zinc-900/70 px-4 py-6 text-center text-zinc-400">
No posts yet.
</div>
@endforelse
</div>
@if (isset($posts) && method_exists($posts, 'links'))
<div class="mt-4">{{ $posts->withQueryString()->links() }}</div>
@endif
</div>
@endsection

View File

@@ -0,0 +1,69 @@
@extends('layouts.nova')
@php
use Carbon\Carbon;
use Illuminate\Support\Str;
@endphp
@section('content')
<div class="legacy-page">
<div class="mb-6">
<a href="{{ route('legacy.forum.index') }}" class="text-sm text-sky-300 hover:text-sky-200"> Back to forum</a>
<h1 class="mt-2 text-2xl font-semibold text-white">{{ $topic->topic ?? $topic->title ?? 'Topic' }}</h1>
@if (!empty($topic->discuss))
<p class="mt-1 text-sm text-zinc-300">{!! Str::limit(strip_tags((string) $topic->discuss), 220) !!}</p>
@endif
</div>
<div class="overflow-hidden rounded-lg border border-white/10 bg-zinc-900/70">
<div class="border-b border-white/10 px-4 py-3 text-sm font-semibold text-zinc-100">Threads</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-white/10 text-sm">
<thead class="bg-zinc-800/60 text-zinc-300">
<tr>
<th class="px-4 py-3 text-left font-medium">Thread</th>
<th class="px-4 py-3 text-center font-medium">Posts</th>
<th class="px-4 py-3 text-center font-medium">By</th>
<th class="px-4 py-3 text-right font-medium">Last Update</th>
</tr>
</thead>
<tbody class="divide-y divide-white/10 text-zinc-100">
@forelse (($subtopics ?? []) as $sub)
@php
$id = (int) ($sub->topic_id ?? $sub->id ?? 0);
$title = $sub->topic ?? $sub->title ?? 'Untitled';
@endphp
<tr class="hover:bg-white/5">
<td class="px-4 py-3 align-top">
<a class="font-medium text-sky-300 hover:text-sky-200" href="{{ route('legacy.forum.topic', ['topic_id' => $id, 'slug' => Str::slug($title)]) }}">{{ $title }}</a>
@if (!empty($sub->discuss))
<div class="mt-1 text-xs text-zinc-400">{!! Str::limit(strip_tags((string) $sub->discuss), 180) !!}</div>
@endif
</td>
<td class="px-4 py-3 text-center text-zinc-300">{{ $sub->num_posts ?? 0 }}</td>
<td class="px-4 py-3 text-center text-zinc-300">{{ $sub->uname ?? 'Unknown' }}</td>
<td class="px-4 py-3 text-right text-zinc-400">
@if (!empty($sub->last_update))
{{ Carbon::parse($sub->last_update)->format('d.m.Y H:i') }}
@elseif (!empty($sub->post_date))
{{ Carbon::parse($sub->post_date)->format('d.m.Y H:i') }}
@else
-
@endif
</td>
</tr>
@empty
<tr>
<td colspan="4" class="px-4 py-6 text-center text-zinc-400">No threads in this section yet.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
@if (isset($subtopics) && method_exists($subtopics, 'links'))
<div class="mt-4">{{ $subtopics->withQueryString()->links() }}</div>
@endif
</div>
@endsection

View File

@@ -101,7 +101,7 @@
</div>
<div class="flex justify-center mt-10" data-gallery-pagination>
@if ($artworks instanceof \Illuminate\Contracts\Pagination\Paginator)
@if ($artworks instanceof \Illuminate\Contracts\Pagination\Paginator || $artworks instanceof \Illuminate\Contracts\Pagination\CursorPaginator)
{{ method_exists($artworks, 'withQueryString') ? $artworks->withQueryString()->links() : $artworks->links() }}
@endif
</div>
@@ -132,7 +132,39 @@
[data-nova-gallery].is-enhanced [data-gallery-grid] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
[data-nova-gallery].is-enhanced [data-gallery-grid] > .nova-card { margin: 0 !important; }
[data-nova-gallery].is-enhanced [data-gallery-pagination] { display: none; }
/* Keep pagination visible when JS enhances the gallery so users
have a clear navigation control (numeric links for length-aware
paginators, prev/next for cursor paginators). Make it compact. */
[data-nova-gallery].is-enhanced [data-gallery-pagination] {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
margin-top: 1.5rem;
}
[data-nova-gallery].is-enhanced [data-gallery-pagination] ul {
display: inline-flex;
gap: 0.25rem;
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
[data-nova-gallery].is-enhanced [data-gallery-pagination] li a,
[data-nova-gallery].is-enhanced [data-gallery-pagination] li span {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2.25rem;
height: 2.25rem;
border-radius: 0.5rem;
padding: 0 0.5rem;
background: rgba(255,255,255,0.03);
color: #e6eef8;
border: 1px solid rgba(255,255,255,0.04);
text-decoration: none;
font-size: 0.875rem;
}
[data-gallery-skeleton].is-loading { display: grid !important; grid-template-columns: inherit; gap: 1rem; }
.nova-skeleton-card {
border-radius: 1rem;

View File

@@ -0,0 +1,51 @@
@include('layouts._legacy')
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<title>{{ $page_title ?? 'Skinbase' }}</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ $page_meta_description ?? '' }}">
<meta name="keywords" content="{{ $page_meta_keywords ?? '' }}">
@isset($page_canonical)
<link rel="canonical" href="{{ $page_canonical }}" />
@endisset
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
<link rel="shortcut icon" href="/favicon.ico">
@vite(['resources/css/app.css','resources/scss/nova.scss','resources/js/nova.js'])
@stack('head')
</head>
<body class="bg-nova-900 text-white min-h-screen flex flex-col">
<div id="topbar-root"></div>
@include('layouts.nova.toolbar')
<main class="flex-1 pt-16">
<div class="mx-auto w-full max-w-7xl px-4 py-6 md:px-6 lg:px-8">
@hasSection('sidebar')
<div class="grid grid-cols-1 gap-6 xl:grid-cols-[minmax(0,1fr)_20rem]">
<section class="min-w-0">
@yield('content')
</section>
<aside class="xl:sticky xl:top-24 xl:self-start">
@yield('sidebar')
</aside>
</div>
@else
<section class="min-w-0">
@yield('content')
</section>
@endif
</div>
</main>
@include('layouts.nova.footer')
@stack('toolbar')
@stack('scripts')
</body>
</html>

View File

@@ -41,4 +41,4 @@
@endif
</div>
</div>
@endsection
@endsection

View File

@@ -70,4 +70,4 @@
@endif
</div>
@endsection
@endsection

View File

@@ -115,4 +115,4 @@
</div>
</div>
</div>
@endsection
@endsection

View File

@@ -49,4 +49,4 @@
@endforelse
</div>
</div>
@endsection
@endsection

View File

@@ -45,4 +45,4 @@
</script>
@endpush
@endsection
@endsection

View File

@@ -46,4 +46,4 @@
@if($artworks){{ $artworks->withQueryString()->links('pagination::bootstrap-4') }}@endif
</div>
</div>
@endsection
@endsection

View File

@@ -57,4 +57,4 @@
@endif
</div>
@endsection
@endsection

View File

@@ -1,46 +1,36 @@
{{-- Featured row (migrated from legacy/home/featured.blade.php) --}}
<div class="row featured-row">
<div class="col-md-4 col-sm-12">
<div class="featured-card effect2">
<div class="card-header">Featured Artwork</div>
<div class="card-body text-center">
<a href="/art/{{ data_get($featured, 'id') }}/{{ Str::slug(data_get($featured, 'name') ?? 'artwork') }}" class="thumb-link">
@php
$fthumb = data_get($featured, 'thumb_url') ?? data_get($featured, 'thumb');
@endphp
<img src="{{ $fthumb }}" class="img-responsive featured-img" alt="{{ data_get($featured, 'name') }}">
</a>
<div class="featured-title">{{ data_get($featured, 'name') }}</div>
<div class="featured-author">by {{ data_get($featured, 'uname') }}</div>
</div>
</div>
</div>
<div class="col-md-4 col-sm-12">
<div class="featured-card effect2">
<div class="card-header">Featured by Members Vote</div>
<div class="card-body text-center">
<a href="/art/{{ data_get($memberFeatured, 'id') }}/{{ Str::slug(data_get($memberFeatured, 'name') ?? 'artwork') }}" class="thumb-link">
@php
$mthumb = data_get($memberFeatured, 'thumb_url') ?? data_get($memberFeatured, 'thumb');
@endphp
<img src="{{ $mthumb }}" class="img-responsive featured-img" alt="{{ data_get($memberFeatured, 'name') }}">
</a>
<div class="featured-title">{{ data_get($memberFeatured, 'name') }}</div>
<div class="featured-author">by {{ data_get($memberFeatured, 'uname') }}</div>
</div>
{{-- Featured row use Nova cards for consistent layout with browse/gallery --}}
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
@if(!empty($featured))
<div>
@include('web.partials._artwork_card', ['art' => $featured])
</div>
</div>
@else
<div class="panel panel-default effect2">
<div class="panel-heading"><strong>Featured Artwork</strong></div>
<div class="panel-body text-neutral-400">No featured artwork set.</div>
</div>
@endif
<div class="col-md-4 col-sm-12">
<div class="featured-card join-card effect2">
<div class="card-header">Join to Skinbase World</div>
<div class="card-body text-center">
<a href="{{ route('register') }}" title="Join Skinbase">
<img src="/gfx/sb_join.jpg" alt="Join SkinBase Community" class="img-responsive join-img center-block">
</a>
<div class="join-text">Join to Skinbase and be part of our great community! We have big collection of high quality Photography, Wallpapers and Skins for popular applications.</div>
</div>
@if(!empty($memberFeatured))
<div>
@include('web.partials._artwork_card', ['art' => $memberFeatured])
</div>
@else
<div class="panel panel-default effect2">
<div class="panel-heading"><strong>Member Featured</strong></div>
<div class="panel-body text-neutral-400">No member featured artwork.</div>
</div>
@endif
<div>
<div class="group relative block overflow-hidden rounded-2xl ring-1 ring-white/5 bg-black/20 shadow-lg p-4 text-center">
<a href="{{ route('register') }}" title="Join Skinbase" class="inline-block mb-3">
<img src="/gfx/sb_join.jpg" alt="Join SkinBase Community" class="w-full h-40 object-cover rounded-lg">
</a>
<div class="text-lg font-semibold text-white/90">Join Skinbase World</div>
<p class="mt-2 text-sm text-neutral-400">Join Skinbase and be part of our community. Upload, share and explore curated photography and skins.</p>
<a href="{{ route('register') }}" class="mt-3 inline-block px-4 py-2 rounded-md bg-sky-500 text-white">Create an account</a>
</div>
</div>
</div>

View File

@@ -1,14 +1,47 @@
{{-- Latest uploads grid (migrated from legacy/home/uploads.blade.php) --}}
<div class="gallery-grid">
@foreach ($latestUploads as $upload)
<div class="thumb-card effect2">
@php
$t = \App\Services\ThumbnailPresenter::present($upload, 'md');
@endphp
<a href="/art/{{ $t['id'] }}/{{ Str::slug($t['title'] ?: 'artwork') }}" title="{{ $t['title'] }}" class="thumb-link">
<img src="{{ $t['url'] }}" @if(!empty($t['srcset'])) srcset="{{ $t['srcset'] }}" @endif alt="{{ $t['title'] }}" class="img-responsive">
</a>
</div>
@endforeach
</div> <!-- end .gallery-grid -->
{{-- Latest uploads grid use same Nova gallery layout as /browse --}}
<section class="px-6 pb-10 pt-6 md:px-10" data-nova-gallery data-gallery-type="home-uploads">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" data-gallery-grid>
@forelse($latestUploads as $upload)
@include('web.partials._artwork_card', ['art' => $upload])
@empty
<div class="panel panel-default effect2">
<div class="panel-heading"><strong>No uploads yet</strong></div>
<div class="panel-body text-neutral-400">No recent uploads to show.</div>
</div>
@endforelse
</div>
<div class="flex justify-center mt-10" data-gallery-pagination>
{{-- no pagination for home grid; kept for parity with browse layout --}}
</div>
<div class="hidden mt-8" data-gallery-skeleton></div>
</section>
@push('styles')
<style>
[data-nova-gallery].is-enhanced [data-gallery-grid] {
display: grid;
grid-template-columns: repeat(1, minmax(0, 1fr));
grid-auto-rows: 8px;
gap: 1rem;
}
@media (min-width: 768px) {
[data-nova-gallery].is-enhanced [data-gallery-grid] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
[data-nova-gallery].is-enhanced [data-gallery-grid] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 2600px) {
[data-nova-gallery].is-enhanced [data-gallery-grid] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
[data-nova-gallery].is-enhanced [data-gallery-grid] > .nova-card { margin: 0 !important; }
[data-nova-gallery].is-enhanced [data-gallery-pagination] { display: none; }
[data-gallery-skeleton].is-loading { display: grid !important; grid-template-columns: inherit; gap: 1rem; }
</style>
@endpush
@push('scripts')
<script src="/js/legacy-gallery-init.js" defer></script>
@endpush