From c60f1714c16a6b17b082473a034c10ebe926a2d3 Mon Sep 17 00:00:00 2001 From: Matt Young Date: Fri, 31 Oct 2025 14:35:37 -0500 Subject: [PATCH] Now able to manage split score definitions --- .../Admin/SplitScoreDefinitionController.php | 78 +++++++++++++++++++ .../EditSplitScoreDefinitionRequest.php | 53 +++++++++++++ app/Models/Audition.php | 5 ++ app/Models/SplitScoreDefinition.php | 5 ++ ...3_create_split_score_definitions_table.php | 2 +- .../split_score_definitions/create.blade.php | 19 +++++ .../split_score_definitions/edit.blade.php | 50 ++++++++++++ .../split_score_definitions/index.blade.php | 17 ++++ routes/admin.php | 11 +++ 9 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/Admin/SplitScoreDefinitionController.php create mode 100644 app/Http/Requests/EditSplitScoreDefinitionRequest.php create mode 100644 resources/views/admin/split_score_definitions/create.blade.php create mode 100644 resources/views/admin/split_score_definitions/edit.blade.php create mode 100644 resources/views/admin/split_score_definitions/index.blade.php diff --git a/app/Http/Controllers/Admin/SplitScoreDefinitionController.php b/app/Http/Controllers/Admin/SplitScoreDefinitionController.php new file mode 100644 index 0000000..29c8bfe --- /dev/null +++ b/app/Http/Controllers/Admin/SplitScoreDefinitionController.php @@ -0,0 +1,78 @@ +get(); + + return view('admin.split_score_definitions.create', compact('availableAuditions')); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'audition_id' => 'required|exists:auditions,id|unique:split_score_definitions,audition_id', + ]); + $newSplit = SplitScoreDefinition::create([ + 'audition_id' => $validated['audition_id'], + 'splits' => [], + ]); + + return redirect()->route('admin.split_score_definitions.edit', $newSplit)->with('success', + 'Split score definition created'); + } + + public function edit(SplitScoreDefinition $splitScoreDefinition) + { + $subscores = $splitScoreDefinition->audition->scoringGuide->subscores; + $judges = $splitScoreDefinition->audition->room->judges; + + return view('admin.split_score_definitions.edit', compact('splitScoreDefinition', 'subscores', 'judges')); + } + + public function update(EditSplitScoreDefinitionRequest $request, SplitScoreDefinition $splitScoreDefinition) + { + $savedSplits = $splitScoreDefinition->splits; + if ($request->validated()['split'] ?? false) { + $newSplit = []; + $submittedSplitData = $request->validated()['split']; + foreach ($submittedSplitData as $splitName => $splitData) { + $name = $splitName; + $judges = array_values($splitData['judges'] ?? []); + $subscores = array_values($splitData['subscores'] ?? []); + $newSplit[$name] = ['judges' => $judges, 'subscores' => $subscores]; + } + $splitScoreDefinition->splits = $newSplit; + $splitScoreDefinition->save(); + + } + if ($request->validated()['new_split'] ?? false) { + $savedSplits[$request->validated()['new_split']] = ['judges' => [], 'subscores' => []]; + $splitScoreDefinition->splits = $savedSplits; + $splitScoreDefinition->save(); + } + + return redirect()->route('admin.split_score_definitions.edit', $splitScoreDefinition); + } + + public function destroy(SplitScoreDefinition $scoreDefinition) + { + + } +} diff --git a/app/Http/Requests/EditSplitScoreDefinitionRequest.php b/app/Http/Requests/EditSplitScoreDefinitionRequest.php new file mode 100644 index 0000000..3479c5d --- /dev/null +++ b/app/Http/Requests/EditSplitScoreDefinitionRequest.php @@ -0,0 +1,53 @@ +user()->is_admin; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + + return [ + 'new_split' => 'sometimes|string|max:255|min:1', + 'split' => 'sometimes|array', + ]; + } + + public function after(): array + { + $splitScoreDefinition = $this->route('splitScoreDefinition'); + + return [ + function (Validator $validator) use ($splitScoreDefinition) { + if ($this->has('new_split')) { + $existingSplitNames = collect($splitScoreDefinition->splits) + ->pluck('name') + ->toArray(); + + if (in_array($this->new_split, $existingSplitNames)) { + $validator->errors()->add( + 'new_split', + 'This split name already exists in this definition.' + ); + } + } + }, + ]; + } +} diff --git a/app/Models/Audition.php b/app/Models/Audition.php index 9ae5c8a..ab9c817 100644 --- a/app/Models/Audition.php +++ b/app/Models/Audition.php @@ -125,6 +125,11 @@ class Audition extends Model return $this->attributes['judges_count']; } + public function splitScoreDefinition(): HasOne + { + return $this->hasOne(SplitScoreDefinition::class); + } + public function flags(): HasMany { return $this->hasMany(AuditionFlag::class); diff --git a/app/Models/SplitScoreDefinition.php b/app/Models/SplitScoreDefinition.php index d619140..37efa63 100644 --- a/app/Models/SplitScoreDefinition.php +++ b/app/Models/SplitScoreDefinition.php @@ -14,4 +14,9 @@ class SplitScoreDefinition extends Model protected $casts = [ 'splits' => 'array', ]; + + public function audition() + { + return $this->belongsTo(Audition::class); + } } diff --git a/database/migrations/2025_10_31_125143_create_split_score_definitions_table.php b/database/migrations/2025_10_31_125143_create_split_score_definitions_table.php index 093e3e5..69f0ae7 100644 --- a/database/migrations/2025_10_31_125143_create_split_score_definitions_table.php +++ b/database/migrations/2025_10_31_125143_create_split_score_definitions_table.php @@ -14,7 +14,7 @@ return new class extends Migration { Schema::create('split_score_definitions', function (Blueprint $table) { $table->id(); - $table->foreignIdFor(Audition::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + $table->foreignIdFor(Audition::class)->unique()->constrained()->cascadeOnDelete()->cascadeOnUpdate(); $table->json('splits')->nullable(); $table->timestamps(); }); diff --git a/resources/views/admin/split_score_definitions/create.blade.php b/resources/views/admin/split_score_definitions/create.blade.php new file mode 100644 index 0000000..5f3cc53 --- /dev/null +++ b/resources/views/admin/split_score_definitions/create.blade.php @@ -0,0 +1,19 @@ + + Split Score Definition + + + Create Split Score + + + + Audition + + @foreach ($availableAuditions as $audition) + + @endforeach + + Create Split Score + + + + diff --git a/resources/views/admin/split_score_definitions/edit.blade.php b/resources/views/admin/split_score_definitions/edit.blade.php new file mode 100644 index 0000000..a4d5649 --- /dev/null +++ b/resources/views/admin/split_score_definitions/edit.blade.php @@ -0,0 +1,50 @@ + + Split Score - {{ $splitScoreDefinition->audition->name }} + + Add Split + + + Create New Split + + + + @if(is_array($splitScoreDefinition->splits)) + + @foreach($splitScoreDefinition->splits as $splitName => $splitData) + + {{ $splitName }} +
+
+
Subscores
+ + @foreach($subscores as $subscore) + + @php($checked = in_array($subscore->id, $splitScoreDefinition->splits[$splitName]['subscores']) ?? false) + + {{ $subscore->name }} + + @endforeach + +
+
+
Judges
+ + @foreach($judges as $judge) + @php($checked = in_array($judge->id, $splitScoreDefinition->splits[$splitName]['judges']) ?? false) + + + {{ $judge->full_name() }} + + @endforeach + +
+
+
+ @endforeach + Submit Changes +
+ @endif +
diff --git a/resources/views/admin/split_score_definitions/index.blade.php b/resources/views/admin/split_score_definitions/index.blade.php new file mode 100644 index 0000000..9f1b324 --- /dev/null +++ b/resources/views/admin/split_score_definitions/index.blade.php @@ -0,0 +1,17 @@ + + Split Scores + + Create Split-Score + + + + @foreach($splitScores as $splitScore) + + + {{ $splitScore->audition->name }} + + + @endforeach + + + diff --git a/routes/admin.php b/routes/admin.php index 885101f..62aeec4 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -20,6 +20,7 @@ use App\Http\Controllers\Admin\RecapController; use App\Http\Controllers\Admin\RoomController; use App\Http\Controllers\Admin\SchoolController; use App\Http\Controllers\Admin\ScoringGuideController; +use App\Http\Controllers\Admin\SplitScoreDefinitionController; use App\Http\Controllers\Admin\StudentController; use App\Http\Controllers\Admin\UserController; use App\Http\Controllers\Admin\YearEndResetController; @@ -219,4 +220,14 @@ Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')-> Route::patch('/{prelimDefinition}', 'update')->name('admin.prelim_definitions.update'); Route::delete('/{prelimDefinition}', 'destroy')->name('admin.prelim_definitions.destroy'); }); + + // SplitScoreDefinition Routes + Route::prefix('split_score_definitions')->controller(SplitScoreDefinitionController::class)->group(function () { + Route::get('/', 'index')->name('admin.split_score_definitions.index'); + Route::get('/new', 'create')->name('admin.split_score_definitions.create'); + Route::post('/', 'store')->name('admin.split_score_definitions.store'); + Route::get('/{splitScoreDefinition}', 'edit')->name('admin.split_score_definitions.edit'); + Route::patch('/{splitScoreDefinition}', 'update')->name('admin.split_score_definitions.update'); + Route::delete('/{splitScoreDefinition}', 'destroy')->name('admin.split_score_definitions.destroy'); + }); });