parent
4548be098a
commit
3315efc83b
|
|
@ -4,12 +4,14 @@ namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\AuditionStoreOrUpdateRequest;
|
use App\Http\Requests\AuditionStoreOrUpdateRequest;
|
||||||
|
use App\Http\Requests\BulkAuditionEditRequest;
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
use App\Models\Event;
|
use App\Models\Event;
|
||||||
use App\Models\Room;
|
use App\Models\Room;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
use function compact;
|
||||||
use function redirect;
|
use function redirect;
|
||||||
use function request;
|
use function request;
|
||||||
use function response;
|
use function response;
|
||||||
|
|
@ -84,6 +86,57 @@ class AuditionController extends Controller
|
||||||
return to_route('admin.auditions.index')->with('success', 'Audition updated successfully');
|
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)
|
public function reorder(Request $request)
|
||||||
{
|
{
|
||||||
$order = $request->order;
|
$order = $request->order;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class BulkAuditionEditRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
// TODO write authorize
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareForValidation(): void
|
||||||
|
{
|
||||||
|
if (! $this->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, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|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',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
<x-layout.app x-data="{ selectAuditionsForm: true, newValuesForm: false }">
|
||||||
|
<x-slot:page_title>Bulk Edit Auditions</x-slot:page_title>
|
||||||
|
|
||||||
|
@if($errors->any())
|
||||||
|
<div class="mt-3">
|
||||||
|
@foreach($errors->all() as $error)
|
||||||
|
<div class="ml-3">
|
||||||
|
<span
|
||||||
|
class="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 inset-ring inset-ring-red-600/10 dark:bg-red-400/10 dark:text-red-400 dark:inset-ring-red-400/20">{{$error}}</span>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<x-form.form method="POST" action="{{ route('admin.auditions.bulkEdit') }}">
|
||||||
|
<div x-show="selectAuditionsForm" x-cloak>
|
||||||
|
@foreach($events as $event)
|
||||||
|
<x-card.card class="mb-3">
|
||||||
|
<x-card.heading>
|
||||||
|
{{ $event->name }}
|
||||||
|
<x-slot:right_side>
|
||||||
|
<x-form.button type="button" @click="checkAllCheckboxesByClass('event-{{$event->id}}')">Select all {{ $event->name }}</x-form.button>
|
||||||
|
</x-slot:right_side>
|
||||||
|
</x-card.heading>
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-3">
|
||||||
|
@foreach($auditions[$event->id] as $audition)
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="auditions[{{ $audition->id }}]" label="{{$audition->name}}" value="{{ $audition->id }}"
|
||||||
|
class="event-{{$event->id}}"/>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</x-card.card>
|
||||||
|
@endforeach
|
||||||
|
<x-form.button type="button" @click="selectAuditionsForm = false; newValuesForm = true">Edit Selected
|
||||||
|
Auditions
|
||||||
|
</x-form.button>
|
||||||
|
</div>
|
||||||
|
<div x-show="newValuesForm" x-cloak>
|
||||||
|
<x-card.card class="max-w-xl mx-auto" x-data="{ editName: false, editEvent: false, editDeadline: false, editFee: false, editMinGrade: false, editMaxGrade: false, editScope: false }">
|
||||||
|
<x-card.heading>Select Values to Edit</x-card.heading>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editEvent" label="Edit Audition Event" x-model="editEvent"/>
|
||||||
|
</div>
|
||||||
|
<x-form.select name="event_id" x-show="editEvent" x-cloak>
|
||||||
|
<x-slot:label></x-slot:label>
|
||||||
|
@foreach($events as $event)
|
||||||
|
<option value="{{ $event->id }}">{{ $event->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</x-form.select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editDeadline" label="Edit Entry Deadline" x-model="editDeadline"/>
|
||||||
|
</div>
|
||||||
|
<x-form.field name="entry_deadline" type="date" x-cloak x-show="editDeadline"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editFee" label="Edit Entry Fee" x-model="editFee"/>
|
||||||
|
</div>
|
||||||
|
<x-form.field name="entry_fee" type="number" placeholder="Enter New Entry Fee" x-cloak x-show="editFee" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editMinGrade" label="Edit Minimum Grade" x-model="editMinGrade"/>
|
||||||
|
</div>
|
||||||
|
<x-form.field name="minimum_grade" type="number" placeholder="Enter New Minimum Grade" x-cloak x-show="editMinGrade" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editMaxGrade" label="Edit Maximum Grade" x-model="editMaxGrade"/>
|
||||||
|
</div>
|
||||||
|
<x-form.field name="maximum_grade" type="number" placeholder="Enter New Maximum Grade " x-cloak x-show="editMaxGrade" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if(auditionSetting('advanceTo'))
|
||||||
|
<div class="grid grid-cols-2 gap-4 p-3 border-b-2">
|
||||||
|
<div>
|
||||||
|
<x-form.checkbox name="editScope" label="Edit Audition Scope" x-model="editScope"/>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2" x-show="editScope" x-cloak>
|
||||||
|
<div class="align-top">
|
||||||
|
<x-form.checkbox name="for_seating" label="For Seats" description="Students will be seated in this audition" checked />
|
||||||
|
</div>
|
||||||
|
<div class="align-top">
|
||||||
|
<x-form.checkbox name="for_advancement" label="For {{ auditionSetting('advanceTo') }}" description="Students compete for advancement" checked/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</x-card.card>
|
||||||
|
</div>
|
||||||
|
<x-form.button x-cloak x-show="newValuesForm" class="mt-3 max-w-xl mx-auto">Submit Changes</x-form.button>
|
||||||
|
</x-form.form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function checkAllCheckboxesByClass(className) {
|
||||||
|
const checkboxes = document.querySelectorAll(`input[type="checkbox"].${className}`);
|
||||||
|
checkboxes.forEach(checkbox => {
|
||||||
|
checkbox.checked = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</x-layout.app>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<x-slot:page_title>Audition Administration</x-slot:page_title>
|
<x-slot:page_title>Audition Administration</x-slot:page_title>
|
||||||
<x-card.card>
|
<x-card.card>
|
||||||
<x-table.table with_title_area sortable="false" id="auditions-table">
|
<x-table.table with_title_area sortable="false" id="auditions-table">
|
||||||
<x-slot:title class="ml-3">Auditions</x-slot:title>
|
<x-slot:title class="ml-3">Auditions <span class="font-normal text-sm"><a href="{{ route('admin.auditions.bulkEditForm') }}">[Bulk Edit]</a></span></x-slot:title>
|
||||||
<x-slot:subtitle class="ml-3">Drag to reorder. Double click to edit.</x-slot:subtitle>
|
<x-slot:subtitle class="ml-3">Drag to reorder. Double click to edit.</x-slot:subtitle>
|
||||||
<x-slot:title_block_right class="mr-3">
|
<x-slot:title_block_right class="mr-3">
|
||||||
<x-form.button href="{{ route('admin.auditions.create') }}">New Audition</x-form.button>
|
<x-form.button href="{{ route('admin.auditions.create') }}">New Audition</x-form.button>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
'label' => false,
|
'label' => false,
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'checked' => false,
|
'checked' => false,
|
||||||
'id' => false])
|
'id' => false,
|
||||||
|
'value' => 1,
|
||||||
|
])
|
||||||
@php
|
@php
|
||||||
if(! $id):
|
if(! $id):
|
||||||
$id = $name;
|
$id = $name;
|
||||||
|
|
@ -14,7 +16,7 @@
|
||||||
aria-describedby="comments-description"
|
aria-describedby="comments-description"
|
||||||
name="{{ $name }}"
|
name="{{ $name }}"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
value="1"
|
value="{{ $value }}"
|
||||||
@if($checked) checked @endif
|
@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"]) }}>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<script src="{{ asset('js/sort_table_by_column.js') }}"></script>
|
<script src="{{ asset('js/sort_table_by_column.js') }}"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="h-full">
|
<body {{ $attributes->merge(['class' => 'h-full']) }}>
|
||||||
<div class="min-h-full">
|
<div class="min-h-full">
|
||||||
{{-- @if(request()->is('*admin*'))--}}
|
{{-- @if(request()->is('*admin*'))--}}
|
||||||
{{-- <x-layout.navbar.navbar-admin />--}}
|
{{-- <x-layout.navbar.navbar-admin />--}}
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')->
|
||||||
Route::patch('/{audition}', 'update')->name('admin.auditions.update');
|
Route::patch('/{audition}', 'update')->name('admin.auditions.update');
|
||||||
Route::post('/reorder', 'reorder')->name('admin.auditions.reorder');
|
Route::post('/reorder', 'reorder')->name('admin.auditions.reorder');
|
||||||
Route::delete('/{audition}', 'destroy')->name('admin.auditions.destroy');
|
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
|
// Admin Audition Draw Routes
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue