feat: Inertia profile settings page, Studio edit redesign, EGS, Nova UI components\n\n- Redesign /dashboard/profile as Inertia React page (Settings/ProfileEdit)\n with SettingsLayout sidebar, Nova UI components (TextInput, Textarea,\n Toggle, Select, RadioGroup, Modal, Button), avatar drag-and-drop,\n password change, and account deletion sections\n- Redesign Studio artwork edit page with two-column layout, Nova components,\n integrated TagPicker, and version history modal\n- Add shared MarkdownEditor component\n- Add Early-Stage Growth System (EGS): SpotlightEngine, FeedBlender,\n GridFiller, AdaptiveTimeWindow, ActivityLayer, admin panel\n- Fix upload category/tag persistence (V1+V2 paths)\n- Fix tag source enum, category tree display, binding resolution\n- Add settings.jsx Vite entry, settings.blade.php wrapper\n- Update ProfileController with JSON response support for API calls\n- Various route fixes (profile.edit, toolbar settings link)"
This commit is contained in:
@@ -6,6 +6,8 @@ use App\Http\Controllers\Controller;
|
||||
use App\Models\Artwork;
|
||||
use App\Services\ArtworkSearchService;
|
||||
use App\Services\ArtworkService;
|
||||
use App\Services\EarlyGrowth\FeedBlender;
|
||||
use App\Services\EarlyGrowth\GridFiller;
|
||||
use App\Services\Recommendation\RecommendationService;
|
||||
use App\Services\ThumbnailPresenter;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -27,17 +29,21 @@ use Illuminate\Support\Facades\Schema;
|
||||
final class DiscoverController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ArtworkService $artworkService,
|
||||
private readonly ArtworkSearchService $searchService,
|
||||
private readonly ArtworkService $artworkService,
|
||||
private readonly ArtworkSearchService $searchService,
|
||||
private readonly RecommendationService $recoService,
|
||||
private readonly FeedBlender $feedBlender,
|
||||
private readonly GridFiller $gridFiller,
|
||||
) {}
|
||||
|
||||
// ─── /discover/trending ──────────────────────────────────────────────────
|
||||
|
||||
public function trending(Request $request)
|
||||
{
|
||||
$perPage = 24;
|
||||
$results = $this->searchService->discoverTrending($perPage);
|
||||
$perPage = 24;
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$results = $this->searchService->discoverTrending($perPage);
|
||||
$results = $this->gridFiller->fill($results, 0, $page);
|
||||
$this->hydrateDiscoverSearchResults($results);
|
||||
|
||||
return view('web.discover.index', [
|
||||
@@ -53,8 +59,10 @@ final class DiscoverController extends Controller
|
||||
|
||||
public function rising(Request $request)
|
||||
{
|
||||
$perPage = 24;
|
||||
$results = $this->searchService->discoverRising($perPage);
|
||||
$perPage = 24;
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$results = $this->searchService->discoverRising($perPage);
|
||||
$results = $this->gridFiller->fill($results, 0, $page);
|
||||
$this->hydrateDiscoverSearchResults($results);
|
||||
|
||||
return view('web.discover.index', [
|
||||
@@ -70,8 +78,12 @@ final class DiscoverController extends Controller
|
||||
|
||||
public function fresh(Request $request)
|
||||
{
|
||||
$perPage = 24;
|
||||
$results = $this->searchService->discoverFresh($perPage);
|
||||
$perPage = 24;
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$results = $this->searchService->discoverFresh($perPage);
|
||||
// EGS: blend fresh feed with curated + spotlight on page 1
|
||||
$results = $this->feedBlender->blend($results, $perPage, $page);
|
||||
$results = $this->gridFiller->fill($results, 0, $page);
|
||||
$this->hydrateDiscoverSearchResults($results);
|
||||
|
||||
return view('web.discover.index', [
|
||||
@@ -87,8 +99,10 @@ final class DiscoverController extends Controller
|
||||
|
||||
public function topRated(Request $request)
|
||||
{
|
||||
$perPage = 24;
|
||||
$results = $this->searchService->discoverTopRated($perPage);
|
||||
$perPage = 24;
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$results = $this->searchService->discoverTopRated($perPage);
|
||||
$results = $this->gridFiller->fill($results, 0, $page);
|
||||
$this->hydrateDiscoverSearchResults($results);
|
||||
|
||||
return view('web.discover.index', [
|
||||
@@ -104,8 +118,10 @@ final class DiscoverController extends Controller
|
||||
|
||||
public function mostDownloaded(Request $request)
|
||||
{
|
||||
$perPage = 24;
|
||||
$results = $this->searchService->discoverMostDownloaded($perPage);
|
||||
$perPage = 24;
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$results = $this->searchService->discoverMostDownloaded($perPage);
|
||||
$results = $this->gridFiller->fill($results, 0, $page);
|
||||
$this->hydrateDiscoverSearchResults($results);
|
||||
|
||||
return view('web.discover.index', [
|
||||
@@ -180,7 +196,8 @@ final class DiscoverController extends Controller
|
||||
$creators = DB::table(DB::raw('(' . $sub->toSql() . ') as t'))
|
||||
->mergeBindings($sub->getQuery())
|
||||
->join('users as u', 'u.id', '=', 't.user_id')
|
||||
->select('u.id as user_id', 'u.name as uname', 'u.username', 't.recent_views', 't.latest_published')
|
||||
->leftJoin('user_profiles as up', 'up.user_id', '=', 't.user_id')
|
||||
->select('u.id as user_id', 'u.name as uname', 'u.username', 't.recent_views', 't.latest_published', 'up.avatar_hash')
|
||||
->orderByDesc('t.recent_views')
|
||||
->orderByDesc('t.latest_published')
|
||||
->paginate($perPage)
|
||||
@@ -188,11 +205,12 @@ final class DiscoverController extends Controller
|
||||
|
||||
$creators->getCollection()->transform(function ($row) {
|
||||
return (object) [
|
||||
'user_id' => $row->user_id,
|
||||
'uname' => $row->uname,
|
||||
'username' => $row->username,
|
||||
'total' => (int) $row->recent_views,
|
||||
'metric' => 'views',
|
||||
'user_id' => $row->user_id,
|
||||
'uname' => $row->uname,
|
||||
'username' => $row->username,
|
||||
'total' => (int) $row->recent_views,
|
||||
'metric' => 'views',
|
||||
'avatar_hash' => $row->avatar_hash ?? null,
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user