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'), ])->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(); return Inertia::render('Academy/Show', [ 'pageType' => 'pack', 'item' => $payload, 'seo' => $seo, 'pricingUrl' => route('academy.pricing'), ])->rootView('collections'); } }