From 0baa87e3736722b4ae2bbc6eac484f7510ef0847 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sun, 4 Jan 2026 15:54:31 +0100 Subject: [PATCH] bug - 14 - Add user multi-select --- app/Livewire/Dishes/DishesList.php | 10 ++ app/Livewire/Schedule/ScheduleCalendar.php | 131 +++++++++++------- .../components/user-multi-select.blade.php | 36 +++++ .../livewire/dishes/dishes-list.blade.php | 68 +++------ .../schedule/schedule-calendar.blade.php | 59 +++----- 5 files changed, 172 insertions(+), 132 deletions(-) create mode 100644 resources/views/components/user-multi-select.blade.php diff --git a/app/Livewire/Dishes/DishesList.php b/app/Livewire/Dishes/DishesList.php index 392ff2a..ffe8049 100644 --- a/app/Livewire/Dishes/DishesList.php +++ b/app/Livewire/Dishes/DishesList.php @@ -119,4 +119,14 @@ public function cancel() $this->showDeleteModal = false; $this->reset(['name', 'selectedUsers', 'editingDish', 'deletingDish']); } + + public function toggleAllUsers(): void + { + $users = User::where('planner_id', auth()->id())->get(); + if (count($this->selectedUsers) === $users->count()) { + $this->selectedUsers = []; + } else { + $this->selectedUsers = $users->pluck('id')->map(fn($id) => (string) $id)->toArray(); + } + } } \ No newline at end of file diff --git a/app/Livewire/Schedule/ScheduleCalendar.php b/app/Livewire/Schedule/ScheduleCalendar.php index 0ba2b73..9d2a911 100644 --- a/app/Livewire/Schedule/ScheduleCalendar.php +++ b/app/Livewire/Schedule/ScheduleCalendar.php @@ -35,7 +35,7 @@ class ScheduleCalendar extends Component // Add dish modal public $showAddDishModal = false; public $addDate = null; - public $addUserId = null; + public $addUserIds = []; public $addSelectedDishId = null; public $addAvailableUsers = []; public $addAvailableDishes = []; @@ -170,7 +170,7 @@ public function cancel(): void $this->availableDishes = []; $this->showAddDishModal = false; $this->addDate = null; - $this->addUserId = null; + $this->addUserIds = []; $this->addSelectedDishId = null; $this->addAvailableUsers = []; $this->addAvailableDishes = []; @@ -212,21 +212,37 @@ public function openAddDishModal($date): void ->get(); $this->addAvailableDishes = []; - $this->addUserId = null; + $this->addUserIds = []; $this->addSelectedDishId = null; $this->showAddDishModal = true; } - public function updatedAddUserId($value): void + public function toggleAllUsers(): void { - if ($value) { - // Load dishes available for selected user - $this->addAvailableDishes = Dish::whereHas('users', function ($query) use ($value) { - $query->where('users.id', $value); - })->orderBy('name')->get(); + if (count($this->addUserIds) === count($this->addAvailableUsers)) { + $this->addUserIds = []; } else { + $this->addUserIds = $this->addAvailableUsers->pluck('id')->map(fn($id) => (string) $id)->toArray(); + } + $this->updateAvailableDishes(); + } + + public function updatedAddUserIds(): void + { + $this->updateAvailableDishes(); + } + + private function updateAvailableDishes(): void + { + if (empty($this->addUserIds)) { $this->addAvailableDishes = []; + } else { + // Load dishes that ALL selected users have in common + $selectedCount = count($this->addUserIds); + $this->addAvailableDishes = Dish::whereHas('users', function ($query) { + $query->whereIn('users.id', $this->addUserIds); + }, '=', $selectedCount)->orderBy('name')->get(); } $this->addSelectedDishId = null; } @@ -234,13 +250,8 @@ public function updatedAddUserId($value): void public function saveAddDish(): void { try { - if (!$this->addUserId) { - session()->flash('error', 'Please select a user.'); - return; - } - - if (!$this->authorizeUser($this->addUserId)) { - session()->flash('error', 'Unauthorized action.'); + if (empty($this->addUserIds)) { + session()->flash('error', 'Please select at least one user.'); return; } @@ -258,49 +269,71 @@ public function saveAddDish(): void ['is_skipped' => false] ); - // Check if user already has a dish scheduled for this date - $existing = ScheduledUserDish::where('schedule_id', $schedule->id) - ->where('user_id', $this->addUserId) - ->first(); + $addedCount = 0; + $skippedCount = 0; - if ($existing) { - session()->flash('error', 'This user already has a dish scheduled for this date. Use Edit instead.'); - return; + foreach ($this->addUserIds as $userId) { + if (!$this->authorizeUser((int) $userId)) { + $skippedCount++; + continue; + } + + // Check if user already has a dish scheduled for this date + $existing = ScheduledUserDish::where('schedule_id', $schedule->id) + ->where('user_id', $userId) + ->first(); + + if ($existing) { + $skippedCount++; + continue; + } + + // Find the UserDish for this user and dish + $userDish = UserDish::where('user_id', $userId) + ->where('dish_id', $this->addSelectedDishId) + ->first(); + + if (!$userDish) { + $skippedCount++; + continue; + } + + // Create the scheduled user dish + ScheduledUserDish::create([ + 'schedule_id' => $schedule->id, + 'user_id' => $userId, + 'user_dish_id' => $userDish->id, + 'is_skipped' => false, + ]); + $addedCount++; } - // Find the UserDish for this user and dish - $userDish = UserDish::where('user_id', $this->addUserId) - ->where('dish_id', $this->addSelectedDishId) - ->first(); - - if (!$userDish) { - session()->flash('error', 'This dish is not assigned to this user.'); - return; - } - - // Create the scheduled user dish - ScheduledUserDish::create([ - 'schedule_id' => $schedule->id, - 'user_id' => $this->addUserId, - 'user_dish_id' => $userDish->id, - 'is_skipped' => false, - ]); - - $this->showAddDishModal = false; - $this->addDate = null; - $this->addUserId = null; - $this->addSelectedDishId = null; - $this->addAvailableUsers = []; - $this->addAvailableDishes = []; - + $this->closeAddDishModal(); $this->loadCalendar(); - session()->flash('success', 'Dish added successfully!'); + + if ($addedCount > 0 && $skippedCount > 0) { + session()->flash('success', "Dish added for {$addedCount} user(s). {$skippedCount} user(s) skipped (already scheduled)."); + } elseif ($addedCount > 0) { + session()->flash('success', "Dish added for {$addedCount} user(s)!"); + } else { + session()->flash('error', 'No users could be scheduled. They may already have dishes for this date.'); + } } catch (Exception $e) { Log::error('Add dish failed', ['exception' => $e]); session()->flash('error', 'Unable to add dish. Please try again.'); } } + private function closeAddDishModal(): void + { + $this->showAddDishModal = false; + $this->addDate = null; + $this->addUserIds = []; + $this->addSelectedDishId = null; + $this->addAvailableUsers = []; + $this->addAvailableDishes = []; + } + public function editDish($date, $userId): void { if (!$this->authorizeUser($userId)) { diff --git a/resources/views/components/user-multi-select.blade.php b/resources/views/components/user-multi-select.blade.php new file mode 100644 index 0000000..0429e73 --- /dev/null +++ b/resources/views/components/user-multi-select.blade.php @@ -0,0 +1,36 @@ +@props([ + 'users', + 'selectedIds' => [], + 'wireModel' => null, + 'toggleAllMethod' => null, + 'label' => 'Users', +]) + +
+ +
+ @if($toggleAllMethod) + + +
+ @endif + + @forelse($users as $user) + + @empty +

No users available.

+ @endforelse +
+
\ No newline at end of file diff --git a/resources/views/livewire/dishes/dishes-list.blade.php b/resources/views/livewire/dishes/dishes-list.blade.php index 559a508..0157fbb 100644 --- a/resources/views/livewire/dishes/dishes-list.blade.php +++ b/resources/views/livewire/dishes/dishes-list.blade.php @@ -84,26 +84,14 @@ class="w-full p-2 border rounded bg-gray-600 border-secondary text-gray-100 focu @if($users->count() > 0) -
- -
- @foreach($users as $user) - - @endforeach -
- @error('selectedUsers') {{ $message }} @enderror -
+ + @error('selectedUsers') {{ $message }} @enderror @else

No users available to assign. Add users to assign them to dishes.

@@ -111,12 +99,12 @@ class="rounded border-secondary bg-gray-600 text-primary focus:ring-accent-blue @endif
- - @@ -142,26 +130,14 @@ class="w-full p-2 border rounded bg-gray-600 border-secondary text-gray-100 focu
@if($users->count() > 0) -
- -
- @foreach($users as $user) - - @endforeach -
- @error('selectedUsers') {{ $message }} @enderror -
+ + @error('selectedUsers') {{ $message }} @enderror @else

No users available to assign. Add users to assign them to dishes.

@@ -169,12 +145,12 @@ class="rounded border-secondary bg-gray-600 text-primary focus:ring-accent-blue @endif
- - diff --git a/resources/views/livewire/schedule/schedule-calendar.blade.php b/resources/views/livewire/schedule/schedule-calendar.blade.php index eed6ec7..83fad1f 100644 --- a/resources/views/livewire/schedule/schedule-calendar.blade.php +++ b/resources/views/livewire/schedule/schedule-calendar.blade.php @@ -266,45 +266,30 @@ class="px-4 py-2 bg-primary text-white rounded hover:bg-secondary transition-col Add a dish for {{ \Carbon\Carbon::parse($addDate)->format('M j, Y') }}

- @if(count($addAvailableUsers) > 0) - -
- - -
+ - - @if($addUserId) -
- - @if(count($addAvailableDishes) > 0) - - @else -

- No dishes available for this user. - Add dishes first. -

- @endif -
- @endif - @else + @if(count($addUserIds) > 0)
-

- No users available. - Add users first. -

+ + @if(count($addAvailableDishes) > 0) + + @else +

+ No dishes in common for selected users. + Add dishes first. +

+ @endif
@endif