Admin settings for auditions complete
This commit is contained in:
parent
1948bdb85f
commit
7c62168ec5
|
|
@ -4,42 +4,112 @@ namespace App\Http\Controllers\Admin;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Audition;
|
||||
use App\Models\Event;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use function abort;
|
||||
use function redirect;
|
||||
use function request;
|
||||
use function response;
|
||||
use function route;
|
||||
|
||||
class AuditionController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
$auditions = Audition::with(['event','entries'])->orderBy('score_order')->get();
|
||||
$auditions = Audition::with(['event','entries'])->orderBy('score_order')->orderBy('created_at','desc')->get();
|
||||
return view('admin.auditions.index', ['auditions' => $auditions] );
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
return view('admin.auditions.create');
|
||||
$events = Event::orderBy('name')->get();
|
||||
return view('admin.auditions.create',['events'=> $events]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
|
||||
$validData = request()->validate([
|
||||
'event_id' => ['required', 'exists:events,id'],
|
||||
'name' => ['required'],
|
||||
'entry_deadline' => ['required', 'date'],
|
||||
'entry_fee' => ['required', 'numeric'],
|
||||
'minimum_grade' => ['required', 'integer'],
|
||||
'maximum_grade' => 'required|numeric|gt:minimum_grade',
|
||||
], [
|
||||
'maximum_grade.gt' => 'The maximum grade must be greater than the minimum grade.',
|
||||
]);
|
||||
|
||||
Audition::create([
|
||||
'event_id' => $validData['event_id'],
|
||||
'name' => $validData['name'],
|
||||
'entry_deadline' => $validData['entry_deadline'],
|
||||
'entry_fee' => $validData['entry_fee'] * 100,
|
||||
'minimum_grade' => $validData['minimum_grade'],
|
||||
'maximum_grade' => $validData['maximum_grade'],
|
||||
]);
|
||||
|
||||
return redirect('/admin/auditions');
|
||||
}
|
||||
|
||||
public function edit(Audition $audition)
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
return view('admin.auditions.edit', ['audition' => $audition]);
|
||||
$events = Event::orderBy('name')->get();
|
||||
return view('admin.auditions.edit', ['audition' => $audition,'events'=> $events]);
|
||||
}
|
||||
|
||||
public function update(Audition $audition)
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
|
||||
$validData = request()->validate([
|
||||
'event_id' => ['required', 'exists:events,id'],
|
||||
'name' => ['required'],
|
||||
'entry_deadline' => ['required', 'date'],
|
||||
'entry_fee' => ['required', 'numeric'],
|
||||
'minimum_grade' => ['required', 'integer'],
|
||||
'maximum_grade' => 'required|numeric|gt:minimum_grade',
|
||||
], [
|
||||
'maximum_grade.gt' => 'The maximum grade must be greater than the minimum grade.',
|
||||
]);
|
||||
|
||||
$audition->update([
|
||||
'event_id' => $validData['event_id'],
|
||||
'name' => $validData['name'],
|
||||
'entry_deadline' => $validData['entry_deadline'],
|
||||
'entry_fee' => $validData['entry_fee'] * 100,
|
||||
'minimum_grade' => $validData['minimum_grade'],
|
||||
'maximum_grade' => $validData['maximum_grade'],
|
||||
]);
|
||||
|
||||
return redirect('/admin/auditions');
|
||||
}
|
||||
|
||||
public function reorder(Request $request)
|
||||
{
|
||||
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
$order = $request->order;
|
||||
foreach ($order as $index => $id) {
|
||||
$audition = Audition::find($id);
|
||||
#$audition->score_order = $index;
|
||||
#return response()->json(['status' => $index]);
|
||||
#$item->save();
|
||||
$audition->update(['score_order' => $index]);
|
||||
}
|
||||
return response()->json(['status' => 'success']);
|
||||
}
|
||||
|
||||
public function destroy(Audition $audition)
|
||||
{
|
||||
if(! Auth::user()->is_admin) abort(403);
|
||||
// if($audition->entries->count() > 0) abort(403, 'Cannot delete an audition with entries.'
|
||||
if($audition->entries->count() > 0) {
|
||||
return redirect()->route('adminAuditionIndex')->with('error', 'Cannot delete an audition with entries.');
|
||||
}
|
||||
$audition->delete();
|
||||
return redirect('/admin/auditions');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Auditions</x-slot:page_title>
|
||||
|
||||
<x-card.card class="max-w-lg mx-auto">
|
||||
<x-card.heading>
|
||||
Create Audition
|
||||
</x-card.heading>
|
||||
<x-form.form method="POST" action="/admin/auditions">
|
||||
<x-form.body-grid columns="12" class="pb-1 pt-3">
|
||||
<x-form.field name="name" label_text="Audition Name" colspan="12" />
|
||||
<x-form.select name="event_id" colspan="12">
|
||||
<x-slot:label>Event</x-slot:label>
|
||||
@foreach($events as $event)
|
||||
<option value="{{ $event->id }}">{{ $event->name }}</option>
|
||||
@endforeach
|
||||
</x-form.select>
|
||||
<x-form.field name="entry_deadline" label_text="Entry Deadline" type="date" colspan="6"/>
|
||||
<x-form.field name="entry_fee" label_text="Entry Fee" type="number" colspan="6" />
|
||||
<x-form.field name="minimum_grade" label_text="Minimum Grade" type="number" colspan="6" />
|
||||
<x-form.field name="maximum_grade" label_text="Maximum Grade" type="number" colspan="6" />
|
||||
</x-form.body-grid>
|
||||
<x-form.footer submit-button-text="Create Audition" class="pb-4"/>
|
||||
</x-form.form>
|
||||
</x-card.card>
|
||||
</x-layout.app>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Auditions</x-slot:page_title>
|
||||
<x-card.card class="max-w-lg mx-auto">
|
||||
<x-card.heading>
|
||||
Edit Audition
|
||||
</x-card.heading>
|
||||
<x-form.form method="PATCH" action="/admin/auditions/{{ $audition->id }}">
|
||||
<x-form.body-grid columns="12" class="pb-1 pt-3">
|
||||
<x-form.field name="name" label_text="Audition Name" colspan="12" value="{{ $audition->name }}" />
|
||||
<x-form.select name="event_id" colspan="12">
|
||||
<x-slot:label>Event</x-slot:label>
|
||||
@foreach($events as $event)
|
||||
<option value="{{ $event->id }}" {{ ($event->id == $audition->event_id) ? "selected":'' }}>{{ $event->name }}</option>
|
||||
@endforeach
|
||||
</x-form.select>
|
||||
<x-form.field name="entry_deadline" label_text="Entry Deadline" type="date" colspan="6" value="{{ $audition->entry_deadline }}"/>
|
||||
<x-form.field name="entry_fee" label_text="Entry Fee" type="number" colspan="6" value="{{ $audition->entry_fee / 100 }}" />
|
||||
<x-form.field name="minimum_grade" label_text="Minimum Grade" type="number" colspan="6" value="{{ $audition->minimum_grade }}" />
|
||||
<x-form.field name="maximum_grade" label_text="Maximum Grade" type="number" colspan="6" value="{{ $audition->maximum_grade }}" />
|
||||
</x-form.body-grid>
|
||||
<x-form.footer submit-button-text="Update Audition" class="pb-4 !justify-between">
|
||||
<div>
|
||||
<x-form.red-trash-button size="20"></x-form.red-trash-button>
|
||||
</div>
|
||||
<div>
|
||||
<x-form.button>Edit Audition</x-form.button>
|
||||
</div>
|
||||
</x-form.footer>
|
||||
|
||||
</x-form.form>
|
||||
<x-form.delete-form action="/admin/auditions/{{ $audition->id }}"></x-form.delete-form>
|
||||
</x-card.card>
|
||||
</x-layout.app>
|
||||
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Audition Administration</x-slot:page_title>
|
||||
|
||||
<x-card.card>
|
||||
<x-table.table with_title_area>
|
||||
<x-slot:title class="ml-3">Auditions</x-slot:title>
|
||||
<x-slot:subtitle class="ml-3">Click name 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-form.button href="/admin/entries/create">New Audition</x-form.button>
|
||||
<x-form.button href="/admin/auditions/create">New Audition</x-form.button>
|
||||
</x-slot:title_block_right>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<x-table.th>Event</x-table.th>
|
||||
<x-table.th>Name</x-table.th>
|
||||
<x-table.th>Order</x-table.th>
|
||||
<x-table.th>Deadline</x-table.th>
|
||||
<x-table.th>Entry Fee</x-table.th>
|
||||
<x-table.th>Grade Range</x-table.th>
|
||||
|
|
@ -25,10 +23,9 @@
|
|||
<div x-data="sortableList()" x-init="init">
|
||||
<x-table.body id="sortable-list">
|
||||
@foreach($auditions as $audition)
|
||||
<tr data-id="{{ $audition->id }}">
|
||||
<tr data-id="{{ $audition->id }}" @dblclick="window.location.href='/admin/auditions/{{ $audition->id }}/edit'">
|
||||
<x-table.td>{{ $audition->event->name }}</x-table.td>
|
||||
<x-table.td>{{ $audition->name }}</x-table.td>
|
||||
<x-table.td>{{ $audition->score_order }}</x-table.td>
|
||||
<x-table.td>{{ $audition->entry_deadline }}</x-table.td>
|
||||
<x-table.td>{{ $audition->dislpay_fee() }}</x-table.td>
|
||||
<x-table.td>{{ $audition->minimum_grade }} - {{ $audition->maximum_grade }}</x-table.td>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,18 @@
|
|||
{{--Send messages with Session::flash('msg|MESSAGE HERE','success, caution or danger');--}}
|
||||
{{--Can also use helper fuction: sendMessage('Test Message','danger')--}}
|
||||
@props(['message','messageType'])
|
||||
@php
|
||||
$div_classes = 'flex justify-between mx-auto max-w-2xl text-sm rounded-md px-3 py-1 mb-2 font-medium ring-1 ring-inset ';
|
||||
$messages = [
|
||||
'success' => session()->get('success'),
|
||||
'error' => session()->get('error'),
|
||||
'caution' => session()->get('caution')
|
||||
];
|
||||
@endphp
|
||||
|
||||
|
||||
@foreach($messages as $messageType => $message)
|
||||
@continue(!$message)
|
||||
@php
|
||||
|
||||
$div_classes = 'flex justify-between mx-auto max-w-2xl text-sm rounded-md px-3 py-1 mb-5 font-medium ring-1 ring-inset ';
|
||||
$button_classes = 'group relative mr-1 h-5 w-5 rounded-sm ';
|
||||
$svg_classes = 'h-5 w-5 ';
|
||||
switch($messageType) {
|
||||
|
|
@ -12,20 +22,20 @@
|
|||
$svg_classes .= 'stroke-yellow-700/50 group-hover:stroke-yellow-700/75';
|
||||
break;
|
||||
|
||||
case 'danger':
|
||||
case 'error':
|
||||
$div_classes .= 'bg-red-50 text-red-700 ring-red-600/40';
|
||||
$button_classes .= 'hover:bg-red-600/20';
|
||||
$svg_classes .= 'stroke-red-600/50 group-hover:stroke-red-600/75';
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'success':
|
||||
$div_classes .= 'bg-green-50 text-green-700 ring-green-600/40 ';
|
||||
$button_classes .= 'hover:bg-green-600/20';
|
||||
$svg_classes .= 'stroke-green-700/50 group-hover:stroke-green-700/75';
|
||||
break;
|
||||
}
|
||||
@endphp
|
||||
<div class="{{ $div_classes }}" x-data="{ shown: true }" x-show="shown">
|
||||
@endphp
|
||||
<div class="{{ $div_classes }}" x-data="{ shown: true }" x-show="shown">
|
||||
<div>{{ $message }}</div>
|
||||
<div>
|
||||
<button type="button" class="{{ $button_classes }}" x-on:click=" shown = false">
|
||||
|
|
@ -36,4 +46,5 @@
|
|||
<span class="absolute -inset-1"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
@props(['action'])
|
||||
@php
|
||||
$attribs = [
|
||||
'method' => 'post',
|
||||
'id' => 'deleteResource',
|
||||
'action' => $action,
|
||||
'name' => 'deleteResource'
|
||||
];
|
||||
@endphp
|
||||
<form {{ $attributes->merge($attribs) }}>
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
</form>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
@props([
|
||||
'method' => 'POST',
|
||||
'form_classes' => 'px-4 py-6 sm:p-8'
|
||||
'form_classes' => 'px-4 sm:px-8'
|
||||
])
|
||||
|
||||
<form method="{{ ($method === 'GET' ? 'GET':'POST') }}" {{ $attributes->merge(['class' => $form_classes]) }}>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
@props(['size' => 25])
|
||||
@php
|
||||
$attribs = [
|
||||
'form' => 'deleteResource',
|
||||
'type' => 'submit',
|
||||
'class' => 'rounded-lg bg-red-600 p-2 text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600'
|
||||
];
|
||||
@endphp
|
||||
<button {{ $attributes->merge($attribs) }}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="{{ $size }}" height="{{ $size }}" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
|
||||
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/>
|
||||
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/>
|
||||
</svg>
|
||||
</svg>
|
||||
</button>
|
||||
|
|
@ -33,9 +33,7 @@
|
|||
|
||||
<main {{ $attributes }}>
|
||||
<div class="mx-auto max-w-7xl py-6 sm:px-6 lg:px-8">
|
||||
@foreach(getMessages() as $message)
|
||||
<x-flash_message :message="$message['message']" :messageType="$message['type']" />
|
||||
@endforeach
|
||||
<x-flash_message></x-flash_message>
|
||||
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@ Route::middleware(['auth','verified',CheckIfAdmin::class])->prefix('admin/')->gr
|
|||
|
||||
// Admin Auditions Routes
|
||||
Route::prefix('auditions')->controller(\App\Http\Controllers\Admin\AuditionController::class)->group(function() {
|
||||
Route::get('/','index');
|
||||
Route::get('/','index')->name('adminAuditionIndex');
|
||||
Route::get('/create','create');
|
||||
Route::post('/','store');
|
||||
Route::get('/{entry}/edit','edit');
|
||||
Route::patch('/{entry}','update');
|
||||
Route::get('/{audition}/edit','edit');
|
||||
Route::patch('/{audition}','update');
|
||||
Route::post('/reorder','reorder');
|
||||
Route::delete('/{audition}','destroy');
|
||||
});
|
||||
|
||||
// Admin Entries Routes
|
||||
|
|
|
|||
Loading…
Reference in New Issue