Refactor auditionseating controller and related views into multiples files for easier management

This commit is contained in:
Matt Young 2025-07-12 11:08:07 -05:00
parent 56f302ef10
commit 8ad74947af
25 changed files with 639 additions and 882 deletions

View File

@ -1,307 +0,0 @@
<?php
namespace App\Http\Controllers\Tabulation;
use App\Actions\Entries\DoublerDecision;
use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Doubler;
use App\Models\Ensemble;
use App\Models\Entry;
use App\Models\Seat;
use Debugbar;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use function redirect;
class SeatAuditionFormController extends Controller
{
public function showForm(Audition $audition)
{
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
if ($audition->hasFlag('seats_published')) {
$publishedSeats = Seat::where('audition_id', $audition->id)
->join('ensembles', 'seats.ensemble_id', '=', 'ensembles.id')
->orderBy('ensembles.rank')
->orderBy('seats.seat')
->select('seats.*')
->with(['ensemble', 'student.school'])
->get();
} else {
$publishedSeats = false;
}
$ranker = app(RankAuditionEntries::class);
// Get scored entries in order
try {
$scored_entries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$scored_entries->load(['student.doublers', 'student.school']);
// Get unscored entries sorted by draw number
$unscored_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereDoesntHave('flags', function ($query) {
$query->where('flag_name', 'no_show');
})
->whereDoesntHave('flags', function ($query) {
$query->where('flag_name', 'failed_prelim');
})
->with('student.school')
->withCount('scoreSheets')
->orderBy('draw_number')
->get();
// Get no show entries sorted by draw number
$noshow_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereHas('flags', function ($query) {
$query->where('flag_name', 'no_show');
})
->with('student.school')
->orderBy('draw_number')
->get();
// Get failed prelim entries sorted by draw number
$failed_prelim_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereHas('flags', function ($query) {
$query->where('flag_name', 'failed_prelim');
})
->with('student.school')
->orderBy('draw_number')
->get();
// Get Doublers
$doublerData = Doubler::where('event_id', $audition->event_id)
->whereIn('student_id', $scored_entries->pluck('student_id'))
->get()
->keyBy('student_id');
$auditionHasUnresolvedDoublers = false;
foreach ($doublerData as $doubler) {
if (! is_null($doubler->accepted_entry)) {
continue;
}
foreach ($doubler->entries() as $entry) {
if ($entry->audition_id === $audition->id && $entry->hasFlag('declined')) {
continue 2;
}
}
$auditionHasUnresolvedDoublers = true;
}
$canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0;
return view('tabulation.auditionSeating',
compact('audition',
'scored_entries',
'unscored_entries',
'noshow_entries',
'failed_prelim_entries',
'doublerData',
'auditionHasUnresolvedDoublers',
'canSeat',
'seatingProposal',
'publishedSeats',
)
);
}
public function declineSeat(Audition $audition, Entry $entry)
{
$decider = app(DoublerDecision::class);
try {
$decider->decline($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has declined '.$audition->name);
}
public function massDecline(Audition $audition)
{
$decider = app(DoublerDecision::class);
$validData = request()->validate([
'decline-below' => ['required', 'integer', 'min:0'],
]);
$ranker = app(RankAuditionEntries::class);
// Get scored entries in order
try {
$scored_entries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$scored_entries->load(['student.doublers', 'student.school']);
foreach ($scored_entries as $entry) {
Debugbar::info('Starting entry '.$entry->student->full_name());
if ($entry->seatingRank < $validData['decline-below']) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they are ranked above decline threshold');
continue;
}
if ($entry->hasFlag('declined')) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already been declined');
continue;
}
if (! $entry->student->isDoublerInEvent($audition->event_id)) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they are not a doubler');
continue;
}
if ($entry->student->doublers->where('event_id', $audition->event_id)->first()->accepted_entry) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already accepted a seat');
continue;
}
try {
$decider->decline($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
}
Cache::forget('rank_seating_'.$audition->id);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function acceptSeat(Audition $audition, Entry $entry)
{
$decider = app(DoublerDecision::class);
try {
$decider->accept($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has accepted '.$audition->name);
}
public function noshow(
Audition $audition,
Entry $entry
) {
$recorder = app('App\Actions\Tabulation\EnterNoShow');
try {
$msg = $recorder($entry);
} catch (AuditionAdminException $e) {
return redirect()->back()->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', [$audition])->with('success', $msg);
}
public function draftSeats(
Audition $audition,
Request $request
) {
$ranker = app(RankAuditionEntries::class);
$validated = $request->validate([
'ensemble' => ['required', 'array'],
'ensemble.*' => ['required', 'integer', 'min:0'],
]);
$proposedSeatingArray = [];
try {
$rankedEntries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$rankedEntries = $rankedEntries->reject(function ($entry) {
return $entry->hasFlag('declined');
});
$rankedEntries->load(['student.school']);
$rankedEnsembles = Ensemble::orderBy('rank')->where('event_id', $audition->event_id)->get();
$ensembleRankOn = 1;
foreach ($rankedEnsembles as $ensemble) {
if (! Arr::has($validated['ensemble'], $ensemble->id)) {
continue;
}
$proposedSeatingArray[$ensembleRankOn]['ensemble_id'] = $ensemble->id;
$proposedSeatingArray[$ensembleRankOn]['ensemble_name'] = $ensemble->name;
$proposedSeatingArray[$ensembleRankOn]['accept_count'] = $validated['ensemble'][$ensemble->id];
for ($n = 1; $n <= $validated['ensemble'][$ensemble->id]; $n++) {
// Escape the loop if we're out of entries
if ($rankedEntries->isEmpty()) {
break;
}
$thisEntry = $rankedEntries->shift();
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['seat'] = $n;
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_id'] = $thisEntry->id;
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_name'] = $thisEntry->student->full_name();
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_school'] = $thisEntry->student->school->name;
}
$ensembleRankOn++;
}
$sessionKeyName = 'proposedSeatingArray-'.$audition->id;
$request->session()->put($sessionKeyName, $proposedSeatingArray);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function clearDraft(
Audition $audition
) {
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function publishSeats(
Audition $audition
) {
$publisher = app('App\Actions\Tabulation\PublishSeats');
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
$proposal = [];
foreach ($seatingProposal as $ensemble) {
$ensembleId = $ensemble['ensemble_id'];
if (isset($ensemble['seats'])) {
foreach ($ensemble['seats'] as $seat) {
$proposal[] = [
'ensemble_id' => $ensembleId,
'audition_id' => $audition->id,
'seat' => $seat['seat'],
'entry_id' => $seat['entry_id'],
];
}
}
}
try {
$publisher($audition, $proposal);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', [$audition])->with('error', $e->getMessage());
}
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', [$audition]);
}
public function unpublishSeats(
Audition $audition
) {
$unpublisher = app('App\Actions\Tabulation\UnpublishSeats');
$unpublisher($audition);
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', [$audition]);
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace App\Http\Controllers\Tabulation\Seating;
use App\Actions\Entries\DoublerDecision;
use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Entry;
use Debugbar;
use Illuminate\Support\Facades\Cache;
use function redirect;
class EnterDoublerDecisionsController extends Controller
{
public function noshow(
Audition $audition,
Entry $entry
) {
$recorder = app('App\Actions\Tabulation\EnterNoShow');
try {
$msg = $recorder($entry);
} catch (AuditionAdminException $e) {
return redirect()->back()->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', [$audition])->with('success', $msg);
}
public function declineSeat(Audition $audition, Entry $entry)
{
$decider = app(DoublerDecision::class);
try {
$decider->decline($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has declined '.$audition->name);
}
public function massDecline(Audition $audition)
{
$decider = app(DoublerDecision::class);
$validData = request()->validate([
'decline-below' => ['required', 'integer', 'min:0'],
]);
$ranker = app(RankAuditionEntries::class);
// Get scored entries in order
try {
$scored_entries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$scored_entries->load(['student.doublers', 'student.school']);
foreach ($scored_entries as $entry) {
Debugbar::info('Starting entry '.$entry->student->full_name());
if ($entry->seatingRank < $validData['decline-below']) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they are ranked above decline threshold');
continue;
}
if ($entry->hasFlag('declined')) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already been declined');
continue;
}
if (! $entry->student->isDoublerInEvent($audition->event_id)) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they are not a doubler');
continue;
}
if ($entry->student->doublers->where('event_id', $audition->event_id)->first()->accepted_entry) {
Debugbar::info('Skipping '.$entry->student->full_name().' because they have already accepted a seat');
continue;
}
try {
$decider->decline($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
}
Cache::forget('rank_seating_'.$audition->id);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function acceptSeat(Audition $audition, Entry $entry)
{
$decider = app(DoublerDecision::class);
try {
$decider->accept($entry);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
return redirect()->route('seating.audition', ['audition' => $audition->id])->with('success',
$entry->student->full_name().' has accepted '.$audition->name);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace App\Http\Controllers\Tabulation\Seating;
use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Ensemble;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use function redirect;
class MakeSeatingDecisionsController extends Controller
{
public function draftSeats(
Audition $audition,
Request $request
) {
$ranker = app(RankAuditionEntries::class);
$validated = $request->validate([
'ensemble' => ['required', 'array'],
'ensemble.*' => ['required', 'integer', 'min:0'],
]);
$proposedSeatingArray = [];
try {
$rankedEntries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$rankedEntries = $rankedEntries->reject(function ($entry) {
return $entry->hasFlag('declined');
});
$rankedEntries->load(['student.school']);
$rankedEnsembles = Ensemble::orderBy('rank')->where('event_id', $audition->event_id)->get();
$ensembleRankOn = 1;
foreach ($rankedEnsembles as $ensemble) {
if (! Arr::has($validated['ensemble'], $ensemble->id)) {
continue;
}
$proposedSeatingArray[$ensembleRankOn]['ensemble_id'] = $ensemble->id;
$proposedSeatingArray[$ensembleRankOn]['ensemble_name'] = $ensemble->name;
$proposedSeatingArray[$ensembleRankOn]['accept_count'] = $validated['ensemble'][$ensemble->id];
for ($n = 1; $n <= $validated['ensemble'][$ensemble->id]; $n++) {
// Escape the loop if we're out of entries
if ($rankedEntries->isEmpty()) {
break;
}
$thisEntry = $rankedEntries->shift();
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['seat'] = $n;
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_id'] = $thisEntry->id;
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_name'] = $thisEntry->student->full_name();
$proposedSeatingArray[$ensembleRankOn]['seats'][$n]['entry_school'] = $thisEntry->student->school->name;
}
$ensembleRankOn++;
}
$sessionKeyName = 'proposedSeatingArray-'.$audition->id;
$request->session()->put($sessionKeyName, $proposedSeatingArray);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
public function clearDraft(
Audition $audition
) {
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', ['audition' => $audition->id]);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers\Tabulation\Seating;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use function redirect;
class PublishSeatingController extends Controller
{
public function publishSeats(
Audition $audition
) {
$publisher = app('App\Actions\Tabulation\PublishSeats');
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
$proposal = [];
foreach ($seatingProposal as $ensemble) {
$ensembleId = $ensemble['ensemble_id'];
if (isset($ensemble['seats'])) {
foreach ($ensemble['seats'] as $seat) {
$proposal[] = [
'ensemble_id' => $ensembleId,
'audition_id' => $audition->id,
'seat' => $seat['seat'],
'entry_id' => $seat['entry_id'],
];
}
}
}
try {
$publisher($audition, $proposal);
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', [$audition])->with('error', $e->getMessage());
}
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', [$audition]);
}
public function unpublishSeats(
Audition $audition
) {
$unpublisher = app('App\Actions\Tabulation\UnpublishSeats');
$unpublisher($audition);
session()->forget('proposedSeatingArray-'.$audition->id);
return redirect()->route('seating.audition', [$audition]);
}
}

View File

@ -0,0 +1,110 @@
<?php
namespace App\Http\Controllers\Tabulation\Seating;
use App\Actions\Tabulation\RankAuditionEntries;
use App\Exceptions\AuditionAdminException;
use App\Http\Controllers\Controller;
use App\Models\Audition;
use App\Models\Doubler;
use App\Models\Seat;
use function redirect;
class ShowAuditionSeatingPage extends Controller
{
public function __invoke(Audition $audition)
{
$seatingProposal = (session('proposedSeatingArray-'.$audition->id));
if ($audition->hasFlag('seats_published')) {
$publishedSeats = Seat::where('audition_id', $audition->id)
->join('ensembles', 'seats.ensemble_id', '=', 'ensembles.id')
->orderBy('ensembles.rank')
->orderBy('seats.seat')
->select('seats.*')
->with(['ensemble', 'student.school'])
->get();
} else {
$publishedSeats = false;
}
$ranker = app(RankAuditionEntries::class);
// Get scored entries in order
try {
$scored_entries = $ranker($audition, 'seating');
} catch (AuditionAdminException $e) {
return redirect()->route('seating.audition', ['audition' => $audition->id])
->with('error', $e->getMessage());
}
$scored_entries->load(['student.doublers', 'student.school']);
// Get unscored entries sorted by draw number
$unscored_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereDoesntHave('flags', function ($query) {
$query->where('flag_name', 'no_show');
})
->whereDoesntHave('flags', function ($query) {
$query->where('flag_name', 'failed_prelim');
})
->with('student.school')
->withCount('scoreSheets')
->orderBy('draw_number')
->get();
// Get no show entries sorted by draw number
$noshow_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereHas('flags', function ($query) {
$query->where('flag_name', 'no_show');
})
->with('student.school')
->orderBy('draw_number')
->get();
// Get failed prelim entries sorted by draw number
$failed_prelim_entries = $audition->entries()
->whereDoesntHave('totalScore')
->whereHas('flags', function ($query) {
$query->where('flag_name', 'failed_prelim');
})
->with('student.school')
->orderBy('draw_number')
->get();
// Get Doublers
$doublerData = Doubler::where('event_id', $audition->event_id)
->whereIn('student_id', $scored_entries->pluck('student_id'))
->get()
->keyBy('student_id');
$auditionHasUnresolvedDoublers = false;
foreach ($doublerData as $doubler) {
if (! is_null($doubler->accepted_entry)) {
continue;
}
foreach ($doubler->entries() as $entry) {
if ($entry->audition_id === $audition->id && $entry->hasFlag('declined')) {
continue 2;
}
}
$auditionHasUnresolvedDoublers = true;
}
$canSeat = ! $auditionHasUnresolvedDoublers && $unscored_entries->count() === 0;
return view('tabulation.seating-page.auditionSeating',
compact('audition',
'scored_entries',
'unscored_entries',
'noshow_entries',
'failed_prelim_entries',
'doublerData',
'auditionHasUnresolvedDoublers',
'canSeat',
'seatingProposal',
'publishedSeats',
)
);
}
}

View File

@ -1,55 +0,0 @@
@php($doublerButtonClasses = 'hidden rounded-md bg-white px-2.5 py-1.5 text-xs text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 sm:block')
<ul role="list" class="">
@foreach($entry['doubleData'] as $double)
@php($isopen = $double['status'] == 'undecided')
<li class="pb-2 pt-0 px-0 my-2 rounded-xl border border-gray-200 max-w-xs" x-data="{ open: {{ $isopen ? 'true':'false' }} }">
<div class="flex items-start gap-x-3 bg-gray-100 px-3 py-2 rounded-t-xl" >
<p class="text-sm font-semibold leading-6 text-gray-900">
<a href="{{ route('seating.audition', $double['audition']) }}">
{{ $double['auditionName'] }} - {{ $double['status'] }}
</a>
</p>
<div class="w-full flex justify-end" >
<div x-on:click=" open = ! open ">
<x-icons.hamburger-menu />
</div>
</div>
</div>
<div class="grid grid-cols-4" x-show="open">
<div class="mt-1 px-3 text-xs leading-5 text-gray-500 col-span-3">
<ul>
<li class="">
<p class="whitespace-nowrap">Ranked {{ $double['rank'] }}</p>
<p class="truncate">{{ $double['unscored_entries'] }} Unscored</p>
</li>
@foreach($double['seating_limits'] as $limit)
<li>{{$limit['ensemble_name']}} accepts {{ $limit['accepts'] }}</li>
@endforeach
</ul>
</div>
<div class="flex flex-col justify-end gap-y-1 pt-1">
@if ($double['status'] == 'undecided')
<form method="POST" action="{{ route('doubler.accept',['entry'=>$double['entry']]) }}">
@csrf
<button class="{{ $doublerButtonClasses }}">Accept</button>
</form>
<form method="POST" action="{{ route('doubler.decline',['entry'=>$double['entry']]) }}">
@csrf
<button class="{{ $doublerButtonClasses }}">Decline</button>
</form>
@endif
</div>
</div>
</li>
@endforeach
</ul>
{{--Complete Badge--}}
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-green-50 px-1.5 py-0.5 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Complete</p>--}}
{{--In Progres Badge--}}
{{--<p class="mt-0.5 whitespace-nowrap rounded-md bg-yellow-50 px-1.5 py-0.5 text-xs font-medium text-yellow-800 ring-1 ring-inset ring-yellow-600/20">In Progress</p>--}}

View File

@ -1,26 +0,0 @@
<x-card.card class="mb-3">
@php
@endphp
<x-card.heading>Seating</x-card.heading>
<div class="py-3 px-1">
<x-form.form method="POST" action="{{ route('seating.audition',['audition' => $audition]) }}">
@csrf
@foreach($rightPanel['data'] as $ensembleLimit)
@php
$value = $requestedEnsembleAccepts[$ensembleLimit['ensemble']->id] ?? $ensembleLimit['limit'];
// $value = $ensembleLimit['limit'];
@endphp
<x-form.field name="ensembleAccept[{{ $ensembleLimit['ensemble']->id }}]"
label_text="{{ $ensembleLimit['ensemble']->name }} - Max: {{ $ensembleLimit['limit'] }}"
type="number"
max="{{ $ensembleLimit['limit'] }}"
value="{{ $value }}"
class="mb-3"/>
@endforeach
<x-form.footer>
<x-form.button type="submit">Seat</x-form.button>
</x-form.footer>
</x-form.form>
</div>
</x-card.card>

View File

@ -1,77 +0,0 @@
<x-card.card class="px-3">
<x-table.table>
<thead>
<tr>
<x-table.th>Rank</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Draw #</x-table.th>
<x-table.th>Student Name</x-table.th>
<x-table.th>Doubler</x-table.th>
{{-- @foreach($judges as $judge)--}}
{{-- <x-table.th>{{ $judge->short_name() }}</x-table.th>--}}
{{-- @endforeach--}}
<x-table.th>Total Score
@if($audition->bonusScore()->count() > 0)
<br>
<div class="display: flex">
<x-icons.checkmark color="green"/>
Has Bonus
</div>
@endif
</x-table.th>
<x-table.th>All Scores?</x-table.th>
</tr>
</thead>
<x-table.body>
@foreach($entryData as $entry)
<tr>
<x-table.td>{{ $entry['rank'] }}</x-table.td>
<x-table.td>{{ $entry['id'] }}</x-table.td>
<x-table.td>{{ $entry['drawNumber'] }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry['studentName'] }}</span>
<span class="text-xs text-gray-400">{{ $entry['schoolName'] }}</span>
</x-table.td>
<x-table.td class="!py-0">
@if($entry['doubleData'])
@if($entry['doublerRequest'])
<p class="pt-3"><span class="font-semibold">Request: </span>{{$entry['doublerRequest']}}
</p>
@endif
@include('tabulation.auditionSeating-doubler-block-OLD')
{{-- DOUBLER<br>--}}
{{-- @foreach($entry['doubleData'] as $double)--}}
{{-- ID: {{ $double['entryId'] }} - {{ $double['name'] }} - {{ $double['rank'] }}<br>--}}
{{-- Unscored Entries: {{ $double['unscored_in_audition'] }}<br>--}}
{{-- @foreach($double['limits'] as $limit)--}}
{{-- {{$limit['ensemble']->name}}: {{ $limit['limit'] }}<br>--}}
{{-- @endforeach--}}
{{-- <hr>--}}
{{-- @endforeach--}}
@endif
{{-- @if($doublerService->studentIsDoubler($entry->student_id))--}}
{{-- @include('tabulation.auditionSeating-doubler-block')--}}
{{-- @endif--}}
</x-table.td>
<x-table.td>
<div class="display: flex">
{{ $entry['totalScore'] }}
@if($audition->bonusScore()->count() > 0 && $entry['hasBonusScores'])
<x-icons.checkmark color="green"/>
@endif
</div>
</x-table.td>
<x-table.td>
@if($entry['fullyScored'])
<x-icons.checkmark color="green"/>
@endif
</x-table.td>
</tr>
@endforeach
</x-table.body>
</x-table.table>
</x-card.card>

View File

@ -1,2 +0,0 @@
@include('tabulation.auditionSeating-fill-seats-form')
@include('tabulation.auditionSeating-show-proposed-seats')

View File

@ -1,38 +0,0 @@
@php
$seatingProposal = [];
@endphp
@foreach($rightPanel['data'] as $ensembleLimit)
<x-card.card class="mb-3">
<x-card.heading>{{ $ensembleLimit['ensemble']->name }} - DRAFT</x-card.heading>
<x-card.list.body>
@php
$maxAccepted = $requestedEnsembleAccepts[$ensembleLimit['ensemble']->id] ?? $ensembleLimit['limit'];
// $maxAccepted = $ensembleLimit['limit'];
@endphp
@for($n=1; $n <= $maxAccepted; $n++)
@php
$entry = $seatableEntries->shift();
if (is_null($entry)) continue;
$seatingProposal[] = [
'ensemble_id' => $ensembleLimit['ensemble']->id,
'audition_id' => $audition->id,
'seat' => $n,
'entry_id' => $entry->id,
];
@endphp
<x-card.list.row class="!py-2">
{{ $n }} - {{ $entry->student->full_name() }}
</x-card.list.row>
@endfor
</x-card.list.body>
</x-card.card>
@endforeach
<form method="POST" action="{{ route('seating.audition.publish',['audition' => $audition]) }}">
@csrf
<x-form.button type="submit">Seat and Publish</x-form.button>
</form>
@php
session(['audition' . $audition->id . 'seatingProposal' => $seatingProposal]);
@endphp

View File

@ -1,46 +0,0 @@
<x-card.card class="mb-3">
<x-card.heading>
Seats are Published
</x-card.heading>
<x-form.form method="POST"
action="{{ route('seating.audition.unpublish',['audition' => $audition->id]) }}"
class="mx-5 my-2">
<x-form.button type="submit">
Unpublish
</x-form.button>
</x-form.form>
</x-card.card>
<x-card.card class="mb-3">
@php
$previousEnsemble = null;
@endphp
@foreach($rightPanel['data'] as $seat)
@if($seat['ensemble'] !== $previousEnsemble)
<x-card.heading>{{$seat['ensemble']}}</x-card.heading>
@endif
<x-card.list.row class="!py-2">
{{ $seat['seat'] }} - {{ $seat['student_name'] }}
</x-card.list.row>
@php
$previousEnsemble = $seat['ensemble'];
@endphp
@endforeach
</x-card.card>
{{--@foreach($ensembleLimits as $ensembleLimit)--}}
{{-- @php--}}
{{-- $ensembleSeats = $seatingService->getSeatsForAudition($audition->id)[$ensembleLimit->ensemble->id] ?? array();--}}
{{-- @endphp--}}
{{-- <x-card.card class="mb-3">--}}
{{-- <x-card.heading>{{ $ensembleLimit->ensemble->name }}</x-card.heading>--}}
{{-- @foreach($ensembleSeats as $seat)--}}
{{-- <x-card.list.row class="!py-2">--}}
{{-- {{ $seat->seat }} - {{ $seat->student->full_name() }}--}}
{{-- </x-card.list.row>--}}
{{-- @endforeach--}}
{{-- </x-card.card>--}}
{{--@endforeach--}}

View File

@ -1,20 +0,0 @@
<x-card.card>
<x-card.heading>Unable to seat this audition</x-card.heading>
@if(! $rightPanel['data']['allScored'])
<p class="text-sm px-5 py-2">The audition cannot be seated while it has unscored entries.</p>
<div class="p-3">
<x-form.button href="{{ url()->current() }}?mass-no-show=1" class="mb-3" onclick="return confirm('Do you really want to mark unscored entries as no-shows?');">Unscored entries are No-Shows</x-form.button>
</div>
@endif
@if(! $rightPanel['data']['allScored'] && ! $rightPanel['data']['doublersResolved'])
<hr>
@endif
@if(! $rightPanel['data']['doublersResolved'])
<p class="text-sm px-5 py-2">The audition cannot be seated while it has unresolved doublers.</p>
<x-form.form method="POST" action="{{route('seating.audition',['audition' => $audition])}}">
<x-form.field name="decline-below" label_text="Decline Doublers Ranked Below" type="number" class="mb-3" />
<x-form.button class="mb-3">Decline Doublers</x-form.button>
</x-form.form>
@endif
</x-card.card>

View File

@ -1,271 +0,0 @@
<x-layout.app>
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
<div class="grid grid-cols-4 gap-4">
<div class="col-span-3"> {{-- Entry Ranking Table --}}
<x-card.card class="px-3"> {{-- Scored Entries --}}
<x-card.heading class="-ml-3">Scored Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Rank</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Draw #</x-table.th>
<x-table.th>Student</x-table.th>
<x-table.th>Doubler</x-table.th>
<x-table.th>Total Score
@if($audition->bonusScore()->count() > 0)
<br>
<div class="display: flex">
<span class="text-yellow-500">No Bonus Score</span>
</div>
@endif
</x-table.th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@foreach($scored_entries as $entry)
<tr id="entry-{{ $entry->id }}">
<x-table.td class="align-top">{{ $entry->seatingRank }}</x-table.td>
<x-table.td class="align-top">{{ $entry->id }}</x-table.td>
<x-table.td class="align-top">{{ $entry->draw_number }}</x-table.td>
<x-table.td class="align-top">
<div>
<a href="{{ route('admin.students.edit',[$entry->student_id]) }}">{{ $entry->student->full_name() }}</a>
</div>
<div class="text-xs text-gray-400">{{ $entry->student->school->name }}</div>
</x-table.td>
<x-table.td class="align-top">
@php($doubler = $doublerData->get($entry->student_id))
@if($doubler)
@if($doubler->accepted_entry == $entry->id)
ACCEPTED
@elseif($entry->hasFlag('declined'))
DECLINED
@else
@if($request = $entry->student->doublerRequests()->where('event_id',$entry->audition->event_id)->first())
<div
class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block seating request --}}
<div class="font-semibold mb-2">
Request
</div>
<div class="text-wrap">
<p>{{ $request->request }}</p>
</div>
</div>
@endif
@foreach($entry->student->entriesForEvent($entry->audition->event_id) as $de)
@include('tabulation.auditionSeating-doubler-block')
@endforeach
@endif
@endif
</x-table.td>
<x-table.td class="align-top">
@if($audition->bonusScore()->count() > 0)
@if($entry->totalScore->bonus_total)
<span>{{ $entry->totalScore->seating_total_with_bonus }}</span>
@else
<span class="text-yellow-500">{{ $entry->totalScore->seating_total_with_bonus }}</span>
@endif
@else
{{ $entry->totalScore->seating_total }}
@endif
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>
<x-card.card class="mt-3"> {{-- Unscored Entries --}}
<x-card.heading class="-ml-3">Unscored Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
<x-table.th>Judges<br>Scored</x-table.th>
<x-table.th></x-table.th>
</tr>
</thead>
<tbody>
@foreach($unscored_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
<x-table.td>
{{ $entry->score_sheets_count }}
</x-table.td>
<x-table.td>
<x-form.form method="POST"
action="{{ route('seating.audition.noshow',[$audition, $entry]) }}">
<x-form.button>Record No Show</x-form.button>
</x-form.form>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>
<x-card.card class="mt-3"> {{-- No Show Entries --}}
<x-card.heading class="-ml-3">No Show Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
</tr>
</thead>
<tbody>
@foreach($noshow_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>
<x-card.card class="mt-3"> {{-- Failed Prelim Entries --}}
<x-card.heading class="-ml-3">Failed Prelim Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
</tr>
</thead>
<tbody>
@foreach($failed_prelim_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>
</div>
<div> {{-- Right Column Wrapper --}}
@if($audition->hasFlag('seats_published'))
<x-card.card>
<x-card.heading>Published Results</x-card.heading>
<x-card.list.body>
@php($previousEnsemble = '')
@foreach($publishedSeats as $seat)
@if($previousEnsemble !== $seat->ensemble->name)
@php($previousEnsemble = $seat->ensemble->name)
<x-card.list.row class="font-semibold">{{ $seat->ensemble->name }}</x-card.list.row>
@endif
<x-card.list.row>
<div>
<p>{{ $seat->seat }}. {{ $seat->student->full_name() }}</p>
<p class="ml-5 text-xs">{{ $seat->student->school->name }}</p>
</div>
</x-card.list.row>
@endforeach
</x-card.list.body>
</x-card.card>
<x-form.form method="POST" action="{{ route('seating.audition.unpublishSeats',[$audition]) }}">
<x-form.button class="mt-3">Unpublish Results</x-form.button>
</x-form.form>
@else
@if($canSeat)
@if($seatingProposal)
<x-card.card>
<x-card.heading>
Seating Proposal
<x-slot:subheading>Results are not yet published</x-slot:subheading>
</x-card.heading>
@foreach($seatingProposal as $proposedEnsemble)
<h3 class="m-3 font-semibold">{{ $proposedEnsemble['ensemble_name'] }}</h3>
<x-card.list.body>
@if(isset($proposedEnsemble['seats']))
@foreach($proposedEnsemble['seats'] as $seat)
<x-card.list.row>{{ $seat['seat'] }}
. {{ $seat['entry_name'] }}</x-card.list.row>
@endforeach
@endif
</x-card.list.body>
@endforeach
<x-form.form method="POST" action="{{ route('seating.audition.clearDraft',[$audition]) }}">
<x-form.button class="mb-3">Clear Draft</x-form.button>
</x-form.form>
{{-- TODO Hide the publish button if there are no seats --}}
<x-form.form method="POST"
action="{{ route('seating.audition.publishSeats',[$audition]) }}">
<x-form.button class="mb-3">Publish</x-form.button>
</x-form.form>
</x-card.card>
@else
<x-card.card class="p-3">
<x-form.form metohd="POST" action="{{ route('seating.audition.draftSeats',[$audition]) }}">
<x-card.heading class="-ml-5">Seat Audition
<x-slot:subheading>Choose how many entries to seat in each ensemble
</x-slot:subheading>
</x-card.heading>
@foreach($audition->SeatingLimits()->where('maximum_accepted','>',0)->get() as $limit)
<x-form.select name="ensemble[{{ $limit->ensemble_id }}]">
<x-slot:label>{{$limit->ensemble->name}}</x-slot:label>
@for($n = 0; $n< $limit->maximum_accepted; $n++)
<option value="{{$n}}">{{$n}}</option>
@endfor
<option value="{{$n}}" SELECTED>{{$n}}</option>
</x-form.select>
@endforeach
<x-form.button class="mt-3">Draft Seats</x-form.button>
</x-form.form>
</x-card.card>
@endif
@else
<div class="ml-4">
@if($unscored_entries->count() > 0)
<x-card.card class="p-3 text-red-500 mb-3">
Cannot seat the audition while entries are unscored.
</x-card.card>
@endif
@if($auditionHasUnresolvedDoublers)
<x-card.card class="p-3">
<p class="text-red-500">Cannot seat the audition while there are unresolved doublers.</p>
<x-form.form method="POST" action="{{ route('seating.audition.mass_decline',[$audition]) }}">
<x-form.field type="number" name="decline-below" label_text="Decline doubler ranked lower than:" />
<x-form.button>Decline</x-form.button>
</x-form.form>
</x-card.card>
@endif
</div>
@endif
@endif
</div>
</div>
</x-layout.app>

View File

@ -1,30 +0,0 @@
@inject('doublerService','App\Services\DoublerService')
@php
$blockSeating = []
@endphp
<x-layout.app>
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
<div class="grid grid-cols-4"></div>
<div class="grid grid-cols-4">
<div class="col-span-3">
@include('tabulation.auditionSeating-results-table')
</div>
<div class="ml-4">
@include($rightPanel['view'])
</div>
{{-- <div class="ml-4">--}}
{{-- @if($audition->hasFlag('seats_published'))--}}
{{-- @include('tabulation.auditionSeating-show-published-seats')--}}
{{-- @elseif(! $auditionComplete)--}}
{{-- @include('tabulation.auditionSeating-unable-to-seat-card')--}}
{{-- @else--}}
{{-- @include('tabulation.auditionSeating-fill-seats-form')--}}
{{-- @include('tabulation.auditionSeating-show-proposed-seats')--}}
{{-- @endif--}}
{{-- </div>--}}
</div>
</x-layout.app>

View File

@ -0,0 +1,35 @@
<x-layout.app>
<x-slot:page_title>Audition Seating - {{ $audition->name }}</x-slot:page_title>
<div class="grid grid-cols-4 gap-4">
<div class="col-span-3"> {{-- Entry Ranking Table --}}
@include('tabulation.seating-page.scored-entries-table')
@include('tabulation.seating-page.unscored-entries-table')
@include('tabulation.seating-page.no-show-entries-table')
@include('tabulation.seating-page.failed-prelim-entries')
</div>
<div> {{-- Right Column Wrapper --}}
@if($audition->hasFlag('seats_published'))
@include('tabulation.seating-page.right-column.published-results')
@else
@if($canSeat)
@if($seatingProposal)
@include('tabulation.seating-page.right-column.unpublished-results-proposal')
@else
@include('tabulation.seating-page.right-column.form-to-propose-seats')
@endif
@else
@include('tabulation.seating-page.right-column.not-ready-to-seat')
@endif
@endif
</div>
</div>
</x-layout.app>

View File

@ -0,0 +1,24 @@
<x-card.card class="mt-3"> {{-- Failed Prelim Entries --}}
<x-card.heading class="-ml-3">Failed Prelim Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
</tr>
</thead>
<tbody>
@foreach($failed_prelim_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>

View File

@ -0,0 +1,24 @@
<x-card.card class="mt-3"> {{-- No Show Entries --}}
<x-card.heading class="-ml-3">No Show Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
</tr>
</thead>
<tbody>
@foreach($noshow_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>

View File

@ -0,0 +1,18 @@
<x-card.card class="p-3">
<x-form.form metohd="POST" action="{{ route('seating.audition.draftSeats',[$audition]) }}">
<x-card.heading class="-ml-5">Seat Audition
<x-slot:subheading>Choose how many entries to seat in each ensemble
</x-slot:subheading>
</x-card.heading>
@foreach($audition->SeatingLimits()->where('maximum_accepted','>',0)->get() as $limit)
<x-form.select name="ensemble[{{ $limit->ensemble_id }}]">
<x-slot:label>{{$limit->ensemble->name}}</x-slot:label>
@for($n = 0; $n< $limit->maximum_accepted; $n++)
<option value="{{$n}}">{{$n}}</option>
@endfor
<option value="{{$n}}" SELECTED>{{$n}}</option>
</x-form.select>
@endforeach
<x-form.button class="mt-3">Draft Seats</x-form.button>
</x-form.form>
</x-card.card>

View File

@ -0,0 +1,20 @@
<div class="ml-4">
@if($unscored_entries->count() > 0)
<x-card.card class="p-3 text-red-500 mb-3">
Cannot seat the audition while entries are unscored.
</x-card.card>
@endif
@if($auditionHasUnresolvedDoublers)
<x-card.card class="p-3">
<p class="text-red-500">Cannot seat the audition while there are unresolved
doublers.</p>
<x-form.form method="POST"
action="{{ route('seating.audition.mass_decline',[$audition]) }}">
<x-form.field type="number" name="decline-below"
label_text="Decline doubler ranked lower than:"/>
<x-form.button>Decline</x-form.button>
</x-form.form>
</x-card.card>
@endif
</div>

View File

@ -0,0 +1,22 @@
<x-card.card>
<x-card.heading>Published Results</x-card.heading>
<x-card.list.body>
@php($previousEnsemble = '')
@foreach($publishedSeats as $seat)
@if($previousEnsemble !== $seat->ensemble->name)
@php($previousEnsemble = $seat->ensemble->name)
<x-card.list.row class="font-semibold">{{ $seat->ensemble->name }}</x-card.list.row>
@endif
<x-card.list.row>
<div>
<p>{{ $seat->seat }}. {{ $seat->student->full_name() }}</p>
<p class="ml-5 text-xs">{{ $seat->student->school->name }}</p>
</div>
</x-card.list.row>
@endforeach
</x-card.list.body>
</x-card.card>
<x-form.form method="POST" action="{{ route('seating.audition.unpublishSeats',[$audition]) }}">
<x-form.button class="mt-3">Unpublish Results</x-form.button>
</x-form.form>

View File

@ -0,0 +1,25 @@
<x-card.card>
<x-card.heading>
Seating Proposal
<x-slot:subheading>Results are not yet published</x-slot:subheading>
</x-card.heading>
@foreach($seatingProposal as $proposedEnsemble)
<h3 class="m-3 font-semibold">{{ $proposedEnsemble['ensemble_name'] }}</h3>
<x-card.list.body>
@if(isset($proposedEnsemble['seats']))
@foreach($proposedEnsemble['seats'] as $seat)
<x-card.list.row>{{ $seat['seat'] }}
. {{ $seat['entry_name'] }}</x-card.list.row>
@endforeach
@endif
</x-card.list.body>
@endforeach
<x-form.form method="POST" action="{{ route('seating.audition.clearDraft',[$audition]) }}">
<x-form.button class="mb-3">Clear Draft</x-form.button>
</x-form.form>
{{-- TODO Hide the publish button if there are no seats --}}
<x-form.form method="POST"
action="{{ route('seating.audition.publishSeats',[$audition]) }}">
<x-form.button class="mb-3">Publish</x-form.button>
</x-form.form>
</x-card.card>

View File

@ -0,0 +1,78 @@
<x-card.card class="px-3"> {{-- Scored Entries --}}
<x-card.heading class="-ml-3">Scored Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Rank</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Draw #</x-table.th>
<x-table.th>Student</x-table.th>
<x-table.th>Doubler</x-table.th>
<x-table.th>Total Score
@if($audition->bonusScore()->count() > 0)
<br>
<div class="display: flex">
<span class="text-yellow-500">No Bonus Score</span>
</div>
@endif
</x-table.th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@foreach($scored_entries as $entry)
<tr id="entry-{{ $entry->id }}">
<x-table.td class="align-top">{{ $entry->seatingRank }}</x-table.td>
<x-table.td class="align-top">{{ $entry->id }}</x-table.td>
<x-table.td class="align-top">{{ $entry->draw_number }}</x-table.td>
<x-table.td class="align-top">
<div>
<a href="{{ route('admin.students.edit',[$entry->student_id]) }}">{{ $entry->student->full_name() }}</a>
</div>
<div class="text-xs text-gray-400">{{ $entry->student->school->name }}</div>
</x-table.td>
<x-table.td class="align-top">
@php($doubler = $doublerData->get($entry->student_id))
@if($doubler)
@if($doubler->accepted_entry == $entry->id)
ACCEPTED
@elseif($entry->hasFlag('declined'))
DECLINED
@else
@if($request = $entry->student->doublerRequests()->where('event_id',$entry->audition->event_id)->first())
<div
class="border-2 border-gray-200 p-2 m-2"> {{-- Begin block seating request --}}
<div class="font-semibold mb-2">
Request
</div>
<div class="text-wrap">
<p>{{ $request->request }}</p>
</div>
</div>
@endif
@foreach($entry->student->entriesForEvent($entry->audition->event_id) as $de)
@include('tabulation.seating-page.doubler-block')
@endforeach
@endif
@endif
</x-table.td>
<x-table.td class="align-top">
@if($audition->bonusScore()->count() > 0)
@if($entry->totalScore->bonus_total)
<span>{{ $entry->totalScore->seating_total_with_bonus }}</span>
@else
<span
class="text-yellow-500">{{ $entry->totalScore->seating_total_with_bonus }}</span>
@endif
@else
{{ $entry->totalScore->seating_total }}
@endif
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>

View File

@ -0,0 +1,35 @@
<x-card.card class="mt-3"> {{-- Unscored Entries --}}
<x-card.heading class="-ml-3">Unscored Entries</x-card.heading>
<x-table.table>
<thead>
<tr>
<x-table.th>Draw #</x-table.th>
<x-table.th>ID</x-table.th>
<x-table.th>Student</x-table.th>
<x-table.th>Judges<br>Scored</x-table.th>
<x-table.th></x-table.th>
</tr>
</thead>
<tbody>
@foreach($unscored_entries as $entry)
<tr>
<x-table.td>{{ $entry->draw_number }}</x-table.td>
<x-table.td>{{ $entry->id }}</x-table.td>
<x-table.td class="flex flex-col">
<span>{{ $entry->student->full_name() }}</span>
<span class="text-xs text-gray-400">{{ $entry->student->school->name }}</span>
</x-table.td>
<x-table.td>
{{ $entry->score_sheets_count }}
</x-table.td>
<x-table.td>
<x-form.form method="POST"
action="{{ route('seating.audition.noshow',[$audition, $entry]) }}">
<x-form.button>Record No Show</x-form.button>
</x-form.form>
</x-table.td>
</tr>
@endforeach
</tbody>
</x-table.table>
</x-card.card>

View File

@ -6,7 +6,10 @@ use App\Http\Controllers\Tabulation\BonusScoreController;
use App\Http\Controllers\Tabulation\DoublerDecisionController;
use App\Http\Controllers\Tabulation\EntryFlagController;
use App\Http\Controllers\Tabulation\ScoreController;
use App\Http\Controllers\Tabulation\SeatAuditionFormController;
use App\Http\Controllers\Tabulation\Seating\EnterDoublerDecisionsController;
use App\Http\Controllers\Tabulation\Seating\MakeSeatingDecisionsController;
use App\Http\Controllers\Tabulation\Seating\PublishSeatingController;
use App\Http\Controllers\Tabulation\Seating\ShowAuditionSeatingPage;
use App\Http\Controllers\Tabulation\SeatingStatusController;
use App\Http\Middleware\CheckIfCanTab;
use Illuminate\Support\Facades\Route;
@ -41,17 +44,17 @@ Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function ()
// Seating Routes
Route::prefix('seating/')->group(function () {
Route::get('/', SeatingStatusController::class)->name('seating.status');
Route::get('/{audition}', [SeatAuditionFormController::class, 'showForm'])->name('seating.audition');
Route::post('/{audition}/draftSeats', [SeatAuditionFormController::class, 'draftSeats'])->name('seating.audition.draftSeats');
Route::post('/{audition}/clearDraft', [SeatAuditionFormController::class, 'clearDraft'])->name('seating.audition.clearDraft');
Route::post('/{audition}/{entry}/decline', [SeatAuditionFormController::class, 'declineSeat'])->name('seating.audition.decline');
Route::post('/{audition}/mass_decline', [SeatAuditionFormController::class, 'massDecline'])->name('seating.audition.mass_decline');
Route::post('/{audition}/{entry}/accept', [SeatAuditionFormController::class, 'acceptSeat'])->name('seating.audition.accept');
Route::post('/{audition}/{entry}/noshow', [SeatAuditionFormController::class, 'noshow'])->name('seating.audition.noshow');
Route::get('/{audition}', ShowAuditionSeatingPage::class)->name('seating.audition');
Route::post('/{audition}/draftSeats', [MakeSeatingDecisionsController::class, 'draftSeats'])->name('seating.audition.draftSeats');
Route::post('/{audition}/clearDraft', [MakeSeatingDecisionsController::class, 'clearDraft'])->name('seating.audition.clearDraft');
Route::post('/{audition}/{entry}/decline', [EnterDoublerDecisionsController::class, 'declineSeat'])->name('seating.audition.decline');
Route::post('/{audition}/mass_decline', [EnterDoublerDecisionsController::class, 'massDecline'])->name('seating.audition.mass_decline');
Route::post('/{audition}/{entry}/accept', [EnterDoublerDecisionsController::class, 'acceptSeat'])->name('seating.audition.accept');
Route::post('/{audition}/{entry}/noshow', [EnterDoublerDecisionsController::class, 'noshow'])->name('seating.audition.noshow');
Route::post('/{audition}/publish',
[SeatAuditionFormController::class, 'publishSeats'])->name('seating.audition.publishSeats');
[PublishSeatingController::class, 'publishSeats'])->name('seating.audition.publishSeats');
Route::post('/{audition}/unpublish',
[SeatAuditionFormController::class, 'unpublishSeats'])->name('seating.audition.unpublishSeats');
[PublishSeatingController::class, 'unpublishSeats'])->name('seating.audition.unpublishSeats');
});
// Advancement Routes