Merge pull request #4 from okorpheus/ipmlement-judge-pass-fail-advancement
Implement judge pass fail advancement
This commit is contained in:
commit
0f88ae9573
|
|
@ -4,12 +4,13 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Audition;
|
use App\Models\Audition;
|
||||||
use App\Models\Entry;
|
use App\Models\Entry;
|
||||||
|
use App\Models\JudgeAdvancementVote;
|
||||||
use App\Models\ScoreSheet;
|
use App\Models\ScoreSheet;
|
||||||
use App\Models\SubscoreDefinition;
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Gate;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
|
||||||
use function compact;
|
use function compact;
|
||||||
use function redirect;
|
use function redirect;
|
||||||
use function url;
|
use function url;
|
||||||
|
|
@ -19,77 +20,109 @@ class JudgingController extends Controller
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$rooms = Auth::user()->judgingAssignments;
|
$rooms = Auth::user()->judgingAssignments;
|
||||||
|
|
||||||
return view('judging.index', compact('rooms'));
|
return view('judging.index', compact('rooms'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function auditionEntryList(Audition $audition)
|
public function auditionEntryList(Audition $audition)
|
||||||
{
|
{
|
||||||
// TODO verify user is assigned to judge this audition
|
// TODO verify user is assigned to judge this audition
|
||||||
$entries = Entry::where('audition_id','=',$audition->id)->orderBy('draw_number')->with('audition')->get();
|
$entries = Entry::where('audition_id', '=', $audition->id)->orderBy('draw_number')->with('audition')->get();
|
||||||
$subscores = $audition->scoringGuide->subscores()->orderBy('display_order')->get();
|
$subscores = $audition->scoringGuide->subscores()->orderBy('display_order')->get();
|
||||||
return view('judging.audition_entry_list', compact('audition','entries','subscores'));
|
|
||||||
|
$votes = JudgeAdvancementVote::where('user_id', Auth::id())->get();
|
||||||
|
|
||||||
|
return view('judging.audition_entry_list', compact('audition', 'entries', 'subscores', 'votes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function entryScoreSheet(Entry $entry)
|
public function entryScoreSheet(Entry $entry)
|
||||||
{
|
{
|
||||||
// TODO verify user is assigned to judge this audition
|
// TODO verify user is assigned to judge this audition
|
||||||
$oldSheet = ScoreSheet::where('user_id',Auth::id())->where('entry_id',$entry->id)->value('subscores') ?? null;
|
$oldSheet = ScoreSheet::where('user_id', Auth::id())->where('entry_id', $entry->id)->value('subscores') ?? null;
|
||||||
return view('judging.entry_score_sheet',compact('entry','oldSheet'));
|
$oldVote = JudgeAdvancementVote::where('user_id', Auth::id())->where('entry_id', $entry->id)->first();
|
||||||
|
$oldVote = $oldVote ? $oldVote->vote : 'novote';
|
||||||
|
|
||||||
|
return view('judging.entry_score_sheet', compact('entry', 'oldSheet', 'oldVote'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveScoreSheet(Request $request, Entry $entry)
|
public function saveScoreSheet(Request $request, Entry $entry)
|
||||||
{
|
{
|
||||||
Gate::authorize('create',[ScoreSheet::class,$entry]);
|
Gate::authorize('create', [ScoreSheet::class, $entry]);
|
||||||
// TODO verify user is assigned to judge this audition
|
// TODO verify user is assigned to judge this audition
|
||||||
$scoringGuide = $entry->audition->scoringGuide()->with('subscores')->first();
|
$scoringGuide = $entry->audition->scoringGuide()->with('subscores')->first();
|
||||||
$scoreValidation = $scoringGuide->validateScores($request->input('score'));
|
$scoreValidation = $scoringGuide->validateScores($request->input('score'));
|
||||||
if ($scoreValidation != 'success') {
|
if ($scoreValidation != 'success') {
|
||||||
return redirect(url()->previous())->with('error', $scoreValidation)->with('oldScores',$request->all());
|
return redirect(url()->previous())->with('error', $scoreValidation)->with('oldScores', $request->all());
|
||||||
}
|
}
|
||||||
$scoreSheetArray = [];
|
$scoreSheetArray = [];
|
||||||
foreach($scoringGuide->subscores as $subscore) {
|
foreach ($scoringGuide->subscores as $subscore) {
|
||||||
$scoreSheetArray[$subscore->id] = [
|
$scoreSheetArray[$subscore->id] = [
|
||||||
'score' => $request->input('score')[$subscore->id],
|
'score' => $request->input('score')[$subscore->id],
|
||||||
'subscore_id' => $subscore->id,
|
'subscore_id' => $subscore->id,
|
||||||
'subscore_name' => $subscore->name
|
'subscore_name' => $subscore->name,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
ScoreSheet::create([
|
ScoreSheet::create([
|
||||||
'user_id' => Auth::user()->id,
|
'user_id' => Auth::user()->id,
|
||||||
'entry_id' => $entry->id,
|
'entry_id' => $entry->id,
|
||||||
'subscores' => $scoreSheetArray
|
'subscores' => $scoreSheetArray,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect('/judging/audition/' . $entry->audition_id)->with('success','Entered scores for ' . $entry->audition->name . ' ' . $entry->draw_number);
|
$this->advancementVote($request, $entry);
|
||||||
|
|
||||||
|
return redirect('/judging/audition/'.$entry->audition_id)->with('success', 'Entered scores for '.$entry->audition->name.' '.$entry->draw_number);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateScoreSheet(Request $request, Entry $entry)
|
public function updateScoreSheet(Request $request, Entry $entry)
|
||||||
{
|
{
|
||||||
$scoreSheet = ScoreSheet::where('user_id',Auth::id())->where('entry_id',$entry->id)->first();
|
$scoreSheet = ScoreSheet::where('user_id', Auth::id())->where('entry_id', $entry->id)->first();
|
||||||
if (!$scoreSheet) return redirect()->back()->with('error','Attempt to edit non existent entry');
|
if (! $scoreSheet) {
|
||||||
Gate::authorize('update',$scoreSheet);
|
return redirect()->back()->with('error', 'Attempt to edit non existent entry');
|
||||||
|
}
|
||||||
|
Gate::authorize('update', $scoreSheet);
|
||||||
|
|
||||||
$scoringGuide = $entry->audition->scoringGuide()->with('subscores')->first();
|
$scoringGuide = $entry->audition->scoringGuide()->with('subscores')->first();
|
||||||
$scoreValidation = $scoringGuide->validateScores($request->input('score'));
|
$scoreValidation = $scoringGuide->validateScores($request->input('score'));
|
||||||
if ($scoreValidation != 'success') {
|
if ($scoreValidation != 'success') {
|
||||||
return redirect(url()->previous())->with('error', $scoreValidation)->with('oldScores',$request->all());
|
return redirect(url()->previous())->with('error', $scoreValidation)->with('oldScores', $request->all());
|
||||||
}
|
}
|
||||||
$scoreSheetArray = [];
|
$scoreSheetArray = [];
|
||||||
foreach($scoringGuide->subscores as $subscore) {
|
foreach ($scoringGuide->subscores as $subscore) {
|
||||||
$scoreSheetArray[$subscore->id] = [
|
$scoreSheetArray[$subscore->id] = [
|
||||||
'score' => $request->input('score')[$subscore->id],
|
'score' => $request->input('score')[$subscore->id],
|
||||||
'subscore_id' => $subscore->id,
|
'subscore_id' => $subscore->id,
|
||||||
'subscore_name' => $subscore->name
|
'subscore_name' => $subscore->name,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$scoreSheet->update([
|
$scoreSheet->update([
|
||||||
'subscores' => $scoreSheetArray
|
'subscores' => $scoreSheetArray,
|
||||||
]);
|
]);
|
||||||
return redirect('/judging/audition/' . $entry->audition_id)->with('success','Updated scores for ' . $entry->audition->name . ' ' . $entry->draw_number);
|
|
||||||
|
$this->advancementVote($request, $entry);
|
||||||
|
|
||||||
|
return redirect('/judging/audition/'.$entry->audition_id)->with('success', 'Updated scores for '.$entry->audition->name.' '.$entry->draw_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function advancementVote(Request $request, Entry $entry)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($entry->for_advancement and auditionSetting('advanceTo')) {
|
||||||
|
$request->validate([
|
||||||
|
'advancement-vote' => ['required', 'in:yes,no,dq'],
|
||||||
|
]);
|
||||||
|
try {
|
||||||
|
JudgeAdvancementVote::where('user_id', Auth::id())->where('entry_id', $entry->id)->delete();
|
||||||
|
JudgeAdvancementVote::create([
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
'entry_id' => $entry->id,
|
||||||
|
'vote' => $request->input('advancement-vote'),
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect(url()->previous())->with('error', 'Error saving advancement vote');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ class AdvancementController extends Controller
|
||||||
public function ranking(Request $request, Audition $audition)
|
public function ranking(Request $request, Audition $audition)
|
||||||
{
|
{
|
||||||
$entries = $this->tabulationService->auditionEntries($audition->id, 'advancement');
|
$entries = $this->tabulationService->auditionEntries($audition->id, 'advancement');
|
||||||
|
$entries->load('advancementVotes');
|
||||||
|
|
||||||
|
|
||||||
$scoringComplete = $entries->every(function ($entry) {
|
$scoringComplete = $entries->every(function ($entry) {
|
||||||
return $entry->scoring_complete;
|
return $entry->scoring_complete;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,11 @@ class Entry extends Model
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function advancementVotes(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(JudgeAdvancementVote::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function flags(): HasMany
|
public function flags(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(EntryFlag::class);
|
return $this->hasMany(EntryFlag::class);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class JudgeAdvancementVote extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
|
public function entry(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Entry::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function judge(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
@ -11,7 +10,6 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use phpDocumentor\Reflection\Types\Boolean;
|
|
||||||
|
|
||||||
class User extends Authenticatable implements MustVerifyEmail
|
class User extends Authenticatable implements MustVerifyEmail
|
||||||
{
|
{
|
||||||
|
|
@ -30,7 +28,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
'email',
|
'email',
|
||||||
'password',
|
'password',
|
||||||
'profile_image_url',
|
'profile_image_url',
|
||||||
'school_id'
|
'school_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -56,16 +54,19 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function full_name(Bool $last_name_first = false): String
|
public function full_name(bool $last_name_first = false): string
|
||||||
{
|
{
|
||||||
if ($last_name_first) return $this->last_name . ', ' . $this->first_name;
|
if ($last_name_first) {
|
||||||
return $this->first_name . ' ' . $this->last_name;
|
return $this->last_name.', '.$this->first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->first_name.' '.$this->last_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function short_name(): String
|
public function short_name(): string
|
||||||
{
|
{
|
||||||
// return the first letter of $this->first_name and the full $this->last_name
|
// return the first letter of $this->first_name and the full $this->last_name
|
||||||
return $this->first_name[0] . '. ' . $this->last_name;
|
return $this->first_name[0].'. '.$this->last_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function has_school(): bool
|
public function has_school(): bool
|
||||||
|
|
@ -76,7 +77,8 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
public function emailDomain(): string
|
public function emailDomain(): string
|
||||||
{
|
{
|
||||||
$pos = strpos($this->email, '@');
|
$pos = strpos($this->email, '@');
|
||||||
return substr($this->email, $pos+1);
|
|
||||||
|
return substr($this->email, $pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function school(): BelongsTo
|
public function school(): BelongsTo
|
||||||
|
|
@ -87,7 +89,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
public function students(): HasManyThrough
|
public function students(): HasManyThrough
|
||||||
{
|
{
|
||||||
return $this
|
return $this
|
||||||
->hasManyThrough(Student::class, School::class, 'id','school_id','school_id','id')
|
->hasManyThrough(Student::class, School::class, 'id', 'school_id', 'school_id', 'id')
|
||||||
->orderBy('last_name')
|
->orderBy('last_name')
|
||||||
->orderBy('first_name');
|
->orderBy('first_name');
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +108,7 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
|
|
||||||
public function rooms(): BelongsToMany
|
public function rooms(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Room::class,'room_user');
|
return $this->belongsToMany(Room::class, 'room_user');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function judgingAssignments(): BelongsToMany
|
public function judgingAssignments(): BelongsToMany
|
||||||
|
|
@ -114,26 +116,38 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
return $this->rooms();
|
return $this->rooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isJudge(): Bool
|
public function advancementVotes(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(JudgeAdvancementVote::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isJudge(): bool
|
||||||
{
|
{
|
||||||
return $this->judgingAssignments->count() > 0;
|
return $this->judgingAssignments->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an array of schools using the users email domain
|
* Return an array of schools using the users email domain
|
||||||
|
*
|
||||||
* @return SchoolEmailDomain[]
|
* @return SchoolEmailDomain[]
|
||||||
*/
|
*/
|
||||||
public function possibleSchools()
|
public function possibleSchools()
|
||||||
{
|
{
|
||||||
if ($this->school_id) {
|
if ($this->school_id) {
|
||||||
$return[] = $this->school;
|
$return[] = $this->school;
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
return SchoolEmailDomain::with('school')->where('domain','=',$this->emailDomain())->get();
|
|
||||||
|
return SchoolEmailDomain::with('school')->where('domain', '=', $this->emailDomain())->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canTab() {
|
public function canTab()
|
||||||
if ($this->is_admin) return true;
|
{
|
||||||
|
if ($this->is_admin) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->is_tab;
|
return $this->is_tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,12 +159,12 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||||
public function scoresForEntry($entry)
|
public function scoresForEntry($entry)
|
||||||
{
|
{
|
||||||
// TODO Again, why is this here? Needs to go somewhere else. Maybe a Judging service
|
// TODO Again, why is this here? Needs to go somewhere else. Maybe a Judging service
|
||||||
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->subscores;
|
return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->subscores;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function timeForEntryScores($entry)
|
public function timeForEntryScores($entry)
|
||||||
{
|
{
|
||||||
// TODO Why is this in the User mode? Move it somewhere else
|
// TODO Why is this in the User mode? Move it somewhere else
|
||||||
return $this->scoreSheets->where('entry_id','=',$entry)->first()?->created_at;
|
return $this->scoreSheets->where('entry_id', '=', $entry)->first()?->created_at;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('judge_advancement_votes', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignIdFor(User::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreignIdFor(Entry::class)->constrained()->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->string('vote');
|
||||||
|
$table->unique(['user_id', 'entry_id']);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('judge_advancement_votes');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@props(['color' => 'currentColor'])
|
||||||
|
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="{{ $color }}" viewBox="0 0 24 24">
|
||||||
|
<path fill-rule="evenodd" d="M8.97 14.316H5.004c-.322 0-.64-.08-.925-.232a2.022 2.022 0 0 1-.717-.645 2.108 2.108 0 0 1-.242-1.883l2.36-7.201C5.769 3.54 5.96 3 7.365 3c2.072 0 4.276.678 6.156 1.256.473.145.925.284 1.35.404h.114v9.862a25.485 25.485 0 0 0-4.238 5.514c-.197.376-.516.67-.901.83a1.74 1.74 0 0 1-1.21.048 1.79 1.79 0 0 1-.96-.757 1.867 1.867 0 0 1-.269-1.211l1.562-4.63ZM19.822 14H17V6a2 2 0 1 1 4 0v6.823c0 .65-.527 1.177-1.177 1.177Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@props(['color' => 'currentColor'])
|
||||||
|
<svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="{{ $color }}" viewBox="0 0 24 24">
|
||||||
|
<path fill-rule="evenodd" d="M15.03 9.684h3.965c.322 0 .64.08.925.232.286.153.532.374.717.645a2.109 2.109 0 0 1 .242 1.883l-2.36 7.201c-.288.814-.48 1.355-1.884 1.355-2.072 0-4.276-.677-6.157-1.256-.472-.145-.924-.284-1.348-.404h-.115V9.478a25.485 25.485 0 0 0 4.238-5.514 1.8 1.8 0 0 1 .901-.83 1.74 1.74 0 0 1 1.21-.048c.396.13.736.397.96.757.225.36.32.788.269 1.211l-1.562 4.63ZM4.177 10H7v8a2 2 0 1 1-4 0v-6.823C3 10.527 3.527 10 4.176 10Z" clip-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
@php
|
||||||
|
$classes = "pointer-events-none absolute bg-white transform -translate-y-12 z-50 p-3 max-w-sm rounded-lg shadow-lg ring-1 ring-black ring-opacity-5";
|
||||||
|
@endphp
|
||||||
|
<div {{ $attributes->merge(['class'=>$classes]) }} x-cloak
|
||||||
|
x-transition:enter="transform ease-out duration-300 transition "
|
||||||
|
x-transition:enter-start="-translate-y-12 opacity-0 sm:translate-y-0 sm:translate-x-2"
|
||||||
|
x-transition:enter-end="translate-y-0 opacity-100 sm:translate-x-0"
|
||||||
|
x-transition:leave="transition ease-in duration-100"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0">
|
||||||
|
{{ $slot }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<fieldset>
|
||||||
|
<input type="hidden" name="require-vote" value="true">
|
||||||
|
<legend class="text-sm font-semibold leading-6 text-gray-900">{{ auditionSetting('advanceTo') }} Advancement </legend>
|
||||||
|
<p class="mt-1 text-sm leading-6 text-gray-600">Only choose DQ if a rule of some kinds was broken</p>
|
||||||
|
<div class="mt-6 space-y-6 sm:flex sm:items-center sm:space-x-10 sm:space-y-0">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input id="advance-yes"
|
||||||
|
name="advancement-vote"
|
||||||
|
type="radio"
|
||||||
|
value="yes"
|
||||||
|
@if($oldVote === 'yes') checked @endif
|
||||||
|
class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||||
|
<label for="advance-yes" class="ml-3 block text-sm font-medium leading-6 text-gray-900">Yes</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input id="advance-no"
|
||||||
|
name="advancement-vote"
|
||||||
|
type="radio"
|
||||||
|
value="no"
|
||||||
|
@if($oldVote === 'no') checked @endif
|
||||||
|
class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||||
|
<label for="advance-no" class="ml-3 block text-sm font-medium leading-6 text-gray-900">No</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<input id="advance-dq"
|
||||||
|
name="advancement-vote"
|
||||||
|
type="radio"
|
||||||
|
value="dq"
|
||||||
|
@if($oldVote === 'dq') checked @endif
|
||||||
|
class="h-4 w-4 border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
||||||
|
<label for="advance-dq" class="ml-3 block text-sm font-medium leading-6 text-gray-900">DQ</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@error('advancement-vote')
|
||||||
|
<p class="text-xs text-red-500 font-semibold mt-1 ml-3">{{ $message }}</p>
|
||||||
|
@enderror
|
||||||
|
</fieldset>
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
@foreach($subscores as $subscore)
|
@foreach($subscores as $subscore)
|
||||||
<x-table.th :sortable="false">{{ $subscore->name }}</x-table.th>
|
<x-table.th :sortable="false">{{ $subscore->name }}</x-table.th>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@if(auditionSetting('advanceTo') and $audition->for_advancement)
|
||||||
|
<x-table.th>{{ auditionSetting('advanceTo') }}</x-table.th>
|
||||||
|
@endif
|
||||||
<x-table.th :sortable="true">Timestamp</x-table.th>
|
<x-table.th :sortable="true">Timestamp</x-table.th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -27,6 +30,26 @@
|
||||||
@endphp
|
@endphp
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@if(auditionSetting('advanceTo') and $audition->for_advancement)
|
||||||
|
<x-table.td>
|
||||||
|
@if($votes->contains('entry_id', $entry->id))
|
||||||
|
@php
|
||||||
|
$vote = $votes->where('entry_id',$entry->id)->first();
|
||||||
|
@endphp
|
||||||
|
@switch($vote->vote)
|
||||||
|
@case('yes')
|
||||||
|
<x-icons.thumbs-up color="green"/>
|
||||||
|
@break
|
||||||
|
@case('no')
|
||||||
|
<x-icons.thumbs-down color="red"/>
|
||||||
|
@break
|
||||||
|
@case('dq')
|
||||||
|
<x-icons.circle-slash-no color="red"/>
|
||||||
|
@break
|
||||||
|
@endswitch
|
||||||
|
@endif
|
||||||
|
</x-table.td>
|
||||||
|
@endif
|
||||||
<x-table.td>
|
<x-table.td>
|
||||||
{{ Auth::user()->timeForEntryScores($entry->id)?->setTimezone('America/Chicago')->format('m/d/y H:i') }}
|
{{ Auth::user()->timeForEntryScores($entry->id)?->setTimezone('America/Chicago')->format('m/d/y H:i') }}
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
|
{{-- TODO A user should only be able to get this form for an entry they're actually assigned to judge--}}
|
||||||
|
|
||||||
@php
|
@php
|
||||||
$oldScores = session()->get('oldScores') ?? null;
|
$oldScores = session()->get('oldScores') ?? null;
|
||||||
|
// TODO get old vote
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-slot:page_title>Entry Dashboard</x-slot:page_title>
|
<x-slot:page_title>Entry Dashboard</x-slot:page_title>
|
||||||
|
|
@ -15,7 +18,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</x-slot:subheading>
|
</x-slot:subheading>
|
||||||
</x-card.heading>
|
</x-card.heading>
|
||||||
<x-form.form metohd="POST" action="/judging/entry/{{$entry->id}}">
|
<x-form.form metohd="POST" action="{{ route('judging.saveScoreSheet',['entry' => $entry->id]) }}">
|
||||||
@if($oldSheet) {{-- if there are existing sores, make this a patch request --}}
|
@if($oldSheet) {{-- if there are existing sores, make this a patch request --}}
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -46,6 +49,10 @@
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
@if($entry->for_advancement AND auditionSetting('advanceTo'))
|
||||||
|
@include('judging.advancement-vote-form')
|
||||||
|
@endif
|
||||||
</x-card.list.body>
|
</x-card.list.body>
|
||||||
<x-form.footer><x-form.button class="mb-5">Save Scores</x-form.button></x-form.footer>
|
<x-form.footer><x-form.button class="mb-5">Save Scores</x-form.button></x-form.footer>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
<x-table.th>Student Name</x-table.th>
|
<x-table.th>Student Name</x-table.th>
|
||||||
<x-table.th>Total Score</x-table.th>
|
<x-table.th>Total Score</x-table.th>
|
||||||
<x-table.th>All Scores?</x-table.th>
|
<x-table.th>All Scores?</x-table.th>
|
||||||
|
<x-table.th>Votes</x-table.th>
|
||||||
@if($scoringComplete)
|
@if($scoringComplete)
|
||||||
<x-table.th>Pass?</x-table.th>
|
<x-table.th>Pass?</x-table.th>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -30,6 +31,29 @@
|
||||||
<x-icons.checkmark color="green"/>
|
<x-icons.checkmark color="green"/>
|
||||||
@endif
|
@endif
|
||||||
</x-table.td>
|
</x-table.td>
|
||||||
|
<x-table.td class="flex space-x-1">
|
||||||
|
@foreach($entry->advancementVotes as $vote)
|
||||||
|
<div x-data="{ showJudgeName: false, timeout: null }"
|
||||||
|
x-on:mouseover="clearTimeout(timeout); timeout = setTimeout(() => showJudgeName = true, 300)"
|
||||||
|
x-on:mouseleave="clearTimeout(timeout); showJudgeName = false">
|
||||||
|
|
||||||
|
<x-tooltip x-show="showJudgeName">
|
||||||
|
{{ $vote->judge->full_name() }}
|
||||||
|
</x-tooltip>
|
||||||
|
@switch($vote->vote)
|
||||||
|
@case('yes')
|
||||||
|
<x-icons.thumbs-up color="green"/>
|
||||||
|
@break
|
||||||
|
@case('no')
|
||||||
|
<x-icons.thumbs-down color="red"/>
|
||||||
|
@break
|
||||||
|
@case('dq')
|
||||||
|
<x-icons.circle-slash-no color="red"/>
|
||||||
|
@break
|
||||||
|
@endswitch
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</x-table.td>
|
||||||
@if( $audition->hasFlag('advancement_published') )
|
@if( $audition->hasFlag('advancement_published') )
|
||||||
<x-table.td>
|
<x-table.td>
|
||||||
@if($entry->hasFlag('will_advance'))
|
@if($entry->hasFlag('will_advance'))
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ use App\Http\Middleware\CheckIfCanJudge;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging')->controller(JudgingController::class)->group(function () {
|
Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging')->controller(JudgingController::class)->group(function () {
|
||||||
Route::get('/', 'index');
|
Route::get('/', 'index')->name('judging.index');
|
||||||
Route::get('/audition/{audition}', 'auditionEntryList');
|
Route::get('/audition/{audition}', 'auditionEntryList')->name('judging.auditionEntryList');
|
||||||
Route::get('/entry/{entry}', 'entryScoreSheet');
|
Route::get('/entry/{entry}', 'entryScoreSheet')->name('judging.entryScoreSheet');
|
||||||
Route::post('/entry/{entry}', 'saveScoreSheet');
|
Route::post('/entry/{entry}', 'saveScoreSheet')->name('judging.saveScoreSheet');
|
||||||
Route::patch('/entry/{entry}', 'updateScoreSheet');
|
Route::patch('/entry/{entry}', 'updateScoreSheet')->name('judging.updateScoreSheet');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue