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

@@ -15,6 +15,12 @@ use App\Mail\EmailChangedSecurityAlertMail;
use App\Mail\EmailChangeVerificationCodeMail;
use App\Models\Artwork;
use App\Models\Country;
use App\Models\Group;
use App\Models\GroupContributorStat;
use App\Models\GroupMember;
use App\Models\GroupProjectMember;
use App\Models\GroupRelease;
use App\Models\GroupReleaseContributor;
use App\Models\ProfileComment;
use App\Models\Story;
use App\Models\User;
@@ -1196,6 +1202,7 @@ class ProfileController extends Controller
->all();
$achievementSummary = $this->achievements->summary((int) $user->id);
$leaderboardRank = $this->leaderboards->creatorRankSummary((int) $user->id);
$groupContributionHistory = $this->buildGroupContributionHistory($user);
$resolvedInitialTab = $this->normalizeProfileTab($initialTab);
$isTabLanding = ! $galleryOnly && $resolvedInitialTab !== null;
$activeProfileUrl = $resolvedInitialTab !== null
@@ -1269,6 +1276,7 @@ class ProfileController extends Controller
'collections' => $profileCollectionsPayload,
'achievements' => $achievementSummary,
'leaderboardRank' => $leaderboardRank,
'groupContributionHistory' => $groupContributionHistory,
'countryName' => $countryName,
'isOwner' => $isOwner,
'auth' => $authData,
@@ -1315,6 +1323,98 @@ class ProfileController extends Controller
return redirect()->to($baseUrl, 301);
}
private function buildGroupContributionHistory(User $user): array
{
return GroupContributorStat::query()
->with(['group.owner.profile'])
->where('user_id', $user->id)
->whereHas('group', fn ($query) => $query
->whereIn('visibility', [Group::VISIBILITY_PUBLIC, Group::VISIBILITY_UNLISTED])
->where('status', '!=', Group::LIFECYCLE_SUSPENDED))
->orderByDesc('release_count')
->orderByDesc('credited_artworks_count')
->limit(8)
->get()
->map(function (GroupContributorStat $stat) use ($user): ?array {
$group = $stat->group;
if (! $group) {
return null;
}
$member = GroupMember::query()
->where('group_id', $group->id)
->where('user_id', $user->id)
->where('status', Group::STATUS_ACTIVE)
->first();
$roleLabels = collect()
->merge(GroupReleaseContributor::query()
->where('user_id', $user->id)
->whereHas('release', fn ($query) => $query->where('group_id', $group->id))
->pluck('role_label'))
->merge(GroupProjectMember::query()
->where('user_id', $user->id)
->whereHas('project', fn ($query) => $query->where('group_id', $group->id))
->pluck('role_label'))
->filter()
->map(fn ($label): string => trim((string) $label))
->filter()
->unique()
->values()
->all();
$recentReleaseTitles = GroupRelease::query()
->where('group_id', $group->id)
->where('visibility', GroupRelease::VISIBILITY_PUBLIC)
->where(function ($query) use ($user): void {
$query->where('lead_user_id', $user->id)
->orWhere('created_by_user_id', $user->id)
->orWhereHas('contributorLinks', fn ($contributorQuery) => $contributorQuery->where('user_id', $user->id));
})
->orderByDesc('released_at')
->latest('updated_at')
->limit(3)
->pluck('title')
->map(fn ($title): string => (string) $title)
->values()
->all();
$joinedAt = $group->isOwnedBy($user)
? $group->created_at?->toISOString()
: ($member?->accepted_at?->toISOString() ?? $member?->created_at?->toISOString());
$meta = is_array($stat->reputation_meta_json) ? $stat->reputation_meta_json : [];
return [
'group' => [
'id' => (int) $group->id,
'name' => (string) $group->name,
'slug' => (string) $group->slug,
'headline' => $group->headline,
'avatar_url' => $group->avatarUrl(),
'profile_url' => $group->publicUrl(),
],
'joined_at' => $joinedAt,
'role' => $group->isOwnedBy($user)
? Group::ROLE_OWNER
: Group::displayRole($member?->role ?? Group::ROLE_MEMBER),
'counts' => [
'credited_artworks' => (int) $stat->credited_artworks_count,
'releases' => (int) $stat->release_count,
'projects' => (int) $stat->project_count,
'review_actions' => (int) $stat->review_actions_count,
],
'trusted_indicator' => (bool) ($meta['trusted_indicator'] ?? false),
'summary' => $meta['summary'] ?? null,
'role_labels' => $roleLabels,
'recent_release_titles' => $recentReleaseTitles,
];
})
->filter()
->values()
->all();
}
private function resolveFavouriteTable(): ?string
{
foreach (['artwork_favourites', 'user_favorites', 'artworks_favourites', 'favourites'] as $table) {