Commit workspace changes
This commit is contained in:
52
app/Http/Controllers/Web/AccountHelpPageController.php
Normal file
52
app/Http/Controllers/Web/AccountHelpPageController.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class AccountHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.account');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Account Settings Help — Skinbase',
|
||||
'Learn how account settings, profile settings, email changes, password care, and creator preferences work on Skinbase Nova.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/AccountHelpPage', [
|
||||
'title' => 'Account Settings Help',
|
||||
'description' => 'Use this guide when account access already works and you need practical help with settings, identity details, email and password care, or ongoing account maintenance.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'help_auth' => route('help.auth'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'help_troubleshooting' => route('help.troubleshooting'),
|
||||
'profile_settings' => route('dashboard.profile'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'login' => route('login'),
|
||||
'register' => route('register'),
|
||||
'password_request' => route('password.request'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use App\Models\ArtworkComment;
|
||||
use App\Services\ContentSanitizer;
|
||||
use App\Services\ThumbnailPresenter;
|
||||
use App\Services\ErrorSuggestionService;
|
||||
use App\Services\GroupService;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use App\Support\AvatarUrl;
|
||||
use Illuminate\Support\Carbon;
|
||||
@@ -22,6 +23,8 @@ use Illuminate\View\View;
|
||||
|
||||
final class ArtworkPageController extends Controller
|
||||
{
|
||||
public function __construct(private readonly GroupService $groups) {}
|
||||
|
||||
public function show(Request $request, int $id, ?string $slug = null): View|RedirectResponse|Response
|
||||
{
|
||||
// ── Step 1: check existence including soft-deleted ─────────────────
|
||||
@@ -84,7 +87,7 @@ final class ArtworkPageController extends Controller
|
||||
}
|
||||
|
||||
// ── Step 2: full load with all relations ───────────────────────────
|
||||
$artwork = Artwork::with(['user.profile', 'categories.contentType', 'categories.parent.contentType', 'tags', 'stats', 'awardStat'])
|
||||
$artwork = Artwork::with(['user.profile', 'group.owner.profile', 'uploadedBy.profile', 'primaryAuthor.profile', 'contributors.user.profile', 'categories.contentType', 'categories.parent.contentType', 'tags', 'stats', 'awardStat'])
|
||||
->where('id', $id)
|
||||
->public()
|
||||
->published()
|
||||
@@ -108,9 +111,15 @@ final class ArtworkPageController extends Controller
|
||||
$thumbSq = ThumbnailPresenter::present($artwork, 'sq');
|
||||
|
||||
$artworkData = (new ArtworkResource($artwork))->toArray($request);
|
||||
$groupSummary = null;
|
||||
|
||||
if ($artwork->group) {
|
||||
$artwork->group->loadMissing(['owner.profile', 'recruitmentProfile', 'discoveryMetric', 'members', 'badges']);
|
||||
$groupSummary = $this->groups->mapGroupCard($artwork->group, $request->user());
|
||||
}
|
||||
|
||||
$canonical = route('art.show', ['id' => $artwork->id, 'slug' => $canonicalSlug]);
|
||||
$authorName = $artwork->user?->name ?: $artwork->user?->username ?: 'Artist';
|
||||
$authorName = $artwork->group?->name ?: $artwork->primaryAuthor?->name ?: $artwork->primaryAuthor?->username ?: $artwork->user?->name ?: $artwork->user?->username ?: 'Artist';
|
||||
$description = Str::limit(trim(strip_tags(html_entity_decode((string) ($artwork->description ?? ''), ENT_QUOTES | ENT_HTML5, 'UTF-8'))), 160, '…');
|
||||
|
||||
$meta = [
|
||||
@@ -132,13 +141,17 @@ final class ArtworkPageController extends Controller
|
||||
$tagIds = $artwork->tags->pluck('id')->filter()->values();
|
||||
|
||||
$related = Artwork::query()
|
||||
->with(['user', 'categories.contentType'])
|
||||
->with(['user', 'group', 'categories.contentType'])
|
||||
->whereKeyNot($artwork->id)
|
||||
->public()
|
||||
->published()
|
||||
->where(function ($query) use ($artwork, $categoryIds, $tagIds): void {
|
||||
$query->where('user_id', $artwork->user_id);
|
||||
|
||||
if ($artwork->group_id) {
|
||||
$query->orWhere('group_id', $artwork->group_id);
|
||||
}
|
||||
|
||||
if ($categoryIds->isNotEmpty()) {
|
||||
$query->orWhereHas('categories', function ($categoryQuery) use ($categoryIds): void {
|
||||
$categoryQuery->whereIn('categories.id', $categoryIds->all());
|
||||
@@ -166,7 +179,7 @@ final class ArtworkPageController extends Controller
|
||||
return [
|
||||
'id' => (int) $item->id,
|
||||
'title' => html_entity_decode((string) $item->title, ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||
'author' => html_entity_decode((string) ($item->user?->name ?: $item->user?->username ?: 'Artist'), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||
'author' => html_entity_decode((string) ($item->group?->name ?: $item->user?->name ?: $item->user?->username ?: 'Artist'), ENT_QUOTES | ENT_HTML5, 'UTF-8'),
|
||||
'url' => route('art.show', ['id' => $item->id, 'slug' => $itemSlug]),
|
||||
'thumb' => $md['url'] ?? null,
|
||||
'thumb_srcset' => ($md['url'] ?? '') . ' 640w, ' . ($lg['url'] ?? '') . ' 1280w',
|
||||
@@ -237,6 +250,7 @@ final class ArtworkPageController extends Controller
|
||||
'useUnifiedSeo' => true,
|
||||
'relatedItems' => $related,
|
||||
'comments' => $comments,
|
||||
'groupSummary' => $groupSummary,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
53
app/Http/Controllers/Web/AuthHelpPageController.php
Normal file
53
app/Http/Controllers/Web/AuthHelpPageController.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class AuthHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.auth');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Signup and Login Help — Skinbase',
|
||||
'Learn how signup, login, password recovery, verification, and account access work on Skinbase Nova, with clear guidance for common access problems and practical next steps.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/AuthHelpPage', [
|
||||
'title' => 'Signup & Login Help',
|
||||
'description' => 'Get clear help for account creation, sign-in, password recovery, verification basics, and common access problems on Skinbase Nova.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'help_account' => route('help.account'),
|
||||
'help_troubleshooting' => route('help.troubleshooting'),
|
||||
'login' => route('login'),
|
||||
'register' => route('register'),
|
||||
'password_request' => route('password.request'),
|
||||
'verification_notice' => route('verification.notice'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'profile_settings' => route('dashboard.profile'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
50
app/Http/Controllers/Web/CardsHelpPageController.php
Normal file
50
app/Http/Controllers/Web/CardsHelpPageController.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class CardsHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.cards');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Cards Help — Skinbase',
|
||||
'Learn what Cards are on Skinbase Nova, how they differ from artworks, posts, and collections, and how to create, publish, and use them effectively in personal and Group workflows.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/CardsHelpPage', [
|
||||
'title' => 'Cards Help',
|
||||
'description' => 'Understand Cards as a distinct creative format on Skinbase Nova, with guidance for creation, publishing, ownership, design quality, and real-world use cases.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'studio_cards' => route('studio.cards.index'),
|
||||
'create_card' => route('studio.cards.create'),
|
||||
'cards_index' => route('cards.index'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
47
app/Http/Controllers/Web/GroupFaqPageController.php
Normal file
47
app/Http/Controllers/Web/GroupFaqPageController.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class GroupFaqPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.groups.faq');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Groups FAQ — Skinbase',
|
||||
'Fast answers to the most common Groups questions on Skinbase Nova, including roles, permissions, publishing, contributor credit, invites, workflows, and troubleshooting.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Group/GroupFaqPage', [
|
||||
'title' => 'Groups FAQ',
|
||||
'description' => 'Quick answers about Groups, roles, permissions, publishing, contributor credit, invites, workflows, and troubleshooting on Skinbase Nova.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'groups_directory' => route('groups.index'),
|
||||
'create_group' => route('studio.groups.create'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'full_documentation' => route('help.groups'),
|
||||
'quickstart' => route('help.groups.quickstart'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
'help_home' => route('help'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
47
app/Http/Controllers/Web/GroupHelpPageController.php
Normal file
47
app/Http/Controllers/Web/GroupHelpPageController.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class GroupHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.groups');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Groups Guide, Help, and Best Practices — Skinbase',
|
||||
'Learn how Groups work on Skinbase Nova, how shared publishing preserves contributor credit, and how to manage roles, releases, reviews, projects, and team workflows with confidence.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Group/GroupHelpPage', [
|
||||
'title' => 'Groups Help & Guide',
|
||||
'description' => 'Everything creators need to understand Groups, publish collaboratively, preserve contributor credit, and build a healthy shared identity on Skinbase Nova.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'groups_directory' => route('groups.index'),
|
||||
'create_group' => route('studio.groups.create'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'quickstart' => route('help.groups.quickstart'),
|
||||
'faq' => route('help.groups.faq'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
'help_home' => route('help'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
45
app/Http/Controllers/Web/GroupQuickstartPageController.php
Normal file
45
app/Http/Controllers/Web/GroupQuickstartPageController.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class GroupQuickstartPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.groups.quickstart');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Groups Quickstart — Skinbase',
|
||||
'A fast, creator-friendly Groups quickstart for Skinbase Nova. Learn when to use a Group, create one, invite members, and publish your first Group artwork with correct contributor credit.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Group/GroupQuickstartPage', [
|
||||
'title' => 'Groups Quickstart',
|
||||
'description' => 'The fastest way to understand Groups, create one, invite members, and publish your first collaborative artwork with correct contributor credit.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'groups_directory' => route('groups.index'),
|
||||
'create_group' => route('studio.groups.create'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'full_documentation' => route('help.groups'),
|
||||
'faq' => route('help.groups.faq'),
|
||||
'help_home' => route('help'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
68
app/Http/Controllers/Web/HelpCenterPageController.php
Normal file
68
app/Http/Controllers/Web/HelpCenterPageController.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class HelpCenterPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Help Center — Skinbase',
|
||||
'Find help, guides, quickstarts, FAQs, and troubleshooting for Skinbase Nova, including Groups, Studio, Upload, Cards, Profile, and account access.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'website';
|
||||
|
||||
return Inertia::render('Help/HelpCenterPage', [
|
||||
'title' => 'Help Center',
|
||||
'description' => 'Find guides, quickstarts, FAQs, and troubleshooting for Skinbase Nova in one structured help hub.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'studio_help' => route('help.studio'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'groups_documentation' => route('help.groups'),
|
||||
'groups_quickstart' => route('help.groups.quickstart'),
|
||||
'groups_faq' => route('help.groups.faq'),
|
||||
'groups_directory' => route('groups.index'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'create_group' => route('studio.groups.create'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'studio_home' => route('studio.index'),
|
||||
'studio_content' => route('studio.content'),
|
||||
'studio_artworks' => route('studio.artworks'),
|
||||
'studio_cards' => route('studio.cards.index'),
|
||||
'studio_drafts' => route('studio.drafts'),
|
||||
'cards_create' => route('studio.cards.create'),
|
||||
'upload' => route('upload'),
|
||||
'cards_index' => route('cards.index'),
|
||||
'help_cards' => route('help.cards'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'help_auth' => route('help.auth'),
|
||||
'help_account' => route('help.account'),
|
||||
'help_troubleshooting' => route('help.troubleshooting'),
|
||||
'profile_settings' => route('dashboard.profile'),
|
||||
'login' => route('login'),
|
||||
'register' => route('register'),
|
||||
'password_request' => route('password.request'),
|
||||
'help_upload' => route('help', ['q' => 'upload']),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
@@ -19,17 +19,32 @@ class LeaderboardPageController extends Controller
|
||||
$period = $leaderboards->normalizePeriod((string) $request->query('period', 'weekly'));
|
||||
$type = match ((string) $request->query('type', 'creators')) {
|
||||
'artworks', Leaderboard::TYPE_ARTWORK => Leaderboard::TYPE_ARTWORK,
|
||||
'groups', Leaderboard::TYPE_GROUP => Leaderboard::TYPE_GROUP,
|
||||
'stories', Leaderboard::TYPE_STORY => Leaderboard::TYPE_STORY,
|
||||
default => Leaderboard::TYPE_CREATOR,
|
||||
};
|
||||
|
||||
$title = match ($type) {
|
||||
Leaderboard::TYPE_GROUP => 'Top Groups Leaderboard — Skinbase',
|
||||
Leaderboard::TYPE_STORY => 'Top Stories Leaderboard — Skinbase',
|
||||
Leaderboard::TYPE_ARTWORK => 'Top Artworks Leaderboard — Skinbase',
|
||||
default => 'Top Creators & Artworks Leaderboard — Skinbase',
|
||||
};
|
||||
|
||||
$description = match ($type) {
|
||||
Leaderboard::TYPE_GROUP => 'Track the leading groups across Skinbase by daily, weekly, monthly, and all-time performance.',
|
||||
Leaderboard::TYPE_STORY => 'Track the leading stories across Skinbase by daily, weekly, monthly, and all-time performance.',
|
||||
Leaderboard::TYPE_ARTWORK => 'Track the leading artworks across Skinbase by daily, weekly, monthly, and all-time performance.',
|
||||
default => 'Track the leading creators, groups, artworks, and stories across Skinbase by daily, weekly, monthly, and all-time performance.',
|
||||
};
|
||||
|
||||
return Inertia::render('Leaderboard/LeaderboardPage', [
|
||||
'initialType' => $type,
|
||||
'initialPeriod' => $period,
|
||||
'initialData' => $leaderboards->getLeaderboard($type, $period),
|
||||
'seo' => app(SeoFactory::class)->leaderboardPage(
|
||||
'Top Creators & Artworks Leaderboard — Skinbase',
|
||||
'Track the leading creators, artworks, and stories across Skinbase by daily, weekly, monthly, and all-time performance.',
|
||||
$title,
|
||||
$description,
|
||||
route('leaderboard')
|
||||
)->toArray(),
|
||||
]);
|
||||
|
||||
51
app/Http/Controllers/Web/ProfileHelpPageController.php
Normal file
51
app/Http/Controllers/Web/ProfileHelpPageController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class ProfileHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.profile');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Profile Help — Skinbase',
|
||||
'Learn how profiles work on Skinbase Nova, how they differ from Groups, and how to build a stronger personal identity with better setup, presentation, and creator-facing profile habits.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/ProfileHelpPage', [
|
||||
'title' => 'Profile Help',
|
||||
'description' => 'Understand your Skinbase profile as your personal public identity, with practical guidance for setup, presentation, profile content, and creator-friendly best practices.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'cards_help' => route('help.cards'),
|
||||
'profile_settings' => route('dashboard.profile'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'help_auth' => route('help.auth'),
|
||||
'login' => route('login'),
|
||||
'register' => route('register'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,17 @@ namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\ArtworkSearchService;
|
||||
use App\Services\GroupDiscoveryService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use cPad\Plugins\News\Models\NewsArticle;
|
||||
|
||||
final class SearchController extends Controller
|
||||
{
|
||||
public function __construct(private readonly ArtworkSearchService $search) {}
|
||||
public function __construct(
|
||||
private readonly ArtworkSearchService $search,
|
||||
private readonly GroupDiscoveryService $groups,
|
||||
) {}
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
@@ -31,12 +36,33 @@ final class SearchController extends Controller
|
||||
])
|
||||
: $this->search->popular(24);
|
||||
|
||||
$groups = $q !== ''
|
||||
? $this->groups->searchCards($q, $request->user(), 6)
|
||||
: $this->groups->surfaceCards($request->user(), 'featured', 4);
|
||||
|
||||
$news = $q !== ''
|
||||
? NewsArticle::query()
|
||||
->with(['author:id,username,name', 'category:id,name,slug'])
|
||||
->published()
|
||||
->where(function ($builder) use ($q): void {
|
||||
$builder->where('title', 'like', '%' . $q . '%')
|
||||
->orWhere('excerpt', 'like', '%' . $q . '%')
|
||||
->orWhere('content', 'like', '%' . $q . '%')
|
||||
->orWhere('meta_title', 'like', '%' . $q . '%');
|
||||
})
|
||||
->editorialOrder()
|
||||
->limit(4)
|
||||
->get()
|
||||
: collect();
|
||||
|
||||
return view('search.index', [
|
||||
'q' => $q,
|
||||
'sort' => $sort,
|
||||
'groups' => $groups,
|
||||
'artworks' => $artworks,
|
||||
'news' => $news,
|
||||
'page_title' => $q !== '' ? 'Search: ' . $q . ' — Skinbase' : 'Search — Skinbase',
|
||||
'page_meta_description' => 'Search Skinbase for artworks, photography, wallpapers and skins.',
|
||||
'page_meta_description' => 'Search Skinbase for artworks, creators, groups, photography, wallpapers and skins.',
|
||||
'page_robots' => 'noindex,follow',
|
||||
]);
|
||||
}
|
||||
|
||||
60
app/Http/Controllers/Web/StudioHelpPageController.php
Normal file
60
app/Http/Controllers/Web/StudioHelpPageController.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class StudioHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.studio');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Studio Help — Skinbase',
|
||||
'Learn how Studio works on Skinbase Nova, including drafts, publishing, personal versus Group context, artworks, cards, collections, and collaboration workflows.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/StudioHelpPage', [
|
||||
'title' => 'Studio Help',
|
||||
'description' => 'Understand Studio as the creative control center of Skinbase Nova, with guidance for drafts, publishing, artworks, cards, collections, and Group workflows.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'studio_content' => route('studio.content'),
|
||||
'studio_artworks' => route('studio.artworks'),
|
||||
'studio_drafts' => route('studio.drafts'),
|
||||
'studio_scheduled' => route('studio.scheduled'),
|
||||
'studio_collections' => route('studio.collections'),
|
||||
'studio_settings' => route('studio.settings'),
|
||||
'studio_cards' => route('studio.cards.index'),
|
||||
'create_card' => route('studio.cards.create'),
|
||||
'upload' => route('upload'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'groups_quickstart' => route('help.groups.quickstart'),
|
||||
'groups_faq' => route('help.groups.faq'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'help_cards' => route('help.cards'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'help_auth' => route('help.auth'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class TroubleshootingHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.troubleshooting');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Troubleshooting Help — Skinbase',
|
||||
'Use fast, support-oriented troubleshooting guidance for login issues, permissions confusion, publishing blockers, profile setup problems, and bug-report escalation on Skinbase Nova.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/TroubleshootingHelpPage', [
|
||||
'title' => 'Troubleshooting Help',
|
||||
'description' => 'Use diagnosis-first help when something feels broken, blocked, or unclear and you need the fastest next step instead of a long module guide.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'help_auth' => route('help.auth'),
|
||||
'help_account' => route('help.account'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'upload_help' => route('help.upload'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'groups_faq' => route('help.groups.faq'),
|
||||
'profile_settings' => route('dashboard.profile'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'login' => route('login'),
|
||||
'register' => route('register'),
|
||||
'password_request' => route('password.request'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
53
app/Http/Controllers/Web/UploadHelpPageController.php
Normal file
53
app/Http/Controllers/Web/UploadHelpPageController.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\Seo\SeoFactory;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Inertia;
|
||||
use Inertia\Response;
|
||||
|
||||
final class UploadHelpPageController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
$canonical = route('help.upload');
|
||||
$seo = app(SeoFactory::class)
|
||||
->collectionPage(
|
||||
'Upload Help — Skinbase',
|
||||
'Learn how uploading works on Skinbase Nova, including draft creation, metadata review, previews, personal versus Group context, contributor credit, publishing, and troubleshooting.',
|
||||
$canonical,
|
||||
)
|
||||
->toArray();
|
||||
|
||||
$seo['og_type'] = 'article';
|
||||
|
||||
return Inertia::render('Help/UploadHelpPage', [
|
||||
'title' => 'Upload Help',
|
||||
'description' => 'Understand the full upload workflow on Skinbase Nova, from file submission and draft creation to metadata review, contributor credit, and final publish.',
|
||||
'seo' => $seo,
|
||||
'links' => [
|
||||
'help_home' => route('help'),
|
||||
'upload' => route('upload'),
|
||||
'studio_help' => route('help.studio'),
|
||||
'open_studio' => route('studio.index'),
|
||||
'studio_artworks' => route('studio.artworks'),
|
||||
'studio_drafts' => route('studio.drafts'),
|
||||
'groups_help' => route('help.groups'),
|
||||
'groups_quickstart' => route('help.groups.quickstart'),
|
||||
'groups_faq' => route('help.groups.faq'),
|
||||
'group_studio' => route('studio.groups.index'),
|
||||
'help_cards' => route('help.cards'),
|
||||
'help_profile' => route('help.profile'),
|
||||
'contact_support' => route('contact.show'),
|
||||
'report_issue' => route('bug-report'),
|
||||
],
|
||||
'auth' => [
|
||||
'signed_in' => $request->user() !== null,
|
||||
],
|
||||
])->rootView('collections');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user