publiclyVisible() ->latest('starts_at') ->paginate(12) ->withQueryString(); $challenges->getCollection()->transform(fn (AcademyChallenge $challenge): array => $this->access->challengePayload($challenge, $request->user(), true)); $seo = app(SeoFactory::class) ->collectionListing( 'Academy Challenges — Skinbase', 'Join Academy creative briefs, review accepted submissions, and explore current and archived AI Academy challenges.', route('academy.challenges.index'), ) ->toArray(); return Inertia::render('Academy/List', [ 'pageType' => 'challenges', 'title' => 'Academy challenges', 'description' => 'Creative briefs for wallpapers, worlds, covers, and prompt-driven visual experiments.', 'seo' => $seo, 'items' => $challenges, 'filters' => [], 'categories' => [], 'pricingUrl' => route('academy.pricing'), ])->rootView('collections'); } public function show(Request $request, string $slug): Response { abort_unless((bool) config('academy.enabled', true), 404); abort_unless((bool) config('academy.challenges_enabled', true), 404); $challenge = AcademyChallenge::query() ->with(['submissions' => fn ($query) => $query->approved()->with(['user:id,name,username', 'artwork'])]) ->publiclyVisible() ->where('slug', $slug) ->firstOrFail(); $payload = $this->access->challengePayload($challenge, $request->user(), true); $payload['submissions'] = $challenge->submissions->map(fn ($submission): array => [ 'id' => (int) $submission->id, 'user' => $submission->user ? [ 'id' => (int) $submission->user->id, 'name' => (string) $submission->user->name, 'username' => (string) ($submission->user->username ?? ''), ] : null, 'artwork' => $submission->artwork ? [ 'id' => (int) $submission->artwork->id, 'title' => (string) ($submission->artwork->title ?? 'Untitled artwork'), 'thumb_url' => $submission->artwork->thumbUrl('md'), ] : null, 'submitted_at' => $submission->submitted_at?->toISOString(), ])->values()->all(); $seo = app(SeoFactory::class)->collectionPage( $challenge->title . ' — Skinbase Academy', Str::limit((string) ($challenge->excerpt ?? $challenge->description ?? ''), 160, '...'), route('academy.challenges.show', ['slug' => $challenge->slug]), $challenge->cover_image, )->toArray(); return Inertia::render('Academy/Show', [ 'pageType' => 'challenge', 'item' => $payload, 'seo' => $seo, 'pricingUrl' => route('academy.pricing'), 'submitUrl' => $request->user() ? route('academy.challenges.submit', ['slug' => $challenge->slug]) : null, ])->rootView('collections'); } }