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:
119
app/Http/Controllers/Admin/EarlyGrowthAdminController.php
Normal file
119
app/Http/Controllers/Admin/EarlyGrowthAdminController.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\EarlyGrowth\ActivityLayer;
|
||||
use App\Services\EarlyGrowth\AdaptiveTimeWindow;
|
||||
use App\Services\EarlyGrowth\EarlyGrowth;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
* EarlyGrowthAdminController (§14)
|
||||
*
|
||||
* Admin panel for the Early-Stage Growth System.
|
||||
* All toggles are ENV-driven; updating .env requires a deploy.
|
||||
* This panel provides a read-only status view plus a cache-flush action.
|
||||
*
|
||||
* Future v2: wire to a `settings` DB table so admins can toggle without
|
||||
* a deploy. The EarlyGrowth::enabled() contract already supports this.
|
||||
*/
|
||||
final class EarlyGrowthAdminController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AdaptiveTimeWindow $timeWindow,
|
||||
private readonly ActivityLayer $activityLayer,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* GET /admin/early-growth
|
||||
* Status dashboard: shows current config, live stats, toggle instructions.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
$uploadsPerDay = $this->timeWindow->getUploadsPerDay();
|
||||
|
||||
return view('admin.early-growth.index', [
|
||||
'status' => EarlyGrowth::status(),
|
||||
'mode' => EarlyGrowth::mode(),
|
||||
'uploads_per_day' => $uploadsPerDay,
|
||||
'window_days' => $this->timeWindow->getTrendingWindowDays(30),
|
||||
'activity' => $this->activityLayer->getSignals(),
|
||||
'cache_keys' => [
|
||||
'egs.uploads_per_day',
|
||||
'egs.auto_disable_check',
|
||||
'egs.spotlight.*',
|
||||
'egs.curated.*',
|
||||
'egs.grid_filler.*',
|
||||
'egs.activity_signals',
|
||||
'homepage.fresh.*',
|
||||
'discover.trending.*',
|
||||
'discover.rising.*',
|
||||
],
|
||||
'env_toggles' => [
|
||||
['key' => 'NOVA_EARLY_GROWTH_ENABLED', 'current' => env('NOVA_EARLY_GROWTH_ENABLED', 'false')],
|
||||
['key' => 'NOVA_EARLY_GROWTH_MODE', 'current' => env('NOVA_EARLY_GROWTH_MODE', 'off')],
|
||||
['key' => 'NOVA_EGS_ADAPTIVE_WINDOW', 'current' => env('NOVA_EGS_ADAPTIVE_WINDOW', 'true')],
|
||||
['key' => 'NOVA_EGS_GRID_FILLER', 'current' => env('NOVA_EGS_GRID_FILLER', 'true')],
|
||||
['key' => 'NOVA_EGS_SPOTLIGHT', 'current' => env('NOVA_EGS_SPOTLIGHT', 'true')],
|
||||
['key' => 'NOVA_EGS_ACTIVITY_LAYER', 'current' => env('NOVA_EGS_ACTIVITY_LAYER', 'false')],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /admin/early-growth/cache
|
||||
* Flush all EGS-related cache keys so new config changes take effect immediately.
|
||||
*/
|
||||
public function flushCache(Request $request): RedirectResponse
|
||||
{
|
||||
$keys = [
|
||||
'egs.uploads_per_day',
|
||||
'egs.auto_disable_check',
|
||||
'egs.activity_signals',
|
||||
];
|
||||
|
||||
// Flush the EGS daily spotlight caches for today
|
||||
$today = now()->format('Y-m-d');
|
||||
foreach ([6, 12, 18, 24] as $n) {
|
||||
Cache::forget("egs.spotlight.{$today}.{$n}");
|
||||
Cache::forget("egs.curated.{$today}.{$n}.7");
|
||||
}
|
||||
|
||||
// Flush fresh/trending homepage sections
|
||||
foreach ([6, 8, 10, 12] as $limit) {
|
||||
foreach (['off', 'light', 'aggressive'] as $mode) {
|
||||
Cache::forget("homepage.fresh.{$limit}.egs-{$mode}");
|
||||
Cache::forget("homepage.fresh.{$limit}.std");
|
||||
}
|
||||
Cache::forget("homepage.trending.{$limit}");
|
||||
Cache::forget("homepage.rising.{$limit}");
|
||||
}
|
||||
|
||||
// Flush key keys
|
||||
foreach ($keys as $key) {
|
||||
Cache::forget($key);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.early-growth.index')
|
||||
->with('success', 'Early Growth System cache flushed. Changes will take effect on next page load.');
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /admin/early-growth/status (JSON — for monitoring/healthcheck)
|
||||
*/
|
||||
public function status(): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'egs' => EarlyGrowth::status(),
|
||||
'uploads_per_day' => $this->timeWindow->getUploadsPerDay(),
|
||||
'window_days' => $this->timeWindow->getTrendingWindowDays(30),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user