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