diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 80f9a08..6433105 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -13,10 +13,14 @@ class UserController extends Controller public function show(Request $request, int $userId, string $username): View { - $user = User::where('id', $userId) - // Reimplement eager loading after the review. + $user = User::whereId($userId) ->firstOrFail(); + $mods = $user->mods() + ->orderByDesc('created_at') + ->paginate(10) + ->fragment('mods'); + if ($user->slug() !== $username) { abort(404); } @@ -25,6 +29,6 @@ class UserController extends Controller abort(403); } - return view('user.show', compact('user')); + return view('user.show', compact('user', 'mods')); } } diff --git a/app/Livewire/User/FollowButtons.php b/app/Livewire/User/FollowButtons.php new file mode 100644 index 0000000..6b591d2 --- /dev/null +++ b/app/Livewire/User/FollowButtons.php @@ -0,0 +1,52 @@ +user()->follow($this->profileUserId); + $this->isFollowing = true; + + $this->dispatch('user-follow-change'); + } + + /** + * Action to unfollow a user. + */ + public function unfollow(): void + { + auth()->user()->unfollow($this->profileUserId); + $this->isFollowing = false; + + $this->dispatch('user-follow-change'); + } + + /** + * Render the component. + */ + public function render(): View + { + return view('livewire.user.follow-buttons'); + } +} diff --git a/app/Livewire/User/FollowCard.php b/app/Livewire/User/FollowCard.php new file mode 100644 index 0000000..c62b53f --- /dev/null +++ b/app/Livewire/User/FollowCard.php @@ -0,0 +1,152 @@ + + */ + #[Locked] + public Collection $followUsers; + + /** + * The maximum number of users to display on the card. + */ + #[Locked] + public int $limit = 5; + + /** + * Whether to show all users in a model dialog. + */ + public bool $showFollowDialog = false; + + /** + * The user whose profile is being viewed. + */ + #[Locked] + public User $profileUser; + + /** + * Called when the component is initialized. + */ + public function mount(): void + { + $this->profileUser = User::select(['id', 'name', 'profile_photo_path', 'cover_photo_path']) + ->findOrFail($this->profileUserId); + + $this->setTitle(); + $this->setEmptyMessage(); + $this->setDialogTitle(); + } + + /** + * Set the title of the card based on the relationship. + */ + private function setTitle(): void + { + $this->title = match ($this->relationship) { + 'followers' => __('Followers'), + 'following' => __('Following'), + default => __('Users'), + }; + } + + /** + * Set the empty message based on the relationship. + */ + private function setEmptyMessage(): void + { + $this->emptyMessage = match ($this->relationship) { + 'followers' => __('No followers yet.'), + 'following' => __('Not yet following anyone.'), + default => __('No users found.'), + }; + } + + /** + * Set the dialog title based on the relationship. + */ + private function setDialogTitle(): void + { + $this->dialogTitle = match ($this->relationship) { + 'followers' => 'User :name has these followers:', + 'following' => 'User :name is following:', + default => 'Users:', + }; + } + + /** + * Render the component. + */ + public function render(): View + { + $this->populateFollowUsers(); + + return view('livewire.user.follow-card'); + } + + /** + * Called when the user follows or unfollows a user. + */ + #[On('user-follow-change')] + public function populateFollowUsers(): void + { + // Fetch IDs of all users the authenticated user is following. + $followingIds = auth()->user()->following()->pluck('following_id'); + + // Load the profile user's followers (or following) and map the follow status. + $this->followUsers = $this->profileUser->{$this->relationship} + ->map(function (User $user) use ($followingIds) { + // Add the follow status based on the preloaded IDs. + $user->follows = $followingIds->contains($user->id); + + return $user; + }); + } + + /** + * Toggle showing the follow dialog. + */ + public function toggleFollowDialog(): void + { + $this->showFollowDialog = ! $this->showFollowDialog; + } +} diff --git a/app/Livewire/User/Profile.php b/app/Livewire/User/Profile.php deleted file mode 100644 index f6336db..0000000 --- a/app/Livewire/User/Profile.php +++ /dev/null @@ -1,54 +0,0 @@ - 'render']; - - public function render() - { - $this->followers = $this->user->followers; - $this->following = $this->user->following; - - $mods = $this->user->mods()->withWhereHas('latestVersion')->paginate(6); - - return view('livewire.user.profile', compact('mods')); - } - - public function setSection(string $name) - { - $this->section = $name; - } - - public function message() - { - // todo: not implemented yet - } - - public function followUser(User $user) - { - auth()->user()->follow($user); - } - - public function unfollowUser(User $user) - { - auth()->user()->unfollow($user); - } -} diff --git a/app/Livewire/UserStack.php b/app/Livewire/UserStack.php deleted file mode 100644 index 874fff1..0000000 --- a/app/Livewire/UserStack.php +++ /dev/null @@ -1,61 +0,0 @@ -authFollowingIds = Auth::user()->following()->pluck('following_id')->toArray(); - } - - return view('livewire.user-stack'); - } - - public function toggleViewAll() - { - $this->viewAll = ! $this->viewAll; - } - - public function closeDialog() - { - if ($this->refreshNeeded) { - $this->dispatch('refreshNeeded'); - } - - $this->toggleViewAll(); - } - - public function followUser(User $user) - { - Auth::user()->follow($user); - $this->refreshNeeded = true; - } - - public function unfollowUser(User $user) - { - Auth::user()->unfollow($user); - $this->refreshNeeded = true; - } -} diff --git a/resources/views/components/mod-card.blade.php b/resources/views/components/mod-card.blade.php index 3aff1ef..45e271d 100644 --- a/resources/views/components/mod-card.blade.php +++ b/resources/views/components/mod-card.blade.php @@ -7,20 +7,21 @@
{{ __('By :authors', ['authors' => $mod->users->pluck('name')->implode(', ')]) }} @@ -31,7 +32,7 @@