feat: Nova homepage, profile redesign, and legacy view system overhaul
Homepage
- Add HomepageService with hero, trending (award-weighted), fresh uploads,
popular tags, creator spotlight (weekly uploads ranking), and news sections
- Add React components: HomePage, HomeHero, HomeTrending, HomeFresh,
HomeTags, HomeCreators, HomeNews (lazy-loaded below the fold)
- Wire home.blade.php with JSON props, SEO meta, JSON-LD, and hero preload
- Add HomePage.jsx to vite.config.js inputs
Profile page
- Hero banner with random user artwork as background + dark gradient overlay
- Favourites section uses real Artwork models + <x-artwork-card> for CDN URLs
- Newest artworks grid: gallery-grid → grid grid-cols-2 gap-4
Edit Profile page (user.blade.php)
- Add hero banner (featured wallpaper/photography via artwork_features,
content_type_id IN [2,3]) sourced in UserController
- Remove bg-deep from outer wrapper; card backgrounds: bg-panel → bg-nova-800
- Remove stray AI-generated tag fragment from template
Author profile links
- Fix all /@username routes in: HomepageService, MonthlyCommentatorsController,
LatestCommentsController, MyBuddiesController and corresponding blade views
Legacy view namespace
- Register View::addNamespace('legacy', resource_path('views/_legacy'))
in AppServiceProvider::boot()
- Convert all view('legacy.x') and @include('legacy.x') calls to legacy::x
- Migrate legacy views to resources/views/_legacy/ with namespace support
This commit is contained in:
@@ -33,7 +33,7 @@ class CategoryPageController extends Controller
|
||||
$perPage = 40;
|
||||
$artworks = $this->artworkService->getArtworksByContentType($contentType->slug, $perPage, $sort);
|
||||
|
||||
return view('legacy.content-type', compact(
|
||||
return view('legacy::content-type', compact(
|
||||
'contentType',
|
||||
'rootCategories',
|
||||
'artworks',
|
||||
@@ -92,7 +92,7 @@ class CategoryPageController extends Controller
|
||||
|
||||
// resolved category and breadcrumbs are used by the view
|
||||
|
||||
return view('legacy.category-slug', compact(
|
||||
return view('legacy::category-slug', compact(
|
||||
'contentType',
|
||||
'category',
|
||||
'subcategories',
|
||||
|
||||
@@ -20,7 +20,7 @@ class InterviewController extends Controller
|
||||
$interviews = collect();
|
||||
}
|
||||
|
||||
return view('legacy.interviews', [
|
||||
return view('legacy::interviews', [
|
||||
'interviews' => $interviews,
|
||||
'page_title' => 'Interviews',
|
||||
]);
|
||||
|
||||
@@ -33,6 +33,7 @@ class LatestCommentsController extends Controller
|
||||
'comment_id' => $c->getKey(),
|
||||
'comment_description' => $c->content,
|
||||
'commenter_id' => $c->user_id,
|
||||
'commenter_username' => $user?->username ?? null,
|
||||
'country' => $user->country ?? null,
|
||||
'icon' => $user ? DB::table('user_profiles')->where('user_id', $user->id)->value('avatar_hash') : null,
|
||||
'uname' => $user->username ?? $user->name ?? 'User',
|
||||
|
||||
@@ -30,7 +30,7 @@ class GalleryController extends Controller
|
||||
|
||||
$artworks = $query->skip(($page - 1) * $hits)->take($hits)->get();
|
||||
|
||||
return view('legacy.gallery', [
|
||||
return view('legacy::gallery', [
|
||||
'user' => $user,
|
||||
'artworks' => $artworks,
|
||||
'page' => $page,
|
||||
|
||||
@@ -92,7 +92,7 @@ class InterviewController extends Controller
|
||||
|
||||
$page_title = 'Interview with ' . ($ar->username ?? '');
|
||||
|
||||
return view('legacy.interview', [
|
||||
return view('legacy::interview', [
|
||||
'ar' => $ar,
|
||||
'artworks' => $artworks,
|
||||
'comments' => $comments,
|
||||
|
||||
@@ -23,6 +23,6 @@ class InterviewsController extends Controller
|
||||
|
||||
$page_title = 'Interviews';
|
||||
|
||||
return view('legacy.interviews', compact('interviews', 'page_title'));
|
||||
return view('legacy::interviews', compact('interviews', 'page_title'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class ArtController extends Controller
|
||||
$data = $this->legacy->getArtwork((int) $id);
|
||||
|
||||
if (! $data || empty($data['artwork'])) {
|
||||
return view('legacy.placeholder', ['title' => 'Artwork Not Found']);
|
||||
return view('legacy::placeholder', ['title' => 'Artwork Not Found']);
|
||||
}
|
||||
|
||||
// load comments for artwork (legacy schema)
|
||||
@@ -57,6 +57,6 @@ class ArtController extends Controller
|
||||
|
||||
$data['comments'] = $comments;
|
||||
|
||||
return view('legacy.art', $data);
|
||||
return view('legacy::art', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class BrowseController extends Controller
|
||||
|
||||
$page_canonical = url('/browse');
|
||||
|
||||
return view('legacy.browse', compact('page_title', 'page_meta_description', 'page_meta_keywords', 'page_canonical', 'artworks', 'rootCategories'));
|
||||
return view('legacy::browse', compact('page_title', 'page_meta_description', 'page_meta_keywords', 'page_canonical', 'artworks', 'rootCategories'));
|
||||
}
|
||||
|
||||
private function mapArtwork(Artwork $artwork): object
|
||||
|
||||
@@ -32,6 +32,6 @@ class BuddiesController extends Controller
|
||||
|
||||
$page_title = ($user->name ?? $user->username ?? 'User') . ': Followers';
|
||||
|
||||
return view('legacy.buddies', compact('followers', 'page_title'));
|
||||
return view('legacy::buddies', compact('followers', 'page_title'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class CategoryController extends Controller
|
||||
|
||||
// Expecting segments like ['category', '{contentType}', '{...categorySlugs}']
|
||||
if (count($segments) < 2 || strtolower($segments[0]) !== 'category') {
|
||||
return view('legacy.placeholder');
|
||||
return view('legacy::placeholder');
|
||||
}
|
||||
|
||||
$parts = array_slice($segments, 1);
|
||||
@@ -90,7 +90,7 @@ class CategoryController extends Controller
|
||||
$page_meta_description = $category->description ?? ($category->contentType->name . ' artworks on Skinbase');
|
||||
$page_meta_keywords = strtolower($category->contentType->slug) . ', skinbase, artworks, wallpapers, skins, photography';
|
||||
|
||||
return view('legacy.category', compact(
|
||||
return view('legacy::category', compact(
|
||||
'page_title',
|
||||
'page_meta_description',
|
||||
'page_meta_keywords',
|
||||
@@ -104,6 +104,6 @@ class CategoryController extends Controller
|
||||
public function browseCategories()
|
||||
{
|
||||
$data = $this->legacy->browseCategories();
|
||||
return view('legacy.categories', $data);
|
||||
return view('legacy::categories', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,6 @@ class ChatController extends Controller
|
||||
$smileys = collect();
|
||||
}
|
||||
|
||||
return view('legacy.chat', compact('page_title', 'adHtml', 'chatHtml', 'smileys'));
|
||||
return view('legacy::chat', compact('page_title', 'adHtml', 'chatHtml', 'smileys'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class DailyUploadsController extends Controller
|
||||
if ($isAjax && $datum) {
|
||||
// Return partial gallery for the given date
|
||||
$arts = $this->fetchByDate($datum);
|
||||
return view('legacy.partials.daily-uploads-grid', ['arts' => $arts])->render();
|
||||
return view('legacy::partials.daily-uploads-grid', ['arts' => $arts])->render();
|
||||
}
|
||||
|
||||
// Build date tabs (today .. -14 days)
|
||||
@@ -41,7 +41,7 @@ class DailyUploadsController extends Controller
|
||||
// initial content: recent (last 7 days)
|
||||
$recent = $this->fetchRecent();
|
||||
|
||||
return view('legacy.daily-uploads', [
|
||||
return view('legacy::daily-uploads', [
|
||||
'dates' => $dates,
|
||||
'recent' => $recent,
|
||||
'page_title' => 'Daily Uploads',
|
||||
|
||||
@@ -120,7 +120,7 @@ class FavouritesController extends Controller
|
||||
|
||||
$page_title = ($username ?: ($userNameCol ? DB::table('users')->where($userIdCol, $userId)->value($userNameCol) : '')) . ' Favourites';
|
||||
|
||||
return view('legacy.favourites', [
|
||||
return view('legacy::favourites', [
|
||||
'results' => $results,
|
||||
'page_title' => $page_title,
|
||||
'user_id' => $userId,
|
||||
|
||||
@@ -53,7 +53,7 @@ class FeaturedArtworksController extends Controller
|
||||
|
||||
$pageTitle = $artworkTypes[$type] ?? 'Featured Artworks';
|
||||
|
||||
return view('legacy.featured-artworks', [
|
||||
return view('legacy::featured-artworks', [
|
||||
'artworks' => $artworks,
|
||||
'type' => $type,
|
||||
'artworkTypes' => $artworkTypes,
|
||||
|
||||
@@ -43,7 +43,7 @@ class HomeController extends Controller
|
||||
$ourNews = [];
|
||||
$latestForumActivity = [];
|
||||
|
||||
return view('legacy.home', compact(
|
||||
return view('legacy::home', compact(
|
||||
'page_title',
|
||||
'page_meta_description',
|
||||
'page_meta_keywords',
|
||||
|
||||
@@ -95,7 +95,7 @@ class InterviewController extends Controller
|
||||
|
||||
$page_title = 'Interview with ' . ($ar->username ?? '');
|
||||
|
||||
return view('legacy.interview', [
|
||||
return view('legacy::interview', [
|
||||
'ar' => $ar,
|
||||
'artworks' => $artworks,
|
||||
'comments' => $comments,
|
||||
|
||||
@@ -23,6 +23,6 @@ class InterviewsController extends Controller
|
||||
|
||||
$page_title = 'Interviews';
|
||||
|
||||
return view('legacy.interviews', compact('interviews', 'page_title'));
|
||||
return view('legacy::interviews', compact('interviews', 'page_title'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,6 @@ class LatestCommentsController extends Controller
|
||||
|
||||
$page_title = 'Latest Comments';
|
||||
|
||||
return view('legacy.latest-comments', compact('page_title', 'comments'));
|
||||
return view('legacy::latest-comments', compact('page_title', 'comments'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class LatestController extends Controller
|
||||
];
|
||||
});
|
||||
|
||||
return view('legacy.latest-artworks', [
|
||||
return view('legacy::latest-artworks', [
|
||||
'artworks' => $artworks,
|
||||
'page_title' => 'Latest Artworks',
|
||||
]);
|
||||
|
||||
@@ -46,6 +46,6 @@ class MembersController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
return view('legacy.browse', compact('page_title', 'artworks'));
|
||||
return view('legacy::browse', compact('page_title', 'artworks'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,6 @@ class MonthlyCommentatorsController extends Controller
|
||||
|
||||
$page_title = 'Monthly Top Commentators';
|
||||
|
||||
return view('legacy.monthly-commentators', compact('page_title', 'rows'));
|
||||
return view('legacy::monthly-commentators', compact('page_title', 'rows'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class MyBuddiesController extends Controller
|
||||
|
||||
$page_title = ($user->name ?? $user->username ?? 'User') . ': Following List';
|
||||
|
||||
return view('legacy.mybuddies', compact('buddies', 'page_title'));
|
||||
return view('legacy::mybuddies', compact('buddies', 'page_title'));
|
||||
}
|
||||
|
||||
public function destroy(Request $request, $id)
|
||||
|
||||
@@ -39,6 +39,6 @@ class NewsController extends Controller
|
||||
|
||||
$page_title = ($news->headline ?? 'News') . ' - SkinBase News';
|
||||
|
||||
return view('legacy.news', compact('news', 'comments', 'page_title'));
|
||||
return view('legacy::news', compact('news', 'comments', 'page_title'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,6 @@ class PhotographyController extends Controller
|
||||
|
||||
$page_meta_description = $tidy;
|
||||
|
||||
return view('legacy.content-type', compact('contentType','rootCategories','artworks','page_title','page_meta_description','subcategories','id'));
|
||||
return view('legacy::content-type', compact('contentType','rootCategories','artworks','page_title','page_meta_description','subcategories','id'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class ProfileController extends Controller
|
||||
'about_me' => $user->bio ?? null,
|
||||
];
|
||||
|
||||
return view('legacy.profile', [
|
||||
return view('legacy::profile', [
|
||||
'user' => $legacyUser,
|
||||
'artworks' => $artworks,
|
||||
]);
|
||||
|
||||
@@ -28,7 +28,7 @@ class ReceivedCommentsController extends Controller
|
||||
|
||||
$comments = $base->paginate($hits);
|
||||
|
||||
return view('legacy.received-comments', [
|
||||
return view('legacy::received-comments', [
|
||||
'comments' => $comments,
|
||||
'page' => $page,
|
||||
'hits' => $hits,
|
||||
|
||||
@@ -57,7 +57,7 @@ class StatisticsController extends Controller
|
||||
return $row;
|
||||
});
|
||||
|
||||
return view('legacy.statistics', [
|
||||
return view('legacy::statistics', [
|
||||
'artworks' => $artworks,
|
||||
'sort' => $sort,
|
||||
'page_title' => 'Artwork Statistics',
|
||||
|
||||
@@ -63,6 +63,6 @@ class TodayDownloadsController extends Controller
|
||||
|
||||
$page_title = 'Today Downloaded Artworks';
|
||||
|
||||
return view('legacy.browse', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
return view('legacy::browse', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class TodayInHistoryController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
return view('legacy.today-in-history', [
|
||||
return view('legacy::today-in-history', [
|
||||
'artworks' => $artworks,
|
||||
'page_title' => 'Popular on this day in history',
|
||||
]);
|
||||
|
||||
@@ -55,6 +55,6 @@ class TopAuthorsController extends Controller
|
||||
|
||||
$page_title = 'Top Authors';
|
||||
|
||||
return view('legacy.top-authors', compact('page_title', 'authors', 'metric'));
|
||||
return view('legacy::top-authors', compact('page_title', 'authors', 'metric'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,6 @@ class TopFavouritesController extends Controller
|
||||
|
||||
$page_title = 'Top Favourites';
|
||||
|
||||
return view('legacy.top-favourites', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
return view('legacy::top-favourites', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class UserController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return view('legacy.user', [
|
||||
return view('legacy::user', [
|
||||
'user' => $user,
|
||||
'birthDay' => $birthDay,
|
||||
'birthMonth' => $birthMonth,
|
||||
|
||||
@@ -22,7 +22,7 @@ class LegacyController extends Controller
|
||||
$ourNews = $this->ourNews();
|
||||
$latestForumActivity = $this->latestForumActivity();
|
||||
|
||||
return view('legacy.home', compact(
|
||||
return view('legacy::home', compact(
|
||||
'page_title',
|
||||
'page_meta_description',
|
||||
'page_meta_keywords',
|
||||
@@ -75,7 +75,7 @@ class LegacyController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
return view('legacy.browse', compact('page_title', 'page_meta_description', 'page_meta_keywords', 'artworks'));
|
||||
return view('legacy::browse', compact('page_title', 'page_meta_description', 'page_meta_keywords', 'artworks'));
|
||||
}
|
||||
|
||||
public function category(Request $request, string $group, ?string $slug = null, ?int $id = null)
|
||||
@@ -172,7 +172,7 @@ class LegacyController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return view('legacy.category', compact(
|
||||
return view('legacy::category', compact(
|
||||
'group',
|
||||
'category',
|
||||
'artworks',
|
||||
@@ -246,7 +246,7 @@ class LegacyController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return view('legacy.categories', compact(
|
||||
return view('legacy::categories', compact(
|
||||
'categories',
|
||||
'subgroups',
|
||||
'page_title',
|
||||
|
||||
@@ -96,6 +96,6 @@ class PhotographyController extends Controller
|
||||
|
||||
$page_meta_description = $tidy;
|
||||
|
||||
return view('legacy.content-type', compact('contentType','rootCategories','artworks','page_title','page_meta_description','subcategories','id'));
|
||||
return view('legacy::content-type', compact('contentType','rootCategories','artworks','page_title','page_meta_description','subcategories','id'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ class MonthlyCommentatorsController extends Controller
|
||||
->whereRaw('t1.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)')
|
||||
->select(
|
||||
't2.id as user_id',
|
||||
't2.username as user_username',
|
||||
DB::raw('COALESCE(t2.username, t2.name, "User") as uname'),
|
||||
DB::raw('COUNT(*) as num_comments')
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ class MyBuddiesController extends Controller
|
||||
->leftJoin('users as t2', 't1.friend_id', '=', 't2.id')
|
||||
->leftJoin('user_profiles as p', 'p.user_id', '=', 't2.id')
|
||||
->where('t1.user_id', $user->id)
|
||||
->select('t1.id', 't1.friend_id', 't1.user_id', 't2.name as uname', 'p.avatar_hash as icon', 't1.date_added')
|
||||
->select('t1.id', 't1.friend_id', 't1.user_id', 't2.name as uname', 't2.username as user_username', 'p.avatar_hash as icon', 't1.date_added')
|
||||
->orderByDesc('t1.date_added');
|
||||
|
||||
$buddies = $query->paginate($perPage)->withQueryString();
|
||||
|
||||
@@ -383,7 +383,7 @@ class ProfileController extends Controller
|
||||
// ── Favourites ───────────────────────────────────────────────────────
|
||||
$favourites = collect();
|
||||
if (Schema::hasTable('user_favorites')) {
|
||||
$favourites = DB::table('user_favorites as uf')
|
||||
$favIds = DB::table('user_favorites as uf')
|
||||
->join('artworks as a', 'a.id', '=', 'uf.artwork_id')
|
||||
->where('uf.user_id', $user->id)
|
||||
->whereNull('a.deleted_at')
|
||||
@@ -391,20 +391,18 @@ class ProfileController extends Controller
|
||||
->where('a.is_approved', true)
|
||||
->orderByDesc('uf.created_at')
|
||||
->limit(12)
|
||||
->select(['a.id', 'a.title as name', 'a.hash', 'a.thumb_ext', 'a.width', 'a.height', 'a.user_id'])
|
||||
->get()
|
||||
->map(function ($row) {
|
||||
$thumbUrl = ($row->hash && $row->thumb_ext)
|
||||
? ThumbnailService::fromHash($row->hash, $row->thumb_ext, 'sm')
|
||||
: '/images/placeholder.jpg';
|
||||
return (object) [
|
||||
'id' => $row->id,
|
||||
'name' => $row->name,
|
||||
'thumb' => $thumbUrl,
|
||||
'width' => $row->width,
|
||||
'height'=> $row->height,
|
||||
];
|
||||
});
|
||||
->pluck('a.id');
|
||||
|
||||
if ($favIds->isNotEmpty()) {
|
||||
$indexed = Artwork::with('user:id,name,username')
|
||||
->whereIn('id', $favIds)
|
||||
->get()
|
||||
->keyBy('id');
|
||||
// Preserve the ordering from the favourites table
|
||||
$favourites = $favIds
|
||||
->filter(fn ($id) => $indexed->has($id))
|
||||
->map(fn ($id) => $indexed[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Statistics ───────────────────────────────────────────────────────
|
||||
@@ -499,6 +497,16 @@ class ProfileController extends Controller
|
||||
$countryName = $countryName ?? strtoupper((string) $profile->country_code);
|
||||
}
|
||||
|
||||
// ── Hero background artwork ─────────────────────────────────────────
|
||||
$heroBgUrl = Artwork::public()
|
||||
->published()
|
||||
->where('user_id', $user->id)
|
||||
->whereNotNull('hash')
|
||||
->whereNotNull('thumb_ext')
|
||||
->inRandomOrder()
|
||||
->limit(1)
|
||||
->first()?->thumbUrl('lg');
|
||||
|
||||
// ── Increment profile views (async-safe, ignore errors) ──────────────
|
||||
if (! $isOwner) {
|
||||
try {
|
||||
@@ -510,7 +518,7 @@ class ProfileController extends Controller
|
||||
} catch (\Throwable) {}
|
||||
}
|
||||
|
||||
return response()->view('legacy.profile', [
|
||||
return response()->view('legacy::profile', [
|
||||
'user' => $user,
|
||||
'profile' => $profile,
|
||||
'artworks' => $artworks,
|
||||
@@ -521,6 +529,7 @@ class ProfileController extends Controller
|
||||
'followerCount' => $followerCount,
|
||||
'recentFollowers' => $recentFollowers,
|
||||
'viewerIsFollowing' => $viewerIsFollowing,
|
||||
'heroBgUrl' => $heroBgUrl,
|
||||
'profileComments' => $profileComments,
|
||||
'countryName' => $countryName,
|
||||
'isOwner' => $isOwner,
|
||||
|
||||
@@ -45,7 +45,7 @@ class TodayInHistoryController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
return view('legacy.today-in-history', [
|
||||
return view('legacy::today-in-history', [
|
||||
'artworks' => $artworks,
|
||||
'page_title' => 'Popular on this day in history',
|
||||
]);
|
||||
|
||||
@@ -51,6 +51,6 @@ class TopFavouritesController extends Controller
|
||||
|
||||
$page_title = 'Top Favourites';
|
||||
|
||||
return view('legacy.top-favourites', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
return view('legacy::top-favourites', ['page_title' => $page_title, 'artworks' => $paginator]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Artwork;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
@@ -20,8 +21,28 @@ class UserController extends Controller
|
||||
$profile = null;
|
||||
}
|
||||
|
||||
return view('legacy.user', [
|
||||
'profile' => $profile,
|
||||
// Hero background: prefer featured wallpapers or photography
|
||||
$heroBgUrl = Artwork::public()
|
||||
->published()
|
||||
->whereNotNull('hash')
|
||||
->whereNotNull('thumb_ext')
|
||||
->whereHas('features', function ($q) {
|
||||
$q->where('is_active', true)
|
||||
->where(function ($q2) {
|
||||
$q2->whereNull('expires_at')->orWhere('expires_at', '>', now());
|
||||
});
|
||||
})
|
||||
->whereHas('categories', function ($q) {
|
||||
// content_type_id 2 = Wallpapers, 3 = Photography
|
||||
$q->whereIn('content_type_id', [2, 3]);
|
||||
})
|
||||
->inRandomOrder()
|
||||
->limit(1)
|
||||
->first()?->thumbUrl('lg');
|
||||
|
||||
return view('legacy::user', [
|
||||
'profile' => $profile,
|
||||
'heroBgUrl' => $heroBgUrl,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\HomepageService;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\ArtworkService;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class HomeController extends Controller
|
||||
final class HomeController extends Controller
|
||||
{
|
||||
protected ArtworkService $artworks;
|
||||
public function __construct(private readonly HomepageService $homepage) {}
|
||||
|
||||
public function __construct(ArtworkService $artworks)
|
||||
public function index(Request $request): \Illuminate\View\View
|
||||
{
|
||||
$this->artworks = $artworks;
|
||||
}
|
||||
$sections = $this->homepage->all();
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$page_title = 'Skinbase - Photography, Skins & Wallpapers';
|
||||
$page_meta_description = 'Skinbase legacy home, rendered via Laravel.';
|
||||
$page_meta_keywords = 'wallpapers, skins, photography, community';
|
||||
$hero = $sections['hero'];
|
||||
|
||||
$featuredResult = $this->artworks->getFeaturedArtworks(null, 39);
|
||||
if ($featuredResult instanceof \Illuminate\Pagination\LengthAwarePaginator) {
|
||||
$featuredCollection = $featuredResult->getCollection();
|
||||
$featured = $featuredCollection->get(0);
|
||||
$memberFeatured = $featuredCollection->get(1);
|
||||
} elseif (is_array($featuredResult)) {
|
||||
$featured = $featuredResult[0] ?? null;
|
||||
$memberFeatured = $featuredResult[1] ?? null;
|
||||
} elseif ($featuredResult instanceof Collection) {
|
||||
$featured = $featuredResult->get(0);
|
||||
$memberFeatured = $featuredResult->get(1);
|
||||
} else {
|
||||
$featured = $featuredResult;
|
||||
$memberFeatured = null;
|
||||
}
|
||||
$meta = [
|
||||
'title' => 'Skinbase – Digital Art & Wallpapers',
|
||||
'description' => 'Discover stunning digital art, wallpapers, and skins from a global community of creators. Browse trending works, fresh uploads, and beloved classics.',
|
||||
'keywords' => 'wallpapers, digital art, skins, photography, community, wallpaper downloads',
|
||||
'og_image' => $hero['thumb_lg'] ?? $hero['thumb'] ?? null,
|
||||
'canonical' => url('/'),
|
||||
];
|
||||
|
||||
$latestUploads = $this->artworks->getLatestArtworks(20);
|
||||
|
||||
// Forum news (prefer migrated legacy news category id 2876, fallback to slug)
|
||||
try {
|
||||
$forumNews = DB::table('forum_threads as t1')
|
||||
->leftJoin('users as u', 't1.user_id', '=', 'u.id')
|
||||
->leftJoin('forum_categories as c', 't1.category_id', '=', 'c.id')
|
||||
->selectRaw('t1.id as topic_id, t1.title as topic, COALESCE(u.name, ?) as uname, t1.created_at as post_date, t1.content as preview', ['Unknown'])
|
||||
->whereNull('t1.deleted_at')
|
||||
->where(function ($query) {
|
||||
$query->where('t1.category_id', 2876)
|
||||
->orWhereIn('c.slug', ['news', 'forum-news']);
|
||||
})
|
||||
->orderByDesc('t1.created_at')
|
||||
->limit(8)
|
||||
->get();
|
||||
} catch (QueryException $e) {
|
||||
Log::warning('Forum threads table missing or DB error when loading forum news', ['exception' => $e->getMessage()]);
|
||||
$forumNews = collect();
|
||||
}
|
||||
|
||||
// Our news (latest site news)
|
||||
try {
|
||||
$ourNews = DB::table('news as t1')
|
||||
->join('news_categories as c', 't1.category_id', '=', 'c.category_id')
|
||||
->join('users as u', 't1.user_id', '=', 'u.user_id')
|
||||
->selectRaw('t1.news_id, t1.headline, t1.user_id, t1.picture, t1.preview, u.uname, t1.create_date, t1.views, c.category_name, (SELECT COUNT(*) FROM news_comments WHERE news_id = t1.news_id) AS num_comments')
|
||||
->orderBy('t1.create_date', 'desc')
|
||||
->limit(5)
|
||||
->get();
|
||||
} catch (QueryException $e) {
|
||||
Log::warning('News table missing or DB error when loading our news', ['exception' => $e->getMessage()]);
|
||||
$ourNews = collect();
|
||||
}
|
||||
|
||||
// Latest forum activity (exclude forum news category)
|
||||
try {
|
||||
$latestForumActivity = DB::table('forum_threads as t1')
|
||||
->leftJoin('forum_categories as c', 't1.category_id', '=', 'c.id')
|
||||
->leftJoin('forum_posts as p', function ($join) {
|
||||
$join->on('p.thread_id', '=', 't1.id')
|
||||
->whereNull('p.deleted_at');
|
||||
})
|
||||
->selectRaw('t1.id as topic_id, t1.title as topic, COUNT(p.id) as numPosts')
|
||||
->whereNull('t1.deleted_at')
|
||||
->where(function ($query) {
|
||||
$query->where('t1.category_id', '<>', 2876)
|
||||
->orWhereNull('t1.category_id');
|
||||
})
|
||||
->where(function ($query) {
|
||||
$query->whereNull('c.slug')
|
||||
->orWhereNotIn('c.slug', ['news', 'forum-news']);
|
||||
})
|
||||
->groupBy('t1.id', 't1.title')
|
||||
->orderByDesc('t1.last_post_at')
|
||||
->orderByDesc('t1.created_at')
|
||||
->limit(10)
|
||||
->get();
|
||||
} catch (QueryException $e) {
|
||||
Log::warning('Forum threads table missing or DB error when loading latest forum activity', ['exception' => $e->getMessage()]);
|
||||
$latestForumActivity = collect();
|
||||
}
|
||||
|
||||
return view('web.home', compact(
|
||||
'page_title',
|
||||
'page_meta_description',
|
||||
'page_meta_keywords',
|
||||
'featured',
|
||||
'memberFeatured',
|
||||
'latestUploads',
|
||||
'forumNews',
|
||||
'ourNews',
|
||||
'latestForumActivity'
|
||||
));
|
||||
return view('web.home', [
|
||||
'meta' => $meta,
|
||||
'props' => $sections,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user