From d5a5dff21d627fc0bd5e026dadbfe75059aa34dd Mon Sep 17 00:00:00 2001 From: Matt Young Date: Thu, 31 Oct 2024 22:40:16 -0500 Subject: [PATCH] Monitors are able to flag entries as no-shows or failed-prelims Closes #45 --- app/Enums/UserFlags.php | 1 + .../Admin/AssignMonitorsController.php | 32 ++++++ app/Http/Controllers/MonitorController.php | 98 +++++++++++++++++++ app/Models/User.php | 1 + .../views/admin/assign_monitors.blade.php | 18 ++++ .../layout/navbar/menus/setup.blade.php | 1 + .../components/layout/navbar/navbar.blade.php | 8 ++ .../views/monitor_entry_flag_form.blade.php | 37 +++++++ routes/admin.php | 10 +- routes/web.php | 8 ++ 10 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Admin/AssignMonitorsController.php create mode 100644 app/Http/Controllers/MonitorController.php create mode 100644 resources/views/admin/assign_monitors.blade.php create mode 100644 resources/views/monitor_entry_flag_form.blade.php diff --git a/app/Enums/UserFlags.php b/app/Enums/UserFlags.php index aa174d4..f85902b 100644 --- a/app/Enums/UserFlags.php +++ b/app/Enums/UserFlags.php @@ -5,4 +5,5 @@ namespace App\Enums; enum UserFlags: string { case HEAD_DIRECTOR = 'head_director'; + case MONITOR = 'monitor'; } diff --git a/app/Http/Controllers/Admin/AssignMonitorsController.php b/app/Http/Controllers/Admin/AssignMonitorsController.php new file mode 100644 index 0000000..66f5490 --- /dev/null +++ b/app/Http/Controllers/Admin/AssignMonitorsController.php @@ -0,0 +1,32 @@ +orderBy('first_name')->get(); + + return view('admin.assign_monitors', compact('users')); + } + + public function store() + { + $submittedUsers = request()->input('user'); + $monitorUsers = array_keys($submittedUsers); + $users = User::all(); + foreach ($users as $user) { + if (in_array($user->id, $monitorUsers)) { + $user->addFlag('monitor'); + } else { + $user->removeFlag('monitor'); + } + } + + return redirect(route('admin.assign_monitors.index'))->with('success', 'Monitors assigned'); + } +} diff --git a/app/Http/Controllers/MonitorController.php b/app/Http/Controllers/MonitorController.php new file mode 100644 index 0000000..b57a98a --- /dev/null +++ b/app/Http/Controllers/MonitorController.php @@ -0,0 +1,98 @@ +user()->hasFlag('monitor')) { + return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + } + $method = 'GET'; + $formRoute = 'monitor.enterFlag'; + $title = 'Flag Entry'; + + return view('tabulation.choose_entry', compact('method', 'formRoute', 'title')); + + } + + public function flagForm() + { + if (! auth()->user()->hasFlag('monitor')) { + return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + } + $validData = request()->validate([ + 'entry_id' => ['required', 'integer', 'exists:entries,id'], + ]); + $entry = Entry::find($validData['entry_id']); + + // If the entries audition is published, bounce out + if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advance_published')) { + return redirect()->route('monitor.index')->with('error', 'Cannot set flags while results are published'); + } + + // If entry has scores, bounce on out + if ($entry->scoreSheets()->count() > 0) { + return redirect()->route('monitor.index')->with('error', 'That entry has existing scores'); + } + + return view('monitor_entry_flag_form', compact('entry')); + } + + public function storeFlag(Entry $entry) + { + if (! auth()->user()->hasFlag('monitor')) { + return redirect()->route('dashboard')->with('error', 'You are not assigned as a monitor'); + } + + // If the entries audition is published, bounce out + if ($entry->audition->hasFlag('seats_published') || $entry->audition->hasFlag('advance_published')) { + return redirect()->route('monitor.index')->with('error', 'Cannot set flags while results are published'); + } + + // If entry has scores, bounce on out + if ($entry->scoreSheets()->count() > 0) { + return redirect()->route('monitor.index')->with('error', 'That entry has existing scores'); + } + + $action = request()->input('action'); + $result = match ($action) { + 'failed-prelim' => $this->setFlag($entry, 'failed_prelim'), + 'no-show' => $this->setFlag($entry, 'no_show'), + 'clear' => $this->setFlag($entry, 'clear'), + default => redirect()->route('monitor.index')->with('error', 'Invalid action requested'), + }; + if (! $result) { + return redirect()->route('monitor.index')->with('error', 'Failed to set flag'); + } + + return redirect()->route('monitor.index')->with('success', 'Flag set for entry #'.$entry->id); + } + + private function setFlag(Entry $entry, string $flag) + { + if ($flag === 'no_show') { + $entry->removeFlag('failed_prelim'); + $entry->addFlag('no_show'); + + return true; + } + if ($flag === 'failed_prelim') { + $entry->addFlag('failed_prelim'); + $entry->addFlag('no_show'); + + return true; + } + if ($flag === 'clear') { + $entry->removeFlag('failed_prelim'); + $entry->removeFlag('no_show'); + + return true; + } + + return false; + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 21b0722..1c6907b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -182,6 +182,7 @@ class User extends Authenticatable implements MustVerifyEmail } $enum = match ($flag) { 'head_director' => UserFlags::HEAD_DIRECTOR, + 'monitor' => UserFlags::MONITOR, }; $this->flags()->create(['flag_name' => $enum]); $this->load('flags'); diff --git a/resources/views/admin/assign_monitors.blade.php b/resources/views/admin/assign_monitors.blade.php new file mode 100644 index 0000000..771f8ac --- /dev/null +++ b/resources/views/admin/assign_monitors.blade.php @@ -0,0 +1,18 @@ + + Assign Room Monitors + + Users With Monitor Access + + + @foreach($users as $user) + + + {{$user->full_name(true)}} + + + @endforeach + + Submit Monitors + + + diff --git a/resources/views/components/layout/navbar/menus/setup.blade.php b/resources/views/components/layout/navbar/menus/setup.blade.php index 85e884b..892a9d2 100644 --- a/resources/views/components/layout/navbar/menus/setup.blade.php +++ b/resources/views/components/layout/navbar/menus/setup.blade.php @@ -29,6 +29,7 @@ Bonus Scores Rooms Judges + Room Monitors Run Draw Print Cards Print Sign-In Sheets diff --git a/resources/views/components/layout/navbar/navbar.blade.php b/resources/views/components/layout/navbar/navbar.blade.php index 102fb11..43578a6 100644 --- a/resources/views/components/layout/navbar/navbar.blade.php +++ b/resources/views/components/layout/navbar/navbar.blade.php @@ -27,6 +27,10 @@ Judging @endif + @if(Auth::user()->hasFlag('monitor') && Settings::get('judging_enabled')) + Monitor + + @endif @if(Auth::user()->is_admin) @include('components.layout.navbar.menus.admin') @include('components.layout.navbar.menus.setup') @@ -169,6 +173,10 @@ Judging @endif + @if(Auth::user()->hasFlag('monitor') AND Settings::get('judging_enabled')) + Monitor + + @endif @if(Auth::user()->is_admin) @include('components.layout.navbar.menus.admin') @include('components.layout.navbar.menus.setup') diff --git a/resources/views/monitor_entry_flag_form.blade.php b/resources/views/monitor_entry_flag_form.blade.php new file mode 100644 index 0000000..460c775 --- /dev/null +++ b/resources/views/monitor_entry_flag_form.blade.php @@ -0,0 +1,37 @@ + + Entry Status + + Entry #{{$entry->id}} + + Audition{{$entry->audition->name}} + #{{$entry->draw_number}} + Name{{$entry->student->full_name() }} + School{{$entry->student->school->name }} + + Current Status + @if($entry->hasFlag('failed_prelim')) + Failed Prelim + @elseif($entry->hasFlag('no_show')) + No-Show + @else + No Flags + @endif + + + +
+ + @if(! $entry->hasFlag('failed_prelim')) + Failed Prelim + @endif + @if(! $entry->hasFlag('no_show') || $entry->hasFlag('failed_prelim')) + No-Show + @endif + @if($entry->hasFlag('no_show') || $entry->hasFlag('failed_prelim')) + Clear Status + @endif + +
+
+
+
diff --git a/routes/admin.php b/routes/admin.php index 0ab9b6c..fdbd25c 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -1,6 +1,7 @@ prefix('admin/')-> Route::post('/settings', [AuditionSettings::class, 'save'])->name('audition-settings-save'); + // Admin Assign Monitors Routes + Route::prefix('assign_monitors')->controller(AssignMonitorsController::class)->group(function () { + Route::get('/', 'index')->name('admin.assign_monitors.index'); + Route::post('/', 'store')->name('admin.assign_monitors.store'); + }); + // Admin Bonus Scores Routes Route::prefix('bonus-scores')->controller(BonusScoreDefinitionController::class)->group(function () { Route::get('/', 'index')->name('admin.bonus-scores.index'); @@ -180,5 +187,6 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')-> }); // Print Room and Judge Assignment Report - Route::get('room_assignment_report', PrintRoomAssignmentsController::class)->name('admin.print_room_assignment_report'); + Route::get('room_assignment_report', + PrintRoomAssignmentsController::class)->name('admin.print_room_assignment_report'); }); diff --git a/routes/web.php b/routes/web.php index b181fb1..a215e8e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,7 @@ middleware(['auth', 'verified'])->controller(FilterCon Route::get('/admin_student_filter/clear', 'clearAdminStudentFilter')->name('admin.students.filter.clear'); }); +// Monitor Related Routes +Route::prefix('monitor')->middleware(['auth', 'verified'])->controller(MonitorController::class)->group(function () { + Route::get('/', 'index')->name('monitor.index'); + Route::get('/enter_flag', 'flagForm')->name('monitor.enterFlag'); + Route::post('enter_flag/{entry}', 'storeFlag')->name('monitor.storeFlag'); +}); + //Route::get('/my_school', [SchoolController::class, 'my_school'])->middleware('auth','verified'); //Route::get('/schools/create', [SchoolController::class, 'create'])->middleware('auth','verified'); //Route::post('/schools', [SchoolController::class, 'store'])->middleware('auth','verified');