diff --git a/app/Livewire/Schedule/ScheduleCalendar.php b/app/Livewire/Schedule/ScheduleCalendar.php index c54c1c9..0ba2b73 100644 --- a/app/Livewire/Schedule/ScheduleCalendar.php +++ b/app/Livewire/Schedule/ScheduleCalendar.php @@ -2,7 +2,11 @@ namespace App\Livewire\Schedule; +use App\Models\Dish; +use App\Models\Schedule; +use App\Models\ScheduledUserDish; use App\Models\User; +use App\Models\UserDish; use Carbon\Carbon; use DishPlanner\Schedule\Services\ScheduleCalendarService; use DishPlanner\ScheduledUserDish\Actions\DeleteScheduledUserDishForDateAction; @@ -21,6 +25,21 @@ class ScheduleCalendar extends Component public $regenerateDate = null; public $regenerateUserId = null; + // Edit dish modal + public $showEditDishModal = false; + public $editDate = null; + public $editUserId = null; + public $selectedDishId = null; + public $availableDishes = []; + + // Add dish modal + public $showAddDishModal = false; + public $addDate = null; + public $addUserId = null; + public $addSelectedDishId = null; + public $addAvailableUsers = []; + public $addAvailableDishes = []; + public function mount(): void { $this->currentMonth = now()->month; @@ -144,6 +163,233 @@ public function cancel(): void $this->showRegenerateModal = false; $this->regenerateDate = null; $this->regenerateUserId = null; + $this->showEditDishModal = false; + $this->editDate = null; + $this->editUserId = null; + $this->selectedDishId = null; + $this->availableDishes = []; + $this->showAddDishModal = false; + $this->addDate = null; + $this->addUserId = null; + $this->addSelectedDishId = null; + $this->addAvailableUsers = []; + $this->addAvailableDishes = []; + } + + public function removeDish($date, $userId): void + { + try { + if (!$this->authorizeUser($userId)) { + session()->flash('error', 'Unauthorized action.'); + return; + } + + $schedule = Schedule::where('planner_id', auth()->id()) + ->where('date', $date) + ->first(); + + if ($schedule) { + ScheduledUserDish::where('schedule_id', $schedule->id) + ->where('user_id', $userId) + ->delete(); + } + + $this->loadCalendar(); + session()->flash('success', 'Dish removed successfully!'); + } catch (Exception $e) { + Log::error('Remove dish failed', ['exception' => $e, 'date' => $date, 'userId' => $userId]); + session()->flash('error', 'Unable to remove dish. Please try again.'); + } + } + + public function openAddDishModal($date): void + { + $this->addDate = $date; + + // Load all users for this planner + $this->addAvailableUsers = User::where('planner_id', auth()->id()) + ->orderBy('name') + ->get(); + + $this->addAvailableDishes = []; + $this->addUserId = null; + $this->addSelectedDishId = null; + + $this->showAddDishModal = true; + } + + public function updatedAddUserId($value): 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(); + } else { + $this->addAvailableDishes = []; + } + $this->addSelectedDishId = null; + } + + 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.'); + return; + } + + if (!$this->addSelectedDishId) { + session()->flash('error', 'Please select a dish.'); + return; + } + + // Find or create the schedule for this date + $schedule = Schedule::firstOrCreate( + [ + 'planner_id' => auth()->id(), + 'date' => $this->addDate, + ], + ['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(); + + if ($existing) { + session()->flash('error', 'This user already has a dish scheduled for this date. Use Edit instead.'); + return; + } + + // 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->loadCalendar(); + session()->flash('success', 'Dish added successfully!'); + } catch (Exception $e) { + Log::error('Add dish failed', ['exception' => $e]); + session()->flash('error', 'Unable to add dish. Please try again.'); + } + } + + public function editDish($date, $userId): void + { + if (!$this->authorizeUser($userId)) { + session()->flash('error', 'Unauthorized action.'); + return; + } + + $this->editDate = $date; + $this->editUserId = $userId; + + // Load dishes available for this user (via UserDish pivot) + $this->availableDishes = Dish::whereHas('users', function ($query) use ($userId) { + $query->where('users.id', $userId); + })->orderBy('name')->get(); + + // Get currently selected dish for this date/user if exists + $schedule = Schedule::where('planner_id', auth()->id()) + ->where('date', $date) + ->first(); + + if ($schedule) { + $scheduledUserDish = ScheduledUserDish::where('schedule_id', $schedule->id) + ->where('user_id', $userId) + ->first(); + + if ($scheduledUserDish && $scheduledUserDish->userDish) { + $this->selectedDishId = $scheduledUserDish->userDish->dish_id; + } + } + + $this->showEditDishModal = true; + } + + public function saveDish(): void + { + try { + if (!$this->authorizeUser($this->editUserId)) { + session()->flash('error', 'Unauthorized action.'); + return; + } + + if (!$this->selectedDishId) { + session()->flash('error', 'Please select a dish.'); + return; + } + + // Find or create the schedule for this date + $schedule = Schedule::firstOrCreate( + [ + 'planner_id' => auth()->id(), + 'date' => $this->editDate, + ], + ['is_skipped' => false] + ); + + // Find the UserDish for this user and dish + $userDish = UserDish::where('user_id', $this->editUserId) + ->where('dish_id', $this->selectedDishId) + ->first(); + + if (!$userDish) { + session()->flash('error', 'This dish is not assigned to this user.'); + return; + } + + // Update or create the scheduled user dish + ScheduledUserDish::updateOrCreate( + [ + 'schedule_id' => $schedule->id, + 'user_id' => $this->editUserId, + ], + [ + 'user_dish_id' => $userDish->id, + 'is_skipped' => false, + ] + ); + + $this->showEditDishModal = false; + $this->editDate = null; + $this->editUserId = null; + $this->selectedDishId = null; + $this->availableDishes = []; + + $this->loadCalendar(); + session()->flash('success', 'Dish updated successfully!'); + } catch (Exception $e) { + Log::error('Save dish failed', ['exception' => $e]); + session()->flash('error', 'Unable to save dish. Please try again.'); + } } public function getMonthNameProperty(): string diff --git a/database/migrations/2025_02_08_231219_create_schedules_table.php b/database/migrations/2025_02_08_231219_create_schedules_table.php index 98dbb15..8f304b4 100755 --- a/database/migrations/2025_02_08_231219_create_schedules_table.php +++ b/database/migrations/2025_02_08_231219_create_schedules_table.php @@ -29,7 +29,7 @@ public function up(): void $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->foreign('user_dish_id')->references('id')->on('user_dishes')->onDelete('cascade'); - $table->unique(['schedule_id', 'user_dish_id']); + $table->unique(['schedule_id', 'user_id']); $table->index('user_dish_id'); }); } diff --git a/resources/views/livewire/schedule/schedule-calendar.blade.php b/resources/views/livewire/schedule/schedule-calendar.blade.php index ee91eb4..eed6ec7 100644 --- a/resources/views/livewire/schedule/schedule-calendar.blade.php +++ b/resources/views/livewire/schedule/schedule-calendar.blade.php @@ -48,9 +48,15 @@ class="px-4 py-2 bg-gray-700 text-accent-blue rounded hover:bg-gray-600 transiti {{ $dayData['isToday'] ? 'border-2 border-accent-blue' : 'border-gray-600' }}"> @if($dayData['day']) - -
This will clear the selected day and allow for regeneration. Continue?
- ++ Choose a dish for {{ \App\Models\User::find($editUserId)?->name }} on {{ \Carbon\Carbon::parse($editDate)->format('M j, Y') }} +
+ + @if(count($availableDishes) > 0) ++ No dishes available for this user. + Add dishes first. +
++ Add a dish for {{ \Carbon\Carbon::parse($addDate)->format('M j, Y') }} +
+ + @if(count($addAvailableUsers) > 0) + ++ No dishes available for this user. + Add dishes first. +
+ @endif ++ No users available. + Add users first. +
+