From 3315efc83b7444fa64ece53c8e161e1128c924be Mon Sep 17 00:00:00 2001 From: Matt Young Date: Mon, 27 Oct 2025 17:31:18 -0500 Subject: [PATCH] Allow bulk updating of auditions Closes #31 --- .../Controllers/Admin/AuditionController.php | 53 ++++++++ app/Http/Requests/BulkAuditionEditRequest.php | 74 ++++++++++++ .../admin/auditions/bulk_edit_form.blade.php | 114 ++++++++++++++++++ .../views/admin/auditions/index.blade.php | 2 +- .../views/components/form/checkbox.blade.php | 8 +- .../views/components/layout/app.blade.php | 2 +- routes/admin.php | 2 + 7 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 app/Http/Requests/BulkAuditionEditRequest.php create mode 100644 resources/views/admin/auditions/bulk_edit_form.blade.php diff --git a/app/Http/Controllers/Admin/AuditionController.php b/app/Http/Controllers/Admin/AuditionController.php index 67d8107..832270a 100644 --- a/app/Http/Controllers/Admin/AuditionController.php +++ b/app/Http/Controllers/Admin/AuditionController.php @@ -4,12 +4,14 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Http\Requests\AuditionStoreOrUpdateRequest; +use App\Http\Requests\BulkAuditionEditRequest; use App\Models\Audition; use App\Models\Event; use App\Models\Room; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use function compact; use function redirect; use function request; use function response; @@ -84,6 +86,57 @@ class AuditionController extends Controller return to_route('admin.auditions.index')->with('success', 'Audition updated successfully'); } + public function bulkEditForm() + { + $auditions = Audition::with(['event'])->withCount('entries')->orderBy('score_order')->orderBy('created_at', + 'desc')->get()->groupBy('event_id'); + $events = Event::orderBy('name')->get(); + + return view('admin.auditions.bulk_edit_form', compact('auditions', 'events')); + + } + + public function bulkUpdate(BulkAuditionEditRequest $request) + { + $validated = collect($request->validated()); + + $auditions = Audition::whereIn('id', $validated['auditions'])->get(); + foreach ($auditions as $audition) { + if ($validated->has('event_id')) { + $audition->event_id = $validated['event_id']; + } + if ($validated->has('entry_deadline')) { + $audition->entry_deadline = $validated['entry_deadline']; + } + if ($validated->has('entry_fee')) { + + $audition->entry_fee = $validated['entry_fee']; + } + if ($validated->has('minimum_grade')) { + $originalMinimumGrade = $audition->minimum_grade; + $audition->minimum_grade = $validated['minimum_grade']; + } + if ($validated->has('maximum_grade')) { + $originalMaximumGrade = $audition->maximum_grade; + $audition->maximum_grade = $validated['maximum_grade']; + } + if ($validated->has('for_seating')) { + $audition->for_seating = $validated['for_seating']; + } + if ($validated->has('for_advancement')) { + $audition->for_advancement = $validated['for_advancement']; + } + + if ($audition->minimum_grade > $audition->maximum_grade) { + $audition->minimum_grade = $originalMinimumGrade; + $audition->maximum_grade = $originalMaximumGrade; + } + $audition->save(); + } + + return to_route('admin.auditions.index')->with('success', $auditions->count().' Auditions updated successfully'); + } + public function reorder(Request $request) { $order = $request->order; diff --git a/app/Http/Requests/BulkAuditionEditRequest.php b/app/Http/Requests/BulkAuditionEditRequest.php new file mode 100644 index 0000000..a325d93 --- /dev/null +++ b/app/Http/Requests/BulkAuditionEditRequest.php @@ -0,0 +1,74 @@ +has('editEvent')) { + $this->request->remove('event_id'); + } + if (! $this->has('editDeadline')) { + $this->request->remove('entry_deadline'); + } + if (! $this->has('editFee')) { + $this->request->remove('entry_fee'); + } + if (! $this->has('editMinGrade')) { + $this->request->remove('minimum_grade'); + } + if (! $this->has('editMaxGrade')) { + $this->request->remove('maximum_grade'); + } + if (! $this->has('editScope')) { + $this->request->remove('for_seating'); + $this->request->remove('for_advancement'); + } + if ($this->has('editScope')) { + if ($this->has('for_seating')) { + $this->merge(['for_seating' => true]); + } else { + $this->merge(['for_seating' => false]); + } + + if ($this->has('for_advancement')) { + $this->merge(['for_advancement' => true]); + } else { + $this->merge(['for_advancement' => false]); + } + } + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'auditions' => 'required|array|min:1', + 'auditions.*' => 'required|exists:auditions,id', + 'event_id' => 'sometimes|exists:events,id', + 'entry_deadline' => 'sometimes|date', + 'entry_fee' => 'sometimes|numeric', + 'minimum_grade' => 'sometimes|integer|min:1', + 'maximum_grade' => 'sometimes|integer|min:1', + 'for_seating' => 'sometimes|boolean', + 'for_advancement' => 'sometimes|boolean', + 'editScope' => 'sometimes|boolean', + ]; + } +} diff --git a/resources/views/admin/auditions/bulk_edit_form.blade.php b/resources/views/admin/auditions/bulk_edit_form.blade.php new file mode 100644 index 0000000..61c8adf --- /dev/null +++ b/resources/views/admin/auditions/bulk_edit_form.blade.php @@ -0,0 +1,114 @@ + + Bulk Edit Auditions + + @if($errors->any()) +
+ @foreach($errors->all() as $error) +
+ {{$error}} +
+ @endforeach +
+ @endif + + +
+ @foreach($events as $event) + + + {{ $event->name }} + + Select all {{ $event->name }} + + +
+ @foreach($auditions[$event->id] as $audition) +
+ +
+ @endforeach +
+
+ @endforeach + Edit Selected + Auditions + +
+
+ + Select Values to Edit + +
+
+ +
+ + + @foreach($events as $event) + + @endforeach + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + @if(auditionSetting('advanceTo')) +
+
+ +
+
+
+ +
+
+ +
+
+
+ @endif + + + +
+
+ Submit Changes +
+ + +
diff --git a/resources/views/admin/auditions/index.blade.php b/resources/views/admin/auditions/index.blade.php index daa4dfd..441db46 100644 --- a/resources/views/admin/auditions/index.blade.php +++ b/resources/views/admin/auditions/index.blade.php @@ -2,7 +2,7 @@ Audition Administration - Auditions + Auditions [Bulk Edit] Drag to reorder. Double click to edit. New Audition diff --git a/resources/views/components/form/checkbox.blade.php b/resources/views/components/form/checkbox.blade.php index 9c31e41..cd1dec0 100644 --- a/resources/views/components/form/checkbox.blade.php +++ b/resources/views/components/form/checkbox.blade.php @@ -2,7 +2,9 @@ 'label' => false, 'description' => '', 'checked' => false, - 'id' => false]) + 'id' => false, + 'value' => 1, + ]) @php if(! $id): $id = $name; @@ -14,9 +16,9 @@ aria-describedby="comments-description" name="{{ $name }}" type="checkbox" - value="1" + value="{{ $value }}" @if($checked) checked @endif - {{ $attributes->merge(['class' => "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"]) }}> + {{ $attributes->merge(['class' => "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"]) }}>
@if($label) diff --git a/resources/views/components/layout/app.blade.php b/resources/views/components/layout/app.blade.php index 3fa507c..8d9415b 100644 --- a/resources/views/components/layout/app.blade.php +++ b/resources/views/components/layout/app.blade.php @@ -17,7 +17,7 @@ - +merge(['class' => 'h-full']) }}>
{{-- @if(request()->is('*admin*'))--}} {{-- --}} diff --git a/routes/admin.php b/routes/admin.php index 642c40f..93992a2 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -133,6 +133,8 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')-> Route::patch('/{audition}', 'update')->name('admin.auditions.update'); Route::post('/reorder', 'reorder')->name('admin.auditions.reorder'); Route::delete('/{audition}', 'destroy')->name('admin.auditions.destroy'); + Route::get('/bulk-edit', 'bulkEditForm')->name('admin.auditions.bulkEditForm'); + Route::post('/bulk-edit', 'bulkUpdate')->name('admin.auditions.bulkEdit'); }); // Admin Audition Draw Routes