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:
2026-02-26 10:25:35 +01:00
parent d3fd32b004
commit d0aefc5ddc
78 changed files with 1046 additions and 221 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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'));
}
}

View File

@@ -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);
}
}

View File

@@ -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'));
}
}

View File

@@ -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',

View File

@@ -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,

View File

@@ -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,

View File

@@ -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',

View File

@@ -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,

View File

@@ -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'));
}
}

View File

@@ -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'));
}
}

View File

@@ -43,7 +43,7 @@ class LatestController extends Controller
];
});
return view('legacy.latest-artworks', [
return view('legacy::latest-artworks', [
'artworks' => $artworks,
'page_title' => 'Latest Artworks',
]);

View File

@@ -46,6 +46,6 @@ class MembersController extends Controller
});
}
return view('legacy.browse', compact('page_title', 'artworks'));
return view('legacy::browse', compact('page_title', 'artworks'));
}
}

View File

@@ -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'));
}
}

View File

@@ -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)

View File

@@ -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'));
}
}

View File

@@ -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'));
}
}

View File

@@ -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,
]);

View File

@@ -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,

View File

@@ -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',

View File

@@ -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]);
}
}

View File

@@ -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',
]);

View File

@@ -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'));
}
}

View File

@@ -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]);
}
}

View File

@@ -173,7 +173,7 @@ class UserController extends Controller
}
}
return view('legacy.user', [
return view('legacy::user', [
'user' => $user,
'birthDay' => $birthDay,
'birthMonth' => $birthMonth,