Commit workspace changes

This commit is contained in:
2026-04-05 19:42:33 +02:00
parent 148a3bbe43
commit 08ad757bcb
312 changed files with 35149 additions and 399 deletions

View 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');
}
}

View File

@@ -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,
]);
}

View 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');
}
}

View 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');
}
}

View 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');
}
}

View 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');
}
}

View 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');
}
}

View 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');
}
}

View File

@@ -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(),
]);

View 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');
}
}

View File

@@ -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',
]);
}

View 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');
}
}

View File

@@ -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');
}
}

View 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');
}
}