116 lines
4.4 KiB
PHP
116 lines
4.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Academy;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\AcademyPromptPack;
|
|
use App\Services\Academy\AcademyAccessService;
|
|
use App\Services\Academy\AcademyInteractionService;
|
|
use App\Support\AcademyAnalytics\AcademyAnalyticsContentType;
|
|
use App\Support\Seo\SeoFactory;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Str;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
final class AcademyPromptPackController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly AcademyAccessService $access,
|
|
private readonly AcademyInteractionService $interactions,
|
|
)
|
|
{
|
|
}
|
|
|
|
public function index(Request $request): Response
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$packs = AcademyPromptPack::query()
|
|
->with('prompts')
|
|
->active()
|
|
->published()
|
|
->latest('published_at')
|
|
->paginate(12)
|
|
->withQueryString();
|
|
|
|
$packs->getCollection()->transform(fn (AcademyPromptPack $pack): array => $this->access->packPayload($pack, $request->user()));
|
|
|
|
$seo = app(SeoFactory::class)
|
|
->collectionListing(
|
|
'Academy Prompt Packs — Skinbase',
|
|
'Preview bundled prompt packs for Skinbase wallpapers, worlds, mascots, and editorial workflows.',
|
|
route('academy.packs.index'),
|
|
)
|
|
->toArray();
|
|
|
|
return Inertia::render('Academy/List', [
|
|
'pageType' => 'packs',
|
|
'title' => 'Prompt packs',
|
|
'description' => 'Curated prompt bundles with free previews and premium pack access tiers.',
|
|
'seo' => $seo,
|
|
'items' => $packs,
|
|
'filters' => [],
|
|
'categories' => [],
|
|
'pricingUrl' => route('academy.pricing'),
|
|
'analytics' => [
|
|
'enabled' => true,
|
|
'contentType' => null,
|
|
'contentId' => null,
|
|
'eventUrl' => route('academy.analytics.events.store'),
|
|
'pageName' => 'academy_packs_index',
|
|
'isPremium' => false,
|
|
'isGuest' => $request->user() === null,
|
|
'isSubscriber' => $request->user()?->hasAcademyCreatorAccess() || $request->user()?->hasAcademyProAccess(),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
|
|
public function show(Request $request, string $slug): Response
|
|
{
|
|
abort_unless((bool) config('academy.enabled', true), 404);
|
|
|
|
$pack = AcademyPromptPack::query()
|
|
->with(['prompts.category'])
|
|
->active()
|
|
->published()
|
|
->where('slug', $slug)
|
|
->firstOrFail();
|
|
|
|
$payload = $this->access->packPayload($pack, $request->user(), true);
|
|
$seo = app(SeoFactory::class)->collectionPage(
|
|
$pack->title . ' — Skinbase Academy',
|
|
Str::limit((string) ($pack->excerpt ?? $pack->description ?? ''), 160, '...'),
|
|
route('academy.packs.show', ['slug' => $pack->slug]),
|
|
$pack->cover_image,
|
|
)->toArray();
|
|
|
|
$interaction = $this->interactions->getInteractionState($request->user(), AcademyAnalyticsContentType::PROMPT_PACK, (int) $pack->id);
|
|
|
|
return Inertia::render('Academy/Show', [
|
|
'pageType' => 'pack',
|
|
'item' => $payload,
|
|
'seo' => $seo,
|
|
'pricingUrl' => route('academy.pricing'),
|
|
'interaction' => $interaction,
|
|
'interactionRoutes' => [
|
|
'like' => route('academy.interactions.like'),
|
|
'save' => route('academy.interactions.save'),
|
|
],
|
|
'loginUrl' => route('login'),
|
|
'analytics' => [
|
|
'enabled' => true,
|
|
'contentType' => AcademyAnalyticsContentType::PROMPT_PACK,
|
|
'contentId' => (int) $pack->id,
|
|
'eventUrl' => route('academy.analytics.events.store'),
|
|
'pageName' => 'academy_pack_show',
|
|
'isPremium' => (string) ($pack->access_level ?? 'free') !== 'free',
|
|
'isGuest' => $request->user() === null,
|
|
'isSubscriber' => $request->user()?->hasAcademyCreatorAccess() || $request->user()?->hasAcademyProAccess(),
|
|
'isLocked' => (bool) ($payload['locked'] ?? false),
|
|
],
|
|
])->rootView('collections');
|
|
}
|
|
} |