Upload beautify

This commit is contained in:
2026-02-17 17:14:43 +01:00
parent b053c0cc48
commit 41287914aa
106 changed files with 4948 additions and 906 deletions

View File

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

View File

@@ -3,9 +3,7 @@
$size = $size ?? 128;
$profile = $user->profile ?? null;
$hash = $profile->avatar_hash ?? null;
$src = $hash
? asset("storage/avatars/{$user->id}/{$size}.webp?v={$hash}")
: asset('img/default-avatar.webp');
$src = \App\Support\AvatarUrl::forUser((int) $user->id, $hash, (int) $size);
$alt = $alt ?? ($user->username ?? 'avatar');
$class = $class ?? 'rounded-full';
@endphp

View File

@@ -0,0 +1,50 @@
<!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

@@ -1,82 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ $page_title ?? 'Skinbase' }}</title>
<meta name="description" content="{{ $page_meta_description ?? '' }}">
<meta name="keywords" content="{{ $page_meta_keywords ?? '' }}">
<meta name="robots" content="index,follow">
<meta name="revisit" content="1 day">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="{{ config('app.url', '//localhost:8000') }}/">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/css/style.css">
<link rel="stylesheet" type="text/css" href="/css/custom-legacy.css">
@stack('head')
</head>
<body style="padding-top:60px;">
<div id="fb-root"></div>
@include('legacy.toolbar')
<div class="wrapper">
<div class="col-top main_content">
<div id="main_box_page">
@yield('content')
</div>
{{-- Right sidebar placeholder (legacy layout) --}}
<div id="right_box_page" class="hideme">
@yield('sidebar')
</div>
</div>
<div class="push"></div>
</div>
{{-- Toolbar placeholder --}}
@stack('toolbar')
<footer id="mainFooter">
<p>&copy; 2000 - {{ date('Y') }} by SkinBase.org. All artwork copyrighted to its Author. (Dragon II Edition)</p>
<div class="footer_links">
<a href="/bug-report" title="Inform us about any bugs you found">Bug report</a> :
<a href="/rss-feeds" title="Skinbase RSS Feeds about new Artworks">RSS Feeds</a> :
<a href="/faq" title="Frequently Asked Questions">FAQ</a> :
<a href="/rules" title="Rules and Guidelines">Rules and Guidelines</a> :
<a href="/staff" title="Who is actually behind Skinbase">Staff</a> :
<a href="/privacy" title="Privacy Policy">Privacy Policy</a>
</div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.2.1/jquery-migrate.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.0/isotope.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<script src="/js/stickysidebar.jquery.min.js"></script>
<script>
if (window.jQuery) {
(function($){
if (typeof $.fn.stick_in_parent === 'undefined') {
if (typeof $.fn.stickySidebar !== 'undefined') {
$.fn.stick_in_parent = function(){
return this.each(function(){ $(this).stickySidebar(); });
};
} else {
$.fn.stick_in_parent = function(){ return this; };
}
}
})(jQuery);
}
</script>
<script src="/js/script.js"></script>
@stack('scripts')
</body>
</html>

View File

@@ -1,213 +1,240 @@
<header class="fixed inset-x-0 top-0 z-50 h-16 bg-nova border-b border-panel">
<div class="mx-auto w-full h-full px-4 flex items-center gap-3">
<!-- Mobile hamburger -->
<button id="btnSidebar" class="md:hidden inline-flex items-center justify-center w-10 h-10 rounded-lg hover:bg-white/5">
<!-- bars -->
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
<!-- Logo -->
<a href="/" class="flex items-center gap-2 pr-2">
<img src="/gfx/sb_logo.png" alt="Skinbase.org" class="h-8 w-auto rounded-sm shadow-sm object-contain">
<span class="sr-only">Skinbase.org</span>
</a>
<!-- Left nav -->
<nav class="hidden lg:flex items-center gap-4 text-sm text-soft">
<div class="relative">
<button class="hover:text-white inline-flex items-center gap-1" data-dd="browse">
Browse
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"/>
</svg>
<div class="mx-auto w-full h-full px-4 flex items-center gap-3">
<!-- Mobile hamburger -->
<button id="btnSidebar"
class="md:hidden inline-flex items-center justify-center w-10 h-10 rounded-lg hover:bg-white/5">
<!-- bars -->
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
<div id="dd-browse" class="hidden absolute left-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-visible">
<div class="rounded-lg overflow-hidden">
<div class="px-4 dd-section">Views</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/forum"><i class="fa-solid fa-comments mr-3 text-sb-muted"></i>Forum</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/chat"><i class="fa-solid fa-message mr-3 text-sb-muted"></i>Chat</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/sections"><i class="fa-solid fa-folder-open mr-3 text-sb-muted"></i>Browse Sections</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/uploads/latest"><i class="fa-solid fa-cloud-arrow-up mr-3 text-sb-muted"></i>Latest Uploads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/uploads/daily"><i class="fa-solid fa-calendar-day mr-3 text-sb-muted"></i>Daily Uploads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/today-in-history"><i class="fa-solid fa-calendar mr-3 text-sb-muted"></i>Today In History</a>
<!-- Logo -->
<a href="/" class="flex items-center gap-2 pr-2">
<img src="/gfx/sb_logo.png" alt="Skinbase.org" class="h-8 w-auto rounded-sm shadow-sm object-contain">
<span class="sr-only">Skinbase.org</span>
</a>
<div class="px-4 dd-section">Authors</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/interviews"><i class="fa-solid fa-microphone mr-3 text-sb-muted"></i>Interviews</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/members/photos"><i class="fa-solid fa-camera mr-3 text-sb-muted"></i>Members Photos</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/authors/top"><i class="fa-solid fa-star mr-3 text-sb-muted"></i>Top Authors</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/comments/latest"><i class="fa-solid fa-comments mr-3 text-sb-muted"></i>Latest Comments</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/comments/monthly"><i class="fa-solid fa-chart-line mr-3 text-sb-muted"></i>Monthly Commented</a>
<!-- Left nav -->
<nav class="hidden lg:flex items-center gap-4 text-sm text-soft">
<div class="px-4 dd-section">Statistics</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/downloads/today"><i class="fa-solid fa-download mr-3 text-sb-muted"></i>Todays Downloads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/favourites/top"><i class="fa-solid fa-heart mr-3 text-sb-muted"></i>Top Favourites</a>
<div class="relative">
<button class="hover:text-white inline-flex items-center gap-1" data-dd="browse">
Browse
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6" /></svg>
</button>
<div id="dd-browse" class="hidden absolute left-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-visible">
<div class="rounded-lg overflow-hidden">
<div class="px-4 dd-section">Views</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/forum"><i class="fa-solid fa-comments mr-3 text-sb-muted"></i>Forum</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/chat"><i class="fa-solid fa-message mr-3 text-sb-muted"></i>Chat</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/sections"><i class="fa-solid fa-folder-open mr-3 text-sb-muted"></i>Browse Sections</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/uploads/latest"><i class="fa-solid fa-cloud-arrow-up mr-3 text-sb-muted"></i>Latest Uploads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/uploads/daily"><i class="fa-solid fa-calendar-day mr-3 text-sb-muted"></i>Daily Uploads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/today-in-history"><i class="fa-solid fa-calendar mr-3 text-sb-muted"></i>Today In History</a>
</div>
<div class="px-4 dd-section">Authors</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/interviews"><i class="fa-solid fa-microphone mr-3 text-sb-muted"></i>Interviews</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/members/photos"><i class="fa-solid fa-camera mr-3 text-sb-muted"></i>Members Photos</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/authors/top"><i class="fa-solid fa-star mr-3 text-sb-muted"></i>Top Authors</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/comments/latest"><i class="fa-solid fa-comments mr-3 text-sb-muted"></i>Latest Comments</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/comments/monthly"><i class="fa-solid fa-chart-line mr-3 text-sb-muted"></i>Monthly Commented</a>
<div class="px-4 dd-section">Statistics</div>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/downloads/today"><i class="fa-solid fa-download mr-3 text-sb-muted"></i>Todays Downloads</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/favourites/top"><i class="fa-solid fa-heart mr-3 text-sb-muted"></i>Top Favourites</a>
</div> <!-- end .rounded-lg -->
</div> <!-- end .dd-browse -->
</div> <!-- end .relative -->
<div class="relative">
<button class="hover:text-white inline-flex items-center gap-1" data-dd="cats">
Categories
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M6 9l6 6 6-6" />
</svg>
</button>
<div id="dd-cats"
class="hidden absolute left-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-hidden">
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/browse">All Artworks</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/photography">Photography</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/wallpapers">Wallpapers</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/skins">Skins</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/other">Other</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/featured-artworks">Featured Artwork</a>
</div>
</div>
</nav>
<!-- Search -->
<div class="flex-1 flex items-center justify-center">
<div class="w-full max-w-lg relative">
<input
class="w-full h-10 rounded-lg bg-black/20 border border-sb-line pl-4 pr-12 text-sm text-white placeholder:text-sb-muted/80 outline-none focus:border-sb-blue/60"
placeholder="Search tags, artworks, artists..." />
<button
class="absolute right-2 top-1/2 -translate-y-1/2 w-9 h-9 rounded-md hover:bg-white/5 text-sb-muted hover:text-white">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<circle cx="11" cy="11" r="7" />
<path d="M20 20l-3.5-3.5" />
</svg>
</button>
</div>
</div>
</div>
<div class="relative">
<button class="hover:text-white inline-flex items-center gap-1" data-dd="cats">
Categories
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"/>
</svg>
</button>
<div id="dd-cats" class="hidden absolute left-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-hidden">
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/browse">All Artworks</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/photography">Photography</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/wallpapers">Wallpapers</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/skins">Skins</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/other">Other</a>
<a class="block px-4 py-2 text-sm hover:bg-white/5" href="/featured-artworks">Featured Artwork</a>
@auth
<!-- Right icon counters (authenticated users) -->
<div class="hidden md:flex items-center gap-3 text-soft">
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M12 5v14M5 12h14" />
</svg>
</button>
</div>
</div>
</nav>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M12 21s-7-4.4-9-9a5.5 5.5 0 0 1 9-6 5.5 5.5 0 0 1 9 6c-2 4.6-9 9-9 9z" />
</svg>
<span
class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $uploadCount ?? 0 }}</span>
</button>
<!-- Search -->
<div class="flex-1 flex items-center justify-center">
<div class="w-full max-w-lg relative">
<input
class="w-full h-10 rounded-lg bg-black/20 border border-sb-line pl-4 pr-12 text-sm text-white placeholder:text-sb-muted/80 outline-none focus:border-sb-blue/60"
placeholder="Search tags, artworks, artists..."
/>
<button class="absolute right-2 top-1/2 -translate-y-1/2 w-9 h-9 rounded-md hover:bg-white/5 text-sb-muted hover:text-white">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="7"/>
<path d="M20 20l-3.5-3.5"/>
</svg>
</button>
</div>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M4 4h16v14H5.2L4 19.2V4z" />
<path d="M4 6l8 6 8-6" />
</svg>
<span
class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $favCount ?? 0 }}</span>
</button>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M18 8a6 6 0 10-12 0c0 7-3 7-3 7h18s-3 0-3-7" />
<path d="M13.7 21a2 2 0 01-3.4 0" />
</svg>
<span
class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $msgCount ?? 0 }}</span>
</button>
<!-- User dropdown -->
<div class="relative">
<button class="flex items-center gap-2 pl-2 pr-3 h-10 rounded-lg hover:bg-white/5" data-dd="user">
<img class="w-7 h-7 rounded-full object-cover ring-1 ring-white/10"
src="{{ \App\Support\AvatarUrl::forUser((int) ($userId ?? (Auth::id() ?? 0)), $avatarHash ?? null, 64) }}"
alt="{{ $displayName ?? 'User' }}" />
<span class="text-sm text-white/90">{{ $displayName ?? 'User' }}</span>
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M6 9l6 6 6-6" />
</svg>
</button>
<div id="dd-user"
class="hidden absolute right-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-hidden">
<div class="px-4 dd-section">My Account</div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/upload">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-upload text-sb-muted"></i></span>
Upload
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/gallery">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-image text-sb-muted"></i></span>
My Gallery
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/artworks">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-pencil text-sb-muted"></i></span>
Edit Artworks
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/stats">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-chart-line text-sb-muted"></i></span>
Statistics
</a>
<div class="px-4 dd-section">Community</div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/followers">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-user-group text-sb-muted"></i></span>
Followers
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/following">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-user-plus text-sb-muted"></i></span>
Following
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/comments">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-comments text-sb-muted"></i></span>
Comments
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/favourites">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-heart text-sb-muted"></i></span>
Favourites
</a>
<div class="px-4 dd-section">Community</div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/profile">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-eye text-sb-muted"></i></span>
View My Profile
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/user">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-cog text-sb-muted"></i></span>
Edit Profile
</a>
<div class="px-4 dd-section">System</div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/logout">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i
class="fa-solid fa-sign-out text-sb-muted"></i></span>
Logout
</a>
</div>
</div>
</div>
@else
<!-- Guest: show simple Join / Sign in links -->
<div class="hidden md:flex items-center gap-3">
<a href="/signup"
class="px-3 py-2 rounded-lg text-sm text-sb-muted hover:text-white hover:bg-white/5">Join</a>
<a href="/login"
class="px-3 py-2 rounded-lg text-sm text-sb-muted hover:text-white hover:bg-white/5">Sign in</a>
</div>
@endauth
</div>
@auth
<!-- Right icon counters (authenticated users) -->
<div class="hidden md:flex items-center gap-3 text-soft">
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 5v14M5 12h14"/>
</svg>
</button>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 21s-7-4.4-9-9a5.5 5.5 0 0 1 9-6 5.5 5.5 0 0 1 9 6c-2 4.6-9 9-9 9z"/>
</svg>
<span class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $uploadCount ?? 0 }}</span>
</button>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 4h16v14H5.2L4 19.2V4z"/>
<path d="M4 6l8 6 8-6"/>
</svg>
<span class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $favCount ?? 0 }}</span>
</button>
<button class="relative w-10 h-10 rounded-lg hover:bg-white/5">
<svg class="w-5 h-5 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 8a6 6 0 10-12 0c0 7-3 7-3 7h18s-3 0-3-7"/>
<path d="M13.7 21a2 2 0 01-3.4 0"/>
</svg>
<span class="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">{{ $msgCount ?? 0 }}</span>
</button>
<!-- User dropdown -->
<div class="relative">
<button class="flex items-center gap-2 pl-2 pr-3 h-10 rounded-lg hover:bg-white/5" data-dd="user">
<img class="w-7 h-7 rounded-full object-cover ring-1 ring-white/10"
src="{{ url('/avatar/' . ($userId ?? Auth::id() ?? 0) . '/' . ($avatar ? rawurlencode(basename($avatar)) : '1.png')) }}"
alt="{{ $displayName ?? 'User' }}" />
<span class="text-sm text-white/90">{{ $displayName ?? 'User' }}</span>
<svg class="w-4 h-4 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"/>
</svg>
</button>
<div id="dd-user" class="hidden absolute right-0 mt-2 w-64 rounded-lg bg-panel border border-panel shadow-sb overflow-hidden">
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/upload">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-upload text-sb-muted"></i></span>
Upload
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/artworks">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-pencil text-sb-muted"></i></span>
Edit Artworks
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/stats">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-chart-line text-sb-muted"></i></span>
Statistics
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/followers">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-user-group text-sb-muted"></i></span>
My Followers
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/following">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-user-plus text-sb-muted"></i></span>
Who I Follow
</a>
<div class="h-px bg-panel/80 my-1"></div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/comments">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-comments text-sb-muted"></i></span>
Received Comments
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/favourites">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-heart text-sb-muted"></i></span>
My Favourites
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/my/gallery">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-image text-sb-muted"></i></span>
My Gallery
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/settings">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-cog text-sb-muted"></i></span>
Edit Profile
</a>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/profile">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-eye text-sb-muted"></i></span>
View My Profile
</a>
<div class="h-px bg-panel/80 my-1"></div>
<a class="flex items-center gap-3 px-4 py-2 text-sm hover:bg-white/5" href="/logout">
<span class="w-8 h-8 rounded-lg bg-white/5 inline-flex items-center justify-center mr-3"><i class="fa-solid fa-sign-out text-sb-muted"></i></span>
Logout
</a>
</div>
</div>
</div>
@else
<!-- Guest: show simple Join / Sign in links -->
<div class="hidden md:flex items-center gap-3">
<a href="/signup" class="px-3 py-2 rounded-lg text-sm text-sb-muted hover:text-white hover:bg-white/5">Join</a>
<a href="/login" class="px-3 py-2 rounded-lg text-sm text-sb-muted hover:text-white hover:bg-white/5">Sign in</a>
</div>
@endauth
</div>
</header>
<!-- MOBILE MENU -->
<div class="hidden fixed top-16 left-0 right-0 bg-neutral-950 border-b border-neutral-800 p-4" id="mobileMenu">
<div class="space-y-2">
@guest
<a class="block py-2 border-b border-neutral-900" href="/signup">Join</a>
<a class="block py-2 border-b border-neutral-900" href="/login">Sign in</a>
@endguest
<a class="block py-2 border-b border-neutral-900" href="/browse">All Artworks</a>
<a class="block py-2 border-b border-neutral-900" href="/photography">Photography</a>
<a class="block py-2 border-b border-neutral-900" href="/wallpapers">Wallpapers</a>
<a class="block py-2 border-b border-neutral-900" href="/skins">Skins</a>
<a class="block py-2 border-b border-neutral-900" href="/other">Other</a>
<a class="block py-2 border-b border-neutral-900" href="/featured-artworks">Featured</a>
<a class="block py-2 border-b border-neutral-900" href="/forum">Forum</a>
<a class="block py-2 border-b border-neutral-900" href="/profile">Profile</a>
<a class="block py-2" href="/settings">Settings</a>
</div>
<div class="space-y-2">
@guest
<a class="block py-2 border-b border-neutral-900" href="/signup">Join</a>
<a class="block py-2 border-b border-neutral-900" href="/login">Sign in</a>
@endguest
<a class="block py-2 border-b border-neutral-900" href="/browse">All Artworks</a>
<a class="block py-2 border-b border-neutral-900" href="/photography">Photography</a>
<a class="block py-2 border-b border-neutral-900" href="/wallpapers">Wallpapers</a>
<a class="block py-2 border-b border-neutral-900" href="/skins">Skins</a>
<a class="block py-2 border-b border-neutral-900" href="/other">Other</a>
<a class="block py-2 border-b border-neutral-900" href="/featured-artworks">Featured</a>
<a class="block py-2 border-b border-neutral-900" href="/forum">Forum</a>
<a class="block py-2 border-b border-neutral-900" href="/profile">Profile</a>
<a class="block py-2" href="/settings">Settings</a>
</div>
</div>

View File

@@ -1,115 +1,2 @@
@php
// If a Collection or array was passed accidentally, pick the first item.
if (isset($art) && (is_array($art) || $art instanceof Illuminate\Support\Collection || $art instanceof Illuminate\Database\Eloquent\Collection)) {
$first = null;
if (is_array($art)) {
$first = reset($art);
} elseif ($art instanceof Illuminate\Support\Collection || $art instanceof Illuminate\Database\Eloquent\Collection) {
$first = $art->first();
}
if ($first) {
$art = $first;
}
}
$title = trim((string) ($art->name ?? $art->title ?? 'Untitled artwork'));
$author = trim((string) ($art->uname ?? $art->author_name ?? $art->author ?? 'Skinbase'));
$category = trim((string) ($art->category_name ?? $art->category ?? 'General'));
$license = trim((string) ($art->license ?? 'Standard'));
$resolution = trim((string) ($art->resolution ?? ((isset($art->width, $art->height) && $art->width && $art->height) ? ($art->width . '×' . $art->height) : '')));
// Safe integer extractor: handle numeric, arrays, Collections, or relations
$safeInt = function ($v, $fallback = 0) {
if (is_numeric($v)) return (int) $v;
if (is_array($v)) return count($v);
if (is_object($v)) {
// Eloquent Collections implement Countable and have count()
if (method_exists($v, 'count')) return (int) $v->count();
if ($v instanceof Countable) return (int) count($v);
}
return (int) $fallback;
};
$likes = $safeInt($art->likes ?? $art->favourites ?? 0);
$downloads = $safeInt($art->downloads ?? $art->downloaded ?? 0);
$img_src = (string) ($art->thumb ?? $art->thumbnail_url ?? '/images/placeholder.jpg');
$img_srcset = (string) ($art->thumb_srcset ?? $art->thumbnail_srcset ?? $img_src);
$img_avif_srcset = (string) ($art->thumb_avif_srcset ?? $img_srcset);
$img_webp_srcset = (string) ($art->thumb_webp_srcset ?? $img_srcset);
// Width/height may be stored directly or as a related object; handle safely
$resolveDimension = function ($val, $fallback) {
if (is_numeric($val)) return (int) $val;
if (is_array($val)) {
$v = reset($val);
return is_numeric($v) ? (int) $v : (int) $fallback;
}
if (is_object($val)) {
if (method_exists($val, 'first')) {
$f = $val->first();
if (is_object($f) && isset($f->width)) return (int) ($f->width ?: $fallback);
if (is_object($f) && isset($f->height)) return (int) ($f->height ?: $fallback);
}
// Try numeric cast otherwise
if (isset($val->width)) return (int) $val->width;
if (isset($val->height)) return (int) $val->height;
}
return (int) $fallback;
};
$img_width = max(1, $resolveDimension($art->width ?? null, 800));
$img_height = max(1, $resolveDimension($art->height ?? null, 600));
$contentUrl = $img_src;
$cardUrl = (string) ($art->url ?? '#');
@endphp
<article class="nova-card artwork" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="name" content="{{ $title }}">
<meta itemprop="contentUrl" content="{{ $contentUrl }}">
<meta itemprop="creator" content="{{ $author }}">
<meta itemprop="license" content="{{ $license }}">
<a href="{{ $cardUrl }}" itemprop="url" class="group relative block overflow-hidden rounded-2xl ring-1 ring-white/5 bg-black/20 shadow-lg shadow-black/40 transition-all duration-200 ease-out hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/70">
@if(!empty($category))
<div class="absolute left-3 top-3 z-30 rounded-md bg-black/55 px-2 py-1 text-xs text-white backdrop-blur-sm">{{ $category }}</div>
@endif
<div class="nova-card-media relative aspect-[16/10] overflow-hidden bg-neutral-900">
<picture>
<source srcset="{{ $img_avif_srcset }}" type="image/avif">
<source srcset="{{ $img_webp_srcset }}" type="image/webp">
<img
src="{{ $img_src }}"
srcset="{{ $img_srcset }}"
sizes="(max-width: 768px) 50vw, (max-width: 1280px) 33vw, 25vw"
loading="lazy"
decoding="async"
alt="{{ e($title) }}"
width="{{ $img_width }}"
height="{{ $img_height }}"
class="h-full w-full object-cover transition-transform duration-200 ease-out group-hover:scale-[1.04]"
itemprop="thumbnailUrl"
/>
</picture>
<div class="pointer-events-none absolute inset-x-0 bottom-0 z-20 bg-gradient-to-t from-black/80 via-black/40 to-transparent p-3 backdrop-blur-[2px] opacity-100 transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100 md:group-focus-visible:opacity-100">
<div class="truncate text-sm font-semibold text-white">{{ $title }}</div>
<div class="mt-1 flex items-center justify-between gap-3 text-xs text-white/80">
<span class="truncate">by {{ $author }}</span>
<span class="shrink-0"> {{ $likes }} · {{ $downloads }}</span>
</div>
<div class="mt-1 text-[11px] text-white/70">
@if($resolution !== '')
{{ $resolution }}
@endif
{{ $category }} {{ $license }}
</div>
</div>
</div>
<span class="sr-only">{{ $title }} by {{ $author }}</span>
</a>
</article>
{{-- Shim for legacy artwork card includes. Points to new web partial. --}}
@include('web.partials._artwork_card')

View File

@@ -28,7 +28,7 @@
<div class="panel-body" style="display:flex; gap:12px;">
<div style="min-width:52px;">
@if (!empty($post->user_id) && !empty($post->icon))
<img src="/avatar/{{ $post->user_id }}/{{ $post->icon }}" alt="{{ $post->uname }}" width="50" height="50" class="img-thumbnail">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $post->user_id, null, 50) }}" alt="{{ $post->uname }}" width="50" height="50" class="img-thumbnail">
@else
<div class="img-thumbnail" style="width:50px;height:50px;"></div>
@endif

View File

@@ -32,7 +32,7 @@
<tr>
<td rowspan="3" valign="top" width="100" style="background:#fff">
@if(!empty($comment->user_id) && !empty($comment->icon))
<div align="center"><a href="/profile/{{ $comment->user_id }}"><img src="/avatar/{{ $comment->user_id }}/{{ \Illuminate\Support\Str::slug($comment->author ?? '') }}" width="50" height="50" border="0" alt="" /></a></div>
<div align="center"><a href="/profile/{{ $comment->user_id }}"><img src="{{ \App\Support\AvatarUrl::forUser((int) $comment->user_id, null, 50) }}" width="50" height="50" border="0" alt="" /></a></div>
@endif
<br/>Posted by: <b><a href="/profile/{{ $comment->user_id ?? '' }}">{{ $comment->author }}</a></b><br/>
Posts: {{ $postCounts[$comment->author] ?? 0 }}

View File

@@ -22,7 +22,7 @@
<td style="width:60px;">
@if(!empty($interview->icon))
<a href="/profile/{{ $interview->user_id }}/{{ \Illuminate\Support\Str::slug($interview->uname ?? '') }}">
<img src="/avatar/{{ $interview->user_id }}/{{ $interview->icon }}" width="50" height="50" alt="">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $interview->user_id, null, 50) }}" width="50" height="50" alt="">
</a>
@else
<img src="/gfx/avatar.jpg" alt="">

View File

@@ -15,7 +15,7 @@
<div class="comment_box effect3">
<div class="cb_image">
<a href="/profile/{{ $comment->commenter_id }}/{{ rawurlencode($comment->uname) }}">
<img src="/avatar/{{ (int)$comment->commenter_id }}/{{ rawurlencode($comment->uname) }}" width="50" height="50" class="comment_avatar" alt="{{ $comment->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $comment->commenter_id, null, 50) }}" width="50" height="50" class="comment_avatar" alt="{{ $comment->uname }}">
</a>
</div>

View File

@@ -27,7 +27,7 @@
<tr>
<td width="50" class="text-center">
<a href="/profile/{{ (int)$row->user_id }}/{{ rawurlencode($row->uname) }}">
<img src="/avatar/{{ (int)$row->user_id }}/{{ rawurlencode($row->uname) }}" width="30" alt="{{ $row->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $row->user_id, null, 32) }}" width="30" alt="{{ $row->uname }}">
</a>
</td>
<td>

View File

@@ -28,7 +28,7 @@
<div>
<a href="/profile/{{ $friendId }}/{{ Str::slug($uname) }}">
<img src="/avatar/{{ $friendId }}/{{ rawurlencode($icon) }}" alt="{{ $uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $friendId, null, 50) }}" alt="{{ $uname }}">
</a>
</div>

View File

@@ -36,7 +36,7 @@
@if(!empty($ar->icon))
<div style="float:right;padding-left:20px;">
<a href="/profile/{{ $ar->user_id ?? '' }}/{{ Str::slug($ar->uname ?? '') }}">
<img src="/avatar/{{ $ar->user_id ?? '' }}/{{ $ar->icon ?? '' }}" width="50" height="50" alt="">
<img src="{{ \App\Support\AvatarUrl::forUser((int) ($ar->user_id ?? 0), null, 50) }}" width="50" height="50" alt="">
</a>
</div>
@endif

View File

@@ -34,7 +34,7 @@
<div class="panel panel-default effect2">
<div class="panel-heading"><strong>User</strong></div>
<div class="panel-body">
<img src="/avatar/{{ (int)$user->user_id }}/{{ rawurlencode($user->icon ?? '') }}" class="img-responsive" style="max-width:120px;" alt="{{ $user->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $user->user_id, null, 128) }}" class="img-responsive" style="max-width:120px;" alt="{{ $user->uname }}">
<h3>{{ $user->uname }}</h3>
<p>{{ $user->about_me ?? '' }}</p>
</div>

View File

@@ -21,7 +21,7 @@
<div class="comment_box effect3">
<div class="cb_image">
<a href="/profile/{{ (int)($author->id ?? $author->user_id) }}/{{ rawurlencode($author->name ?? $author->uname ?? '') }}">
<img src="/avatar/{{ (int)($author->id ?? $author->user_id) }}/{{ rawurlencode($author->icon ?? '') }}" width="50" height="50" class="comment_avatar" alt="{{ $author->name ?? $author->uname ?? '' }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) ($author->id ?? $author->user_id), null, 50) }}" width="50" height="50" class="comment_avatar" alt="{{ $author->name ?? $author->uname ?? '' }}">
</a>
</div>

View File

@@ -119,9 +119,9 @@
}
try {
$profile = \Illuminate\Support\Facades\DB::table('user_profiles')->where('user_id', $userId)->first();
$avatar = $profile->avatar ?? null;
$avatarHash = $profile->avatar_hash ?? null;
} catch (\Throwable $e) {
$avatar = null;
$avatarHash = null;
}
$displayName = auth()->user()->name ?: (auth()->user()->username ?? '');
@endphp
@@ -141,9 +141,7 @@
<li class="dropdown">
<a href="#" class="dropdown-toggle c-white" data-toggle="dropdown" data-hover="dropdown" data-close-others="true">
@if($avatar)
<img src="/storage/{{ ltrim($avatar, '/') }}" alt="{{ $displayName }}" width="18">&nbsp;&nbsp;
@endif
<img src="{{ \App\Support\AvatarUrl::forUser((int) $userId, $avatarHash ?? null, 32) }}" alt="{{ $displayName }}" width="18">&nbsp;&nbsp;
<span class="username">{{ $displayName }}</span>
&nbsp;<i class="fa fa-angle-down"></i>
</a>

View File

@@ -27,7 +27,7 @@
<tr>
<td width="80">
<a href="/profile/{{ $u->user_id }}/{{ \Illuminate\Support\Str::slug($u->uname) }}">
<img src="/avatar/{{ $u->user_id }}/{{ rawurlencode($u->icon ?? '') }}" width="30" height="30" alt="{{ $u->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $u->user_id, null, 32) }}" width="30" height="30" alt="{{ $u->uname }}">
</a>
</td>
<td>
@@ -60,7 +60,7 @@
<tr>
<td width="60" align="center">
<a href="/profile/{{ $f->user_id }}/{{ \Illuminate\Support\Str::slug($f->uname) }}">
<img src="/avatar/{{ $f->user_id }}/{{ rawurlencode($f->uname) }}" width="30" alt="{{ $f->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $f->user_id, null, 32) }}" width="30" alt="{{ $f->uname }}">
</a>
</td>
<td>
@@ -92,7 +92,7 @@
<tr>
<td width="50" align="center">
<a href="/profile/{{ $c->user_id }}/{{ \Illuminate\Support\Str::slug($c->uname) }}">
<img src="/avatar/{{ $c->user_id }}/{{ rawurlencode($c->uname) }}" width="30" alt="{{ $c->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $c->user_id, null, 32) }}" width="30" alt="{{ $c->uname }}">
</a>
</td>
<td>

View File

@@ -2,15 +2,15 @@
@section('content')
<div class="container">
<h2>Edit Artwork: {{ $artwork->name }}</h2>
<h2>Edit Artwork: {{ $artwork->title }}</h2>
<form enctype="multipart/form-data" method="post" action="{{ route('manage.update', $artwork->id) }}">
@csrf
<div class="row">
<div class="col-md-7">
<label class="label-control">Name:</label>
<input type="text" name="name" class="form-control" value="{{ old('name', $artwork->name) }}">
<label class="label-control">Title:</label>
<input type="text" name="title" class="form-control" value="{{ old('title', $artwork->title) }}">
<label class="label-control">Section:</label>
<select name="section" class="form-control">

View File

@@ -33,9 +33,9 @@
<button class="btn btn-xs btn-danger">Delete</button>
</form>
</td>
<td style="cursor:pointer;" onclick="location.href='{{ route('manage.edit', $ar->id) }}'">{{ $ar->name }}</td>
<td>{{ $ar->categoryRelation->category_name ?? '' }}</td>
<td class="text-center">{{ optional($ar->datum)->format('d.m.Y') ?? (is_string($ar->datum) ? date('d.m.Y', strtotime($ar->datum)) : '') }}</td>
<td style="cursor:pointer;" onclick="location.href='{{ route('manage.edit', $ar->id) }}'">{{ $ar->title }}</td>
<td>{{ $ar->category_name ?? ($ar->categoryRelation->category_name ?? '') }}</td>
<td class="text-center">{{ optional($ar->published_at)->format('d.m.Y') ?? (is_string($ar->published_at) ? date('d.m.Y', strtotime($ar->published_at)) : '') }}</td>
<td class="text-center">{{ $ar->rating_num }}</td>
<td class="text-center">{{ $ar->rating }}</td>
<td class="text-center">{{ $ar->dls }}</td>

View File

@@ -1,3 +1,4 @@
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">

View File

@@ -17,6 +17,17 @@
@csrf
@method('patch')
@php
$avatarHash = optional($user->profile)->avatar_hash;
$avatarInitialSrc = \App\Support\AvatarUrl::forUser((int) $user->id, $avatarHash, 128);
@endphp
<div
data-avatar-uploader="true"
data-upload-url="{{ route('avatar.upload') }}"
data-initial-src="{{ $avatarInitialSrc }}"
></div>
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autofocus autocomplete="name" />

View File

@@ -27,7 +27,7 @@
<div>
<a href="/profile/{{ $followerId }}/{{ Str::slug($uname) }}">
<img src="/avatar/{{ $followerId }}/{{ rawurlencode($icon) }}" alt="{{ $uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $followerId, null, 50) }}" alt="{{ $uname }}">
</a>
</div>
</div>
@@ -41,4 +41,4 @@
@endif
</div>
</div>
@endsection
@endsection

View File

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

View File

@@ -11,7 +11,7 @@
</div>
<div style="clear:both;margin-top:10px;">
<img src="/avatar/{{ $artwork->user_id ?? 0 }}/{{ urlencode($artwork->icon ?? '') }}" class="pull-left" style="padding-right:10px;max-height:50px;" alt="Avatar">
<img src="{{ \App\Support\AvatarUrl::forUser((int) ($artwork->user_id ?? 0), null, 50) }}" class="pull-left" style="padding-right:10px;max-height:50px;" alt="Avatar">
<h1 class="page-header">{{ $artwork->name }}</h1>
<p>By <i class="fa fa-user fa-fw"></i> <a href="/profile/{{ $artwork->user_id }}/{{ \Illuminate\Support\Str::slug($artwork->uname) }}" title="Profile of member {{ $artwork->uname }}">{{ $artwork->uname }}</a></p>
<hr>
@@ -30,7 +30,7 @@
<div class="comment_box effect3">
<div class="cb_image">
<a href="/profile/{{ $comment->user_id }}/{{ urlencode($comment->uname) }}">
<img src="/avatar/{{ $comment->user_id }}/{{ urlencode($comment->icon) }}" width="50" height="50" class="comment_avatar" alt="{{ $comment->uname }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) $comment->user_id, null, 50) }}" width="50" height="50" class="comment_avatar" alt="{{ $comment->uname }}">
</a>
</div>
<div class="bubble_comment panel panel-skinbase">
@@ -53,7 +53,7 @@
<div class="comment_box effect3">
<div class="cb_image">
<a href="/profile/{{ auth()->id() }}/{{ urlencode(auth()->user()->name) }}">
<img src="/avatar/{{ auth()->id() }}/{{ urlencode(auth()->user()->avatar ?? '') }}" class="comment_avatar" width="50" height="50">
<img src="{{ \App\Support\AvatarUrl::forUser((int) auth()->id(), null, 50) }}" class="comment_avatar" width="50" height="50">
</a>
<br>
<a href="/profile/{{ auth()->id() }}/{{ urlencode(auth()->user()->name) }}">{{ auth()->user()->name }}</a>
@@ -115,4 +115,4 @@
</div>
</div>
</div>
@endsection
@endsection

View File

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

View File

@@ -33,7 +33,7 @@
@if ($artworks->count())
<div class="container_photo gallery_box">
@foreach ($artworks as $art)
@include('legacy._artwork_card', ['art' => $art])
@include('web.partials._artwork_card', ['art' => $art])
@endforeach
</div>
@else

View File

@@ -19,7 +19,7 @@
</ul>
<div id="myContent">
@include('legacy.partials.daily-uploads-grid', ['arts' => $recent])
@include('web.partials.daily-uploads-grid', ['arts' => $recent])
</div>
</div>
</div>
@@ -45,4 +45,4 @@
</script>
@endpush
@endsection
@endsection

View File

@@ -34,7 +34,7 @@
'category_name' => $art->category_name ?? '',
];
@endphp
@include('legacy._artwork_card', ['art' => $card])
@include('web.partials._artwork_card', ['art' => $card])
@endforeach
</div>
@else
@@ -46,4 +46,4 @@
@if($artworks){{ $artworks->withQueryString()->links('pagination::bootstrap-4') }}@endif
</div>
</div>
@endsection
@endsection

View File

@@ -34,7 +34,7 @@
<div class="panel panel-default effect2">
<div class="panel-heading"><strong>User</strong></div>
<div class="panel-body">
<img src="/avatar/{{ (int)($user->user_id ?? $user->id) }}/{{ rawurlencode($user->icon ?? '') }}" class="img-responsive" style="max-width:120px;" alt="{{ $user->uname ?? $user->name }}">
<img src="{{ \App\Support\AvatarUrl::forUser((int) ($user->user_id ?? $user->id), null, 128) }}" class="img-responsive" style="max-width:120px;" alt="{{ $user->uname ?? $user->name }}">
<h3>{{ $user->uname ?? $user->name }}</h3>
<p>{{ $user->about_me ?? '' }}</p>
</div>
@@ -57,4 +57,4 @@
@endif
</div>
@endsection
@endsection

View File

@@ -0,0 +1,17 @@
@extends('layouts.nova')
@php
use Illuminate\Support\Str;
use Carbon\Carbon;
use App\Services\LegacyService;
@endphp
@section('content')
<div class="container-fluid legacy-page">
@include('web.home.featured')
@include('web.home.uploads')
@include('web.home.news')
</div>
@endsection

View File

@@ -0,0 +1,47 @@
{{-- 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>
</div>
</div>
<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>
</div>
</div>
</div>

View File

@@ -0,0 +1,80 @@
{{-- News and forum columns (migrated from legacy/home/news.blade.php) --}}
<div class="row news-row">
<div class="col-sm-6">
@forelse ($forumNews as $item)
<div class="panel panel-skinbase effect2">
<div class="panel-heading"><h4 class="panel-title">{{ $item->topic }}</h4></div>
<div class="panel-body">
<div class="text-muted news-head">
Written by {{ $item->uname }} on {{ Carbon::parse($item->post_date)->format('j F Y \@ H:i') }}
</div>
{!! Str::limit(strip_tags($item->preview ?? ''), 240, '...') !!}
<br>
<a class="clearfix btn btn-xs btn-info" href="/forum/{{ $item->topic_id }}/{{ Str::slug($item->topic ?? '') }}" title="{{ strip_tags($item->topic) }}">More</a>
</div>
</div>
@empty
<p>No forum news available.</p>
@endforelse
</div>
<div class="col-sm-6">
@forelse ($ourNews as $news)
<div class="panel panel-skinbase effect2">
<div class="panel-heading"><h3 class="panel-title">{{ $news->headline }}</h3></div>
<div class="panel-body">
<div class="text-muted news-head">
<i class="fa fa-user"></i> {{ $news->uname }}
<i class="fa fa-calendar"></i> {{ Carbon::parse($news->create_date)->format('j F Y \@ H:i') }}
<i class="fa fa-info"></i> {{ $news->category_name }}
<i class="fa fa-info"></i> {{ $news->views }} reads
<i class="fa fa-comment"></i> {{ $news->num_comments }} comments
</div>
@if (!empty($news->picture))
@php $nid = floor($news->news_id / 100); @endphp
<div class="col-md-4">
<img src="/archive/news/{{ $nid }}/{{ $news->picture }}" class="img-responsive" alt="{{ $news->headline }}">
</div>
<div class="col-md-8">
{!! $news->preview !!}
</div>
@else
{!! $news->preview !!}
@endif
<a class="clearfix btn btn-xs btn-info text-white" href="/news/{{ $news->news_id }}/{{ Str::slug($news->headline ?? '') }}">More</a>
</div>
</div>
@empty
<p>No news available.</p>
@endforelse
{{-- Site info --}}
<div class="panel panel-default">
<div class="panel-heading"><strong>Info</strong></div>
<div class="panel-body">
<h4>Photography, Wallpapers and Skins... Thats Skinbase</h4>
<p>Skinbase is the site dedicated to <strong>Photography</strong>, <strong>Wallpapers</strong> and <strong>Skins</strong> for <u>popular applications</u> for every major operating system like Windows, Mac OS X, Linux, iOS and Android</p>
<em>Our members every day uploads new artworks to our site, so don&apos;t hesitate and check Skinbase frequently for updates. We also have forum where you can discuss with other members with anything.</em>
<p>On the site toolbar you can click on Categories and start browsing our atwork (<i>photo</i>, <i>desktop themes</i>, <i>pictures</i>) and of course you can <u>download</u> them for free!</p>
<p>We are also active on all major <b>social</b> sites, find us there too</p>
</div>
</div>
{{-- Latest forum activity --}}
<div class="panel panel-default activity-panel">
<div class="panel-heading"><strong>Latest Forum Activity</strong></div>
<div class="panel-body">
<div class="list-group effect2">
@forelse ($latestForumActivity as $topic)
<a class="list-group-item" href="/forum/{{ $topic->topic_id }}/{{ Str::slug($topic->topic ?? '') }}">
{{ $topic->topic }} <span class="badge badge-info">{{ $topic->numPosts }}</span>
</a>
@empty
<p>No recent forum activity.</p>
@endforelse
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,14 @@
{{-- 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 -->

View File

@@ -0,0 +1,112 @@
@php
// If a Collection or array was passed accidentally, pick the first item.
if (isset($art) && (is_array($art) || $art instanceof Illuminate\Support\Collection || $art instanceof Illuminate\Database\Eloquent\Collection)) {
$first = null;
if (is_array($art)) {
$first = reset($art);
} elseif ($art instanceof Illuminate\Support\Collection || $art instanceof Illuminate\Database\Eloquent\Collection) {
$first = $art->first();
}
if ($first) {
$art = $first;
}
}
$title = trim((string) ($art->name ?? $art->title ?? 'Untitled artwork'));
$author = trim((string) ($art->uname ?? $art->author_name ?? $art->author ?? 'Skinbase'));
$category = trim((string) ($art->category_name ?? $art->category ?? 'General'));
$license = trim((string) ($art->license ?? 'Standard'));
$resolution = trim((string) ($art->resolution ?? ((isset($art->width, $art->height) && $art->width && $art->height) ? ($art->width . '×' . $art->height) : '')));
// Safe integer extractor: handle numeric, arrays, Collections, or relations
$safeInt = function ($v, $fallback = 0) {
if (is_numeric($v)) return (int) $v;
if (is_array($v)) return count($v);
if (is_object($v)) {
if (method_exists($v, 'count')) return (int) $v->count();
if ($v instanceof Countable) return (int) count($v);
}
return (int) $fallback;
};
$likes = $safeInt($art->likes ?? $art->favourites ?? 0);
$downloads = $safeInt($art->downloads ?? $art->downloaded ?? 0);
$img_src = (string) ($art->thumb ?? $art->thumbnail_url ?? '/images/placeholder.jpg');
$img_srcset = (string) ($art->thumb_srcset ?? $art->thumbnail_srcset ?? $img_src);
$img_avif_srcset = (string) ($art->thumb_avif_srcset ?? $img_srcset);
$img_webp_srcset = (string) ($art->thumb_webp_srcset ?? $img_srcset);
$resolveDimension = function ($val, $fallback) {
if (is_numeric($val)) return (int) $val;
if (is_array($val)) {
$v = reset($val);
return is_numeric($v) ? (int) $v : (int) $fallback;
}
if (is_object($val)) {
if (method_exists($val, 'first')) {
$f = $val->first();
if (is_object($f) && isset($f->width)) return (int) ($f->width ?: $fallback);
if (is_object($f) && isset($f->height)) return (int) ($f->height ?: $fallback);
}
if (isset($val->width)) return (int) $val->width;
if (isset($val->height)) return (int) $val->height;
}
return (int) $fallback;
};
$img_width = max(1, $resolveDimension($art->width ?? null, 800));
$img_height = max(1, $resolveDimension($art->height ?? null, 600));
$contentUrl = $img_src;
$cardUrl = (string) ($art->url ?? '#');
@endphp
<article class="nova-card artwork" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="name" content="{{ $title }}">
<meta itemprop="contentUrl" content="{{ $contentUrl }}">
<meta itemprop="creator" content="{{ $author }}">
<meta itemprop="license" content="{{ $license }}">
<a href="{{ $cardUrl }}" itemprop="url" class="group relative block overflow-hidden rounded-2xl ring-1 ring-white/5 bg-black/20 shadow-lg shadow-black/40 transition-all duration-200 ease-out hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/70">
@if(!empty($category))
<div class="absolute left-3 top-3 z-30 rounded-md bg-black/55 px-2 py-1 text-xs text-white backdrop-blur-sm">{{ $category }}</div>
@endif
<div class="nova-card-media relative aspect-[16/10] overflow-hidden bg-neutral-900">
<picture>
<source srcset="{{ $img_avif_srcset }}" type="image/avif">
<source srcset="{{ $img_webp_srcset }}" type="image/webp">
<img
src="{{ $img_src }}"
srcset="{{ $img_srcset }}"
sizes="(max-width: 768px) 50vw, (max-width: 1280px) 33vw, 25vw"
loading="lazy"
decoding="async"
alt="{{ e($title) }}"
width="{{ $img_width }}"
height="{{ $img_height }}"
class="h-full w-full object-cover transition-transform duration-200 ease-out group-hover:scale-[1.04]"
itemprop="thumbnailUrl"
/>
</picture>
<div class="pointer-events-none absolute inset-x-0 bottom-0 z-20 bg-gradient-to-t from-black/80 via-black/40 to-transparent p-3 backdrop-blur-[2px] opacity-100 transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100 md:group-focus-visible:opacity-100">
<div class="truncate text-sm font-semibold text-white">{{ $title }}</div>
<div class="mt-1 flex items-center justify-between gap-3 text-xs text-white/80">
<span class="truncate">by {{ $author }}</span>
<span class="shrink-0"> {{ $likes }} · {{ $downloads }}</span>
</div>
<div class="mt-1 text-[11px] text-white/70">
@if($resolution !== '')
{{ $resolution }}
@endif
{{ $category }} {{ $license }}
</div>
</div>
</div>
<span class="sr-only">{{ $title }} by {{ $author }}</span>
</a>
</article>