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,160 @@
<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\Group;
use App\Models\User;
use App\Support\AvatarUrl;
use Illuminate\Support\Str;
class GroupCardService
{
public function __construct(
private readonly GroupRecruitmentService $recruitment,
private readonly GroupReputationService $reputation,
private readonly GroupFollowService $follows,
private readonly GroupMembershipService $memberships,
) {
}
public function mapGroupCard(Group $group, ?User $viewer = null): array
{
$owner = $group->relationLoaded('owner') ? $group->owner : $group->owner()->with('profile')->first();
$recruitment = $this->recruitment->payloadForGroup($group);
$canManage = $viewer ? $group->canManage($viewer) : false;
$canManageMembers = $viewer ? $group->canManageMembers($viewer) : false;
$canPublishArtworks = $viewer ? $group->canPublishArtworks($viewer) : false;
$canManageCollections = $viewer ? $group->canManageCollections($viewer) : false;
$canRequestJoin = $viewer ? $group->canRequestJoin($viewer) : false;
$canReviewJoinRequests = $viewer ? $group->canReviewJoinRequests($viewer) : false;
$canReviewSubmissions = $viewer ? $group->canReviewSubmissions($viewer) : false;
$canManageRecruitment = $viewer ? $group->canManageRecruitment($viewer) : false;
$canManagePosts = $viewer ? $group->canManagePosts($viewer) : false;
$canPublishPosts = $viewer ? $group->canPublishPosts($viewer) : false;
$canPinPosts = $viewer ? $group->canPinPosts($viewer) : false;
$canManageMemberPermissions = $viewer ? $group->canManageMemberPermissions($viewer) : false;
$canManageProjects = $viewer ? $group->canManageProjects($viewer) : false;
$canManageReleases = $viewer ? $group->canManageReleases($viewer) : false;
$canPublishReleases = $viewer ? $group->canPublishReleases($viewer) : false;
$canManageMilestones = $viewer ? $group->canManageMilestones($viewer) : false;
$canViewReputationDashboard = $viewer ? $group->canViewReputationDashboard($viewer) : false;
$canManageBadges = $viewer ? $group->canManageBadges($viewer) : false;
$canViewInternalTrustMetrics = $viewer ? $group->canViewInternalTrustMetrics($viewer) : false;
$canManageChallenges = $viewer ? $group->canManageChallenges($viewer) : false;
$canManageEvents = $viewer ? $group->canManageEvents($viewer) : false;
$canPublishEventUpdates = $viewer ? $group->canPublishEventUpdates($viewer) : false;
$canManageAssets = $viewer ? $group->canManageAssets($viewer) : false;
$canViewInternalAssets = $viewer ? $group->canViewInternalAssets($viewer) : false;
$canPinActivity = $viewer ? $group->canPinActivity($viewer) : false;
$trustSignals = $this->reputation->trustSignals($group);
$badges = $this->reputation->groupBadges($group, 6);
return [
'id' => (int) $group->id,
'entity_type' => 'group',
'name' => (string) $group->name,
'slug' => (string) $group->slug,
'headline' => $group->headline,
'bio_excerpt' => Str::limit((string) ($group->bio ?? ''), 180),
'visibility' => (string) $group->visibility,
'status' => (string) ($group->status ?? Group::LIFECYCLE_ACTIVE),
'membership_policy' => (string) ($group->membership_policy ?? Group::MEMBERSHIP_INVITE_ONLY),
'type' => $group->type,
'is_verified' => (bool) $group->is_verified,
'is_recruiting' => (bool) ($recruitment['is_recruiting'] ?? false),
'recruitment_headline' => $recruitment['headline'] ?? null,
'avatar_url' => $group->avatarUrl(),
'banner_url' => $group->bannerUrl(),
'owner' => [
'id' => (int) ($owner?->id ?? 0),
'name' => $owner?->name,
'username' => $owner?->username,
'avatar_url' => $owner ? AvatarUrl::forUser((int) $owner->id, $owner->profile?->avatar_hash, 72) : null,
'profile_url' => $owner?->username ? route('profile.show', ['username' => strtolower((string) $owner->username)]) : null,
],
'counts' => [
'artworks' => (int) $group->artworks_count,
'collections' => (int) $group->collections_count,
'followers' => (int) $group->followers_count,
'members' => $group->relationLoaded('members')
? (int) $group->members->where('status', Group::STATUS_ACTIVE)->count()
: (int) $group->members()->where('status', Group::STATUS_ACTIVE)->count(),
],
'permissions' => [
'can_manage' => $canManage,
'can_manage_members' => $canManageMembers,
'can_publish_artworks' => $canPublishArtworks,
'can_manage_collections' => $canManageCollections,
'can_request_join' => $canRequestJoin,
'can_review_join_requests' => $canReviewJoinRequests,
'can_submit_artwork_for_review' => $viewer ? $group->canSubmitArtworkForReview($viewer) : false,
'can_review_submissions' => $canReviewSubmissions,
'can_manage_recruitment' => $canManageRecruitment,
'can_manage_posts' => $canManagePosts,
'can_publish_posts' => $canPublishPosts,
'can_pin_posts' => $canPinPosts,
'can_manage_member_permissions' => $canManageMemberPermissions,
'can_manage_projects' => $canManageProjects,
'can_manage_releases' => $canManageReleases,
'can_publish_releases' => $canPublishReleases,
'can_manage_milestones' => $canManageMilestones,
'can_view_reputation_dashboard' => $canViewReputationDashboard,
'can_manage_badges' => $canManageBadges,
'can_view_internal_trust_metrics' => $canViewInternalTrustMetrics,
'can_manage_challenges' => $canManageChallenges,
'can_manage_events' => $canManageEvents,
'can_publish_event_updates' => $canPublishEventUpdates,
'can_manage_assets' => $canManageAssets,
'can_view_internal_assets' => $canViewInternalAssets,
'can_pin_activity' => $canPinActivity,
],
'trust_signals' => $trustSignals,
'badges' => $badges,
'badge_keys' => array_values(array_filter(array_map(
static fn (array $badge): ?string => $badge['key'] ?? null,
$badges,
))),
'viewer' => [
'role' => $viewer ? $group->activeRoleFor($viewer) : null,
'role_label' => $viewer ? Group::displayRole($group->activeRoleFor($viewer)) : null,
'is_following' => $viewer ? $this->follows->isFollowing($group, $viewer) : false,
'permission_overrides' => $viewer ? $group->permissionOverridesFor($viewer) : [],
],
'urls' => [
'public' => $group->publicUrl(),
'studio' => route('studio.groups.show', ['group' => $group]),
'studio_artworks' => route('studio.groups.artworks', ['group' => $group]),
'studio_collections' => route('studio.groups.collections', ['group' => $group]),
'studio_members' => route('studio.groups.members', ['group' => $group]),
'studio_invitations' => $canManageMembers ? route('studio.groups.invitations', ['group' => $group]) : null,
'studio_join_requests' => $canReviewJoinRequests ? route('studio.groups.join-requests', ['group' => $group]) : null,
'studio_review' => $canReviewSubmissions ? route('studio.groups.review', ['group' => $group]) : null,
'studio_recruitment' => $canManageRecruitment ? route('studio.groups.recruitment', ['group' => $group]) : null,
'studio_posts' => $canManagePosts ? route('studio.groups.posts.index', ['group' => $group]) : null,
'studio_projects' => $canManageProjects ? route('studio.groups.projects.index', ['group' => $group]) : null,
'studio_releases' => $canManageReleases ? route('studio.groups.releases.index', ['group' => $group]) : null,
'studio_reputation' => $canViewReputationDashboard ? route('studio.groups.reputation', ['group' => $group]) : null,
'studio_challenges' => $canManageChallenges ? route('studio.groups.challenges.index', ['group' => $group]) : null,
'studio_events' => ($canManageEvents || $canPublishEventUpdates) ? route('studio.groups.events.index', ['group' => $group]) : null,
'studio_assets' => ($canManageAssets || $canViewInternalAssets) ? route('studio.groups.assets.index', ['group' => $group]) : null,
'studio_activity' => route('studio.groups.activity', ['group' => $group]),
'studio_settings' => $canManage ? route('studio.groups.settings', ['group' => $group]) : null,
'upload' => ($canPublishArtworks || ($viewer && $group->canCreateArtworkDrafts($viewer))) ? route('upload', ['group' => $group->slug]) : null,
'collection_create' => $canManageCollections ? route('settings.collections.create', ['group' => $group->slug]) : null,
'follow' => route('groups.follow', ['group' => $group]),
'unfollow' => route('groups.unfollow', ['group' => $group]),
'join_request_store' => $canRequestJoin ? route('groups.join-requests.store', ['group' => $group]) : null,
'join_request_withdraw_pattern' => $viewer ? route('groups.join-requests.destroy', ['group' => $group, 'joinRequest' => '__JOIN_REQUEST__']) : null,
'posts' => route('groups.section', ['group' => $group, 'section' => 'posts']),
'projects' => route('groups.section', ['group' => $group, 'section' => 'projects']),
'releases' => route('groups.section', ['group' => $group, 'section' => 'releases']),
'challenges' => route('groups.section', ['group' => $group, 'section' => 'challenges']),
'events' => route('groups.section', ['group' => $group, 'section' => 'events']),
'activity' => route('groups.section', ['group' => $group, 'section' => 'activity']),
],
'pending_invites_count' => $this->memberships->pendingInviteCount($group),
];
}
}