Save workspace changes

This commit is contained in:
2026-04-18 17:02:56 +02:00
parent f02ea9a711
commit 87d60af5a9
4220 changed files with 1388603 additions and 1554 deletions

View File

@@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\Group;
use App\Models\Leaderboard;
use App\Services\GroupDiscoveryService;
use App\Services\GroupMembershipService;
use App\Services\GroupService;
use App\Services\LeaderboardService;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\Request;
class GroupController extends Controller
{
public function __construct(
private readonly GroupService $groups,
private readonly GroupMembershipService $memberships,
private readonly GroupDiscoveryService $discovery,
private readonly LeaderboardService $leaderboards,
) {
}
public function index(Request $request): Response
{
$viewer = $request->user();
$surface = (string) $request->query('surface', 'featured');
$groups = $this->discovery->publicListing(
$viewer,
$surface,
(int) $request->query('page', 1),
24,
)
->through(fn (Group $group): array => $this->groups->mapGroupCard($group, $viewer));
return Inertia::render('Group/GroupIndex', [
'title' => 'Groups',
'description' => 'Collective publishing identities for collaborative artwork, collections, and shared presence on Skinbase Nova.',
'surfaces' => $this->discovery->availableSurfaces(),
'currentSurface' => $surface,
'spotlightGroup' => $this->discovery->spotlightCard($viewer, $surface),
'highlightSections' => [
[
'key' => 'featured',
'title' => 'Featured groups',
'description' => 'Established collectives publishing together across artworks, releases, and community initiatives.',
'items' => $this->discovery->surfaceCards($viewer, 'featured', 4),
],
[
'key' => 'recruiting',
'title' => 'Open for collaborators',
'description' => 'Groups currently recruiting artists, curators, moderators, and production contributors.',
'items' => $this->discovery->surfaceCards($viewer, 'recruiting', 4),
],
[
'key' => 'new_rising',
'title' => 'New and rising',
'description' => 'Emerging groups building momentum through fresh releases, shared projects, and fast growth.',
'items' => $this->discovery->surfaceCards($viewer, 'new_rising', 4),
],
],
'leaderboard' => $this->leaderboards->getLeaderboard(Leaderboard::TYPE_GROUP, Leaderboard::PERIOD_MONTHLY, 5),
'groups' => [
'data' => $groups->items(),
'meta' => [
'current_page' => $groups->currentPage(),
'last_page' => $groups->lastPage(),
'per_page' => $groups->perPage(),
'total' => $groups->total(),
],
],
])->rootView('collections');
}
public function show(Request $request, Group $group, string $section = 'overview'): Response
{
$this->authorize('view', $group);
$viewer = $request->user();
$group->loadMissing('owner.profile');
$members = collect($this->memberships->mapMembers($group, $viewer))
->where('status', Group::STATUS_ACTIVE)
->values()
->all();
$groupPayload = $this->groups->mapGroupDetail($group, $viewer);
return Inertia::render('Group/GroupShow', [
'group' => $groupPayload,
'section' => in_array($section, ['overview', 'artworks', 'collections', 'members', 'about', 'posts', 'projects', 'releases', 'challenges', 'events', 'activity'], true) ? $section : 'overview',
'featuredArtworks' => $this->groups->featuredArtworkCards($group),
'artworks' => $this->groups->publicArtworkCards($group),
'featuredCollections' => $this->groups->featuredCollectionCards($group, $viewer),
'collections' => $this->groups->publicCollectionCards($group, $viewer),
'members' => $members,
'leadership' => $this->groups->mapLeadershipPreview($members, $groupPayload['owner'] ?? []),
'posts' => $this->groups->publicPostListing($group),
'projects' => $this->groups->publicProjectListing($group, $viewer),
'releases' => $this->groups->publicReleaseListing($group, $viewer),
'challenges' => $this->groups->publicChallengeListing($group, $viewer),
'events' => $this->groups->publicEventListing($group, $viewer),
'assets' => $this->groups->publicAssetListing($group),
'activity' => $this->groups->publicActivityFeed($group),
'topContributors' => $groupPayload['top_contributors'] ?? [],
'trustSignals' => $groupPayload['trust_signals'] ?? [],
'badgeShowcase' => $groupPayload['badge_showcase'] ?? [],
'recruitment' => $this->groups->recruitmentPayload($group),
'reportEndpoint' => $viewer ? route('api.reports.store') : null,
])->rootView('collections');
}
public function posts(Request $request, Group $group): Response
{
return $this->show($request, $group, 'posts');
}
public function projects(Request $request, Group $group): Response
{
return $this->show($request, $group, 'projects');
}
public function releases(Request $request, Group $group): Response
{
return $this->show($request, $group, 'releases');
}
public function challenges(Request $request, Group $group): Response
{
return $this->show($request, $group, 'challenges');
}
public function events(Request $request, Group $group): Response
{
return $this->show($request, $group, 'events');
}
public function activity(Request $request, Group $group): Response
{
return $this->show($request, $group, 'activity');
}
}