authorize('view', $group); abort_unless((int) $project->group_id === (int) $group->id, 404); abort_unless($project->canBeViewedBy($request->user()), 403); $groupPayload = $this->groups->mapGroupDetail($group, $request->user()); $projectPayload = $this->projects->detailPayload($project, $request->user()); $canonical = route('groups.projects.show', ['group' => $group, 'project' => $project]); $description = Str::limit(trim(strip_tags((string) ($projectPayload['summary'] ?? $projectPayload['description'] ?? $groupPayload['headline'] ?? 'Group project on Skinbase.'))), 160, '…'); $seo = app(SeoFactory::class)->collectionPage( sprintf('%s — %s — Skinbase', $project->title, $group->name), $description, $canonical, $projectPayload['cover_url'] ?? null, )->toArray(); $seo['og_type'] = 'article'; $seo['json_ld'] = [[ '@context' => 'https://schema.org', '@type' => 'CreativeWork', 'name' => (string) $project->title, 'description' => $description, 'url' => $canonical, 'image' => $projectPayload['cover_url'] ?? null, 'dateCreated' => $project->created_at?->toAtomString(), 'publisher' => ['@type' => 'Organization', 'name' => (string) $group->name], ]]; return Inertia::render('Group/GroupProjectShow', [ 'group' => $groupPayload, 'project' => $projectPayload, 'seo' => $seo, ])->rootView('collections'); } }