Require confirmation for making a scored entry a no-show

This commit is contained in:
Matt Young 2024-07-07 22:12:36 -05:00
parent 0f18a7c62e
commit 03a2dd2e1d
7 changed files with 97 additions and 19 deletions

View File

@ -21,21 +21,42 @@ class EntryFlagController extends Controller
$validData = $request->validate([
'entry_id' => 'required|exists:entries,id',
]);
$entry = Entry::with('flags')->find($validData['entry_id']);
$entry = Entry::with('flags')->withCount('scoreSheets')->find($validData['entry_id']);
if ($entry->hasFlag('no_show')) {
$formId = 'no-show-cancellation-form';
$buttonName = 'Remove No Show';
$submitRouteName = 'entry-flags.enterNoShow';
$cardHeading = 'Undo No Show';
$submitRouteName = 'entry-flags.undoNoShow';
$cardHeading = 'Undo No-Show';
$method = 'DELETE';
} else {
$formId = 'no-show-confirmation-form';
$buttonName = 'Confirm No Show';
$submitRouteName = 'entry-flags.enterNoShow';
$cardHeading = 'Confirm No Show';
$cardHeading = 'Confirm No-Show';
$method = 'POST';
}
$scores = [];
if($entry->score_sheets_count > 0) {
$scores = $entry->scoreSheets;
$scores->load('judge');
}
return view('tabulation.no_show_confirm',
compact('entry', 'formId', 'buttonName', 'submitRouteName', 'cardHeading'));
compact('entry',
'formId',
'buttonName',
'submitRouteName',
'cardHeading',
'method',
'scores'));
}
public function enterNoShow(Entry $entry)
{
//
}
public function undoNoShow(Entry $entry)
{
//
}
}

View File

@ -4,7 +4,6 @@ namespace Database\Seeders;
use App\Models\ScoreSheet;
use App\Models\User;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ScoreAllAuditions extends Seeder
@ -16,23 +15,23 @@ class ScoreAllAuditions extends Seeder
{
$judges = User::all();
foreach ($judges as $judge) {
foreach( $judge->rooms as $room) {
foreach ($room->auditions as $audition){
foreach ($judge->rooms as $room) {
foreach ($room->auditions as $audition) {
$scoringGuide = $audition->scoringGuide;
$subscores = $scoringGuide->subscores;
foreach ($audition->entries as $entry){
foreach ($audition->entries as $entry) {
$scoreArray = [];
foreach ($subscores as $subscore) {
$scoreArray[$subscore->id] = [
'score' => mt_rand(0,100),
'score' => mt_rand(0, 100),
'subscore_id' => $subscore->id,
'subscore_name' => $subscore->name
'subscore_name' => $subscore->name,
];
}
ScoreSheet::create([
'user_id' => $judge->id,
'entry_id' => $entry->id,
'subscores' => $scoreArray
'subscores' => $scoreArray,
]);
}
}

View File

@ -2,7 +2,7 @@
<div x-data="{ toggle: {{ $checked ? 'true':'false'}} }" class="flex items-center">
<label {{ $attributes->merge(['class'=>'relative inline-flex items-center cursor-pointer']) }}>{{ $slot }}
<input type="checkbox" x-model="toggle" name="{{ $name }}" class="sr-only" {{ $checked ? 'checked':''}} value="1" >
<div :class="toggle ? 'bg-blue-600' : 'bg-gray-200'" class="w-11 h-6 rounded-full transition-colors duration-300"></div>
<div :class="toggle ? 'bg-indigo-600' : 'bg-gray-200'" class="w-11 h-6 rounded-full transition-colors duration-300"></div>
<div :class="toggle ? 'translate-x-6' : 'translate-x-1'" class="absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform duration-300"></div>
</label>
@error($name)

View File

@ -1,5 +1,30 @@
<x-layout.app>
<x-card.card class="mx-auto max-w-md">
<x-layout.app x-data="{ showButton: {{ $scores ? 'false':'true' }} }">
@if($scores)
<x-card.card class="mx-auto max-w-2xl mb-3">
<x-card.heading class="text-red-600">
WARNING: Entry has existing scores
</x-card.heading>
<div class="grid md:grid-cols-3 px-4 space-x-3 pb-6">
@foreach($scores as $score)
<div>
<div class="my-3 border-b">{{ $score->judge->full_name() }}</div>
<ul>
@foreach($score->subscores as $subscore)
<div class="grid grid-cols-2 gap-x-8 border-b">
<span>{{ $subscore['subscore_name'] }}</span>
<span>{{ $subscore['score'] }}</span>
</div>
@endforeach
</ul>
</div>
@endforeach
</div>
<div class="pb-5 pl-5 flex gap-1">
<x-form.checkbox name="confirm" x-model="showButton" /> I understand that marking this entry as a no-show will delete existing scores. The scores cannot be recovered.
</div>
</x-card.card>
@endif
<x-card.card class="mx-auto max-w-md" x-show="showButton" x-cloak>
<x-card.heading>{{ $cardHeading }}</x-card.heading>
<x-card.list.body>
<x-card.list.row>
@ -11,8 +36,8 @@
</x-card.list.row>
</x-card.list.body>
<x-form.footer class="mb-4">
<x-form.form method="POST" action="{{route($submitRouteName, $entry)}}" id="{{ $formId }}">
<x-form.button type="submit">{{ $buttonName }}</x-form.button>
<x-form.form method="{{ $method }}" action="{{route($submitRouteName, $entry)}}" id="{{ $formId }}">
<x-form.button type="submit" >{{ $buttonName }}</x-form.button>
</x-form.form>
</x-form.footer>
</x-card.card>

View File

@ -0,0 +1,6 @@
<div class="flex items-center">
<label class="'relative inline-flex items-center cursor-pointer'">{{ $slot }}
<input type="checkbox" x-model="toggle" name="{{ $name }}" class="sr-only" {{ $checked ? 'checked':''}} value="1" >
<div :class="toggle ? 'bg-indigo-600' : 'bg-gray-200'" class="w-11 h-6 rounded-full transition-colors duration-300"></div>
<div :class="toggle ? 'translate-x-6' : 'translate-x-1'" class="absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition-transform duration-300"></div>
</label>

View File

@ -19,6 +19,7 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
Route::get('/choose_no_show', 'noShowSelect')->name('entry-flags.noShowSelect');
Route::get('/propose-no-show', 'noShowConfirm')->name('entry-flags.confirmNoShow');
Route::post('/no-show/{entry}', 'enterNoShow')->name('entry-flags.enterNoShow');
Route::delete('/no-show/{entry}', 'undoNoShow')->name('entry-flags.undoNoShow');
});
// Generic Tabulation Routes

View File

@ -1,7 +1,13 @@
<?php
use App\Models\Audition;
use App\Models\Entry;
use App\Models\Room;
use App\Models\ScoringGuide;
use App\Models\SubscoreDefinition;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Sinnbeck\DomAssertions\Asserts\AssertForm;
use function Pest\Laravel\get;
@ -64,3 +70,23 @@ it('posts to entry-flags.undoNoShow and has a remove button if the entry is alre
->hasCSRF();
});
});
it('shows a box with scores if the entry is scored', function () {
// Arrange
$judges = User::factory()->count(3)->create();
$room = Room::factory()->create();
$judges->each(fn ($judge) => $room->addJudge($judge->id));
$scoringGuide = ScoringGuide::factory()->create();
SubscoreDefinition::factory()->count(5)->create(['scoring_guide_id' => $scoringGuide->id]);
$audition = Audition::factory()->create(['room_id' => $room->id, 'scoring_guide_id' => $scoringGuide->id]);
$entry = Entry::factory()->create(['audition_id' => $audition->id]);
// Run the ScoreAllAuditions seeder
Artisan::call('db:seed', ['--class' => 'ScoreAllAuditions']);
// Act & Assert
actAsTab();
$response = get(route('entry-flags.confirmNoShow', ['entry_id' => $entry->id]));
$response->assertOk()
->assertSee('WARNING')
->assertSee('existing scores');
$judges->each(fn ($judge) => $response->assertSee($judge->full_name()));
});