Etude upload form working.
This commit is contained in:
parent
39a598c67b
commit
f7c75fa1f9
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\EtudeUploadRequest;
|
||||
use App\Models\AuditionedEnsemble;
|
||||
use App\Models\AuditionEtude;
|
||||
use App\Models\Instrument;
|
||||
|
|
@ -24,6 +25,7 @@ class AuditionEtudeController extends Controller
|
|||
{
|
||||
$instruments = Instrument::orderBy('score_order')->get();
|
||||
$ensembles = AuditionedEnsemble::all();
|
||||
|
||||
return view('admin.audition_etude.create', [
|
||||
'instruments' => $instruments,
|
||||
'ensembles' => $ensembles,
|
||||
|
|
@ -33,9 +35,22 @@ class AuditionEtudeController extends Controller
|
|||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(EtudeUploadRequest $request)
|
||||
{
|
||||
//
|
||||
$path = $request->file('file_upload')->store('etudes', 'public');
|
||||
$originalFilename = $request->file('file_upload')->getClientOriginalName();
|
||||
$fileSize = $request->file('file_upload')->getSize();
|
||||
|
||||
AuditionEtude::create([
|
||||
'instrument_id' => $request->instrument_id,
|
||||
'auditioned_ensemble_id' => $request->auditioned_ensemble_id,
|
||||
'set' => $request->set,
|
||||
'file_path' => $path,
|
||||
'original_filename' => $originalFilename,
|
||||
'file_size' => $fileSize,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.etudes.index')->with('success', 'Etude uploaded successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\AuditionedEnsemble;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class EtudeUploadRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
||||
return [
|
||||
'auditioned_ensemble_id' => ['required', 'exists:auditioned_ensembles,id'],
|
||||
'instrument_id' => ['required', 'exists:instruments,id'],
|
||||
'set' => [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:1',
|
||||
function ($attribute, $value, $fail) {
|
||||
/** @noinspection PhpUndefinedFieldInspection */
|
||||
$ensemble = AuditionedEnsemble::find($this->audtioned_ensemble_id);
|
||||
if ($ensemble && $value > $ensemble->set_count) {
|
||||
$fail("The set number cannot exceed {$ensemble->set_count} for this ensemble.");
|
||||
}
|
||||
},
|
||||
],
|
||||
'file_upload' => ['required', 'file', 'mimes:pdf', 'mimetypes:application/pdf', 'max:10240'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -2,13 +2,35 @@
|
|||
<x-card class="max-w-xl mx-auto">
|
||||
<x-slot:header class="bg-brand-600!">New Etude</x-slot:header>
|
||||
<x-slot:body class="bg-white border border-brand-600">
|
||||
<x-form.form method="POST" action="{{ route('admin.etudes.store') }}" x-data="{ selectedEnsemble: '', selectedInstrument: '', selectedSetNumber: '' }">
|
||||
@if($errors->any())
|
||||
<div class="mb-4 rounded-md bg-red-50 p-4 dark:bg-red-900/20">
|
||||
<div class="flex">
|
||||
<div class="shrink-0">
|
||||
<svg class="size-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-red-800 dark:text-red-200">There were {{ $errors->count() }} error(s) with your submission</h3>
|
||||
<div class="mt-2 text-sm text-red-700 dark:text-red-300">
|
||||
<ul class="list-disc space-y-1 pl-5">
|
||||
@foreach($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<x-form.form method="POST" action="{{ route('admin.etudes.store') }}" enctype="multipart/form-data" x-data="{ selectedEnsemble: '', selectedInstrument: '', selectedSetNumber: '' }">
|
||||
<div>
|
||||
<x-form.select name="auditioned_ensemble_id" x-model="selectedEnsemble">
|
||||
<x-slot:label>Ensemble</x-slot:label>
|
||||
<option value="">Select Ensemble...</option>
|
||||
@foreach($ensembles as $ensemble)
|
||||
<option value="{{ $ensemble->id }}">{{ $ensemble->name }}</option>
|
||||
<option value="{{ $ensemble->id }}" {{ old('auditioned_ensemble_id') === $ensemble->id ? ' SELECTED ':'' }}>{{ $ensemble->name }}</option>
|
||||
@endforeach
|
||||
</x-form.select>
|
||||
</div>
|
||||
|
|
@ -17,15 +39,18 @@
|
|||
<option value="">Select Instrument...</option>
|
||||
<x-slot:label>Instrument</x-slot:label>
|
||||
@foreach($instruments as $instrument)
|
||||
<option value="{{ $instrument->id }}">{{ $instrument->instrument }}</option>
|
||||
<option value="{{ $instrument->id }}" {{ old('instrument_id') === $instrument->id ? ' SELECTED ':'' }}>{{ $instrument->instrument }}</option>
|
||||
@endforeach
|
||||
</x-form.select>
|
||||
</div>
|
||||
<div class="mt-3" x-show="selectedEnsemble" x-cloak x-model="selectedSetNumber">
|
||||
<x-form.input name="set" label="Set Number" type="number" min="1" x-bind:max="selectedEnsemble ? getSetCount(selectedEnsemble) : ''" />
|
||||
<div class="mt-3">
|
||||
<x-form.input name="set" label="Set Number" value="{{ old('set') }}" type="number" min="1" x-bind:max="selectedEnsemble ? getSetCount(selectedEnsemble) : ''" x-bind:disabled="!selectedEnsemble" x-model="selectedSetNumber" />
|
||||
</div>
|
||||
<div class="mt-3" x-show="selectedEnsemble && selectedInstrument && selectedSetNumber" x-cloak>
|
||||
<x-form.input name="file" type="file" label="Etude PDF" />
|
||||
<div class="mt-3">
|
||||
<x-form.input name="file_upload" type="file" label="Etude PDF" />
|
||||
</div>
|
||||
<div class="mt-3 text-right">
|
||||
<x-form.button type="submit" x-bind:disabled="!selectedEnsemble || !selectedInstrument || !selectedSetNumber">Save Etude</x-form.button>
|
||||
</div>
|
||||
</x-form.form>
|
||||
</x-slot:body>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
@php
|
||||
$classes = [
|
||||
'bg-brand-600 font-semibold text-white shadow-xs hover:bg-brand-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-600 dark:bg-brand-500 dark:shadow-none dark:hover:bg-brand-400 dark:focus-visible:outline-brand-500',
|
||||
'bg-brand-600 font-semibold text-white shadow-xs hover:bg-brand-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-600 dark:bg-brand-500 dark:shadow-none dark:hover:bg-brand-400 dark:focus-visible:outline-brand-500 disabled:bg-brand-200 disabled:cursor-not-allowed',
|
||||
'rounded-sm px-2 py-1 text-xs' => $size == 1,
|
||||
'rounded-sm px-2 py-1 text-sm' => $size == 2,
|
||||
'rounded-md px-2.5 py-1.5 text-sm' => $size == 3,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
@props(['id', 'name', 'label'])
|
||||
<label for="{{ $id ?? $name }}" class="" {{ $label->attributes->merge(['class'=>'block text-sm/6 font-medium text-gray-900 dark:text-white']) }}>{{ $label }}</label>
|
||||
<div class="mt-2 grid grid-cols-1">
|
||||
<select id="{{ $id ?? $name }}" name="{{ $name }}" {{ $attributes->merge(['class' => 'col-start-1 row-start-1 w-full appearance-none rounded-md bg-white py-1.5 pr-8 pl-3 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:*:bg-gray-800 dark:focus-visible:outline-indigo-500']) }}>
|
||||
<div>
|
||||
<label for="{{ $id ?? $name }}"
|
||||
class="" {{ $label->attributes->merge(['class'=>'block text-sm/6 font-medium text-gray-900 dark:text-white']) }}>{{ $label }}</label>
|
||||
<div class="mt-2 grid grid-cols-1">
|
||||
<select id="{{ $id ?? $name }}"
|
||||
name="{{ $name }}" {{ $attributes->merge(['class' => 'col-start-1 row-start-1 w-full appearance-none rounded-md bg-white py-1.5 pr-8 pl-3 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-indigo-600 sm:text-sm/6 dark:bg-white/5 dark:text-white dark:outline-white/10 dark:*:bg-gray-800 dark:focus-visible:outline-indigo-500']) }}>
|
||||
{{ $slot }}
|
||||
</select>
|
||||
<svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-gray-500 sm:size-4 dark:text-gray-400">
|
||||
<path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
|
||||
<svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" aria-hidden="true"
|
||||
class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-gray-500 sm:size-4 dark:text-gray-400">
|
||||
<path
|
||||
d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z"
|
||||
clip-rule="evenodd" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
@error($name)
|
||||
<p id="{{ $id ?? $name }}-error" class="mt-2 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue