Adding entry complete
This commit is contained in:
parent
7edf166985
commit
9f57c930fc
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
|
use App\Models\Entry;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
|
@ -11,6 +13,25 @@ class EntryController extends Controller
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
||||||
return view('entries.index',['entries' => $entries]);
|
$auditions = Audition::all();
|
||||||
|
$students = Auth::user()->students;
|
||||||
|
|
||||||
|
return view('entries.index',['entries' => $entries, 'students' => $students, 'auditions' => $auditions]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
// TODO write custom rule to verify the combination of student and audition is unique
|
||||||
|
$request->validate([
|
||||||
|
'student_id' => ['required', 'exists:students,id'],
|
||||||
|
'audition_id' => ['required', 'exists:auditions,id']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$entry = Entry::create([
|
||||||
|
'student_id' => request('student_id'),
|
||||||
|
'audition_id' => request('audition_id')
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect('/entries');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Audition;
|
||||||
use App\Models\School;
|
use App\Models\School;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
@ -20,7 +21,8 @@ class StudentController extends Controller
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$students = Auth::user()->students()->with('entries')->get();
|
$students = Auth::user()->students()->with('entries')->get();
|
||||||
return view('students.index',['students' => $students]);
|
$auditions = Audition::all();
|
||||||
|
return view('students.index',['students' => $students, 'auditions' => $auditions]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
class Entry extends Model
|
class Entry extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
protected $guarded = [];
|
||||||
|
|
||||||
public function student(): BelongsTo
|
public function student(): BelongsTo
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Policies;
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\Entry;
|
||||||
use App\Models\Student;
|
use App\Models\Student;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Auth\Access\Response;
|
use Illuminate\Auth\Access\Response;
|
||||||
|
|
@ -9,15 +10,6 @@ use function is_null;
|
||||||
|
|
||||||
class StudentPolicy
|
class StudentPolicy
|
||||||
{
|
{
|
||||||
// TODO Blanket admin policy is not appropriate for students as it may break things in the audition process
|
|
||||||
/**
|
|
||||||
* Grant admin users access to all functions
|
|
||||||
*/
|
|
||||||
public function before(User $user, string $ability): bool|null
|
|
||||||
{
|
|
||||||
if($user->is_admin) return true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the user can view any models.
|
* Determine whether the user can view any models.
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,6 +31,7 @@ class StudentPolicy
|
||||||
*/
|
*/
|
||||||
public function create(User $user): bool
|
public function create(User $user): bool
|
||||||
{
|
{
|
||||||
|
if($user->is_admin) return true;
|
||||||
return ! is_null($user->school_id);
|
return ! is_null($user->school_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,6 +40,8 @@ class StudentPolicy
|
||||||
*/
|
*/
|
||||||
public function update(User $user, Student $student): bool
|
public function update(User $user, Student $student): bool
|
||||||
{
|
{
|
||||||
|
if (Entry::where('student_id','=',$student->id)->exists()) return false; // Don't allow deletion of a student with entries
|
||||||
|
if($user->is_admin) return true;
|
||||||
return $user->school_id == $student->school_id;
|
return $user->school_id == $student->school_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
@props([
|
||||||
|
'label' => false,
|
||||||
|
'name',
|
||||||
|
'colspan' => '1'
|
||||||
|
])
|
||||||
|
@php
|
||||||
|
$colspan_classes = [
|
||||||
|
'1' => '',
|
||||||
|
'2' => 'sm:col-span-2',
|
||||||
|
'3' => 'sm:col-span-3',
|
||||||
|
'4' => 'sm:col-span-4',
|
||||||
|
'5' => 'sm:col-span-5',
|
||||||
|
'6' => 'sm:col-span-6',
|
||||||
|
'7' => 'sm:col-span-7',
|
||||||
|
'8' => 'sm:col-span-8',
|
||||||
|
'9' => 'sm:col-span-9',
|
||||||
|
'10' => 'sm:col-span-10',
|
||||||
|
'11' => 'sm:col-span-11',
|
||||||
|
'12' => 'sm:col-span-12'
|
||||||
|
];
|
||||||
|
$label_attribs = [
|
||||||
|
'class' => 'block text-sm font-medium leading-6 text-gray-900',
|
||||||
|
'for' => $name
|
||||||
|
];
|
||||||
|
$select_attribs = [
|
||||||
|
'class' => 'mt-2 block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-indigo-600 sm:text-sm sm:leading-6',
|
||||||
|
'id' => $name,
|
||||||
|
'name' => $name
|
||||||
|
]
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<div @if($colspan > 1) class="{{ $colspan_classes["$colspan"] }}" @endif>
|
||||||
|
@if($label)<label {{ $label->attributes->merge($label_attribs) }}>{{ $label }}</label>@endif
|
||||||
|
<select {{ $attributes->merge($select_attribs) }}>
|
||||||
|
{{ $slot }}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
@ -9,13 +9,27 @@
|
||||||
<x-layout.page-section-container>
|
<x-layout.page-section-container>
|
||||||
<x-layout.page-section>
|
<x-layout.page-section>
|
||||||
<x-slot:section_name>Add Entry</x-slot:section_name>
|
<x-slot:section_name>Add Entry</x-slot:section_name>
|
||||||
<x-form.form method="POST" action="/students">
|
<x-form.form method="POST" action="/entries">
|
||||||
<x-form.body-grid columns="8" class="max-w-full">
|
|
||||||
<x-form.field name="first_name" label_text="First Name" colspan="3" />
|
<x-form.body-grid columns="7" class="max-w-full" x-data="studentAuditionFilter()">
|
||||||
<x-form.field name="last_name" label_text="Last Name" colspan="3" />
|
|
||||||
<x-form.field name="grade" label_text="Grade" colspan="1" />
|
<x-form.select name="student_id" colspan="3" x-model="selectedStudentId" @change="filterAuditions">
|
||||||
{{-- TODO make grade a dropdown --}}
|
<x-slot:label>Student</x-slot:label>
|
||||||
<x-form.button class="mt-6">Save</x-form.button>
|
<option value="" disabled selected>Select a student</option>
|
||||||
|
<template x-for="student in students" :key="student.id">
|
||||||
|
<option :value="student.id" x-text="student.name"></option>
|
||||||
|
</template>
|
||||||
|
</x-form.select>
|
||||||
|
|
||||||
|
<x-form.select name="audition_id" colspan="3">
|
||||||
|
<x-slot:label>Audition</x-slot:label>
|
||||||
|
<option value="" disabled selected>Select an audition</option>
|
||||||
|
<template x-for="audition in filteredAuditions" :key="audition.id">
|
||||||
|
<option :value="audition.id" x-text="audition.name"></option>
|
||||||
|
</template>
|
||||||
|
</x-form.select>
|
||||||
|
|
||||||
|
<x-form.button class="mt-8">Save</x-form.button>
|
||||||
</x-form.body-grid>
|
</x-form.body-grid>
|
||||||
</x-form.form>
|
</x-form.form>
|
||||||
</x-layout.page-section>
|
</x-layout.page-section>
|
||||||
|
|
@ -41,19 +55,19 @@
|
||||||
<x-table.td first>{{ $entry->student->full_name(true) }}</x-table.td>
|
<x-table.td first>{{ $entry->student->full_name(true) }}</x-table.td>
|
||||||
<x-table.td>{{ $entry->student->grade }}</x-table.td>
|
<x-table.td>{{ $entry->student->grade }}</x-table.td>
|
||||||
<x-table.td>{{ $entry->audition->name }}</x-table.td>
|
<x-table.td>{{ $entry->audition->name }}</x-table.td>
|
||||||
{{-- <x-table.td for_button>--}}
|
{{-- <x-table.td for_button>--}}
|
||||||
{{-- <x-table.button href="/students/{{ $student->id }}/edit">Edit</x-table.button>--}}
|
{{-- <x-table.button href="/students/{{ $student->id }}/edit">Edit</x-table.button>--}}
|
||||||
{{-- |--}}
|
{{-- |--}}
|
||||||
|
|
||||||
{{-- <form method="POST" action="/students/{{ $student->id }}" class="inline">--}}
|
{{-- <form method="POST" action="/students/{{ $student->id }}" class="inline">--}}
|
||||||
{{-- @csrf--}}
|
{{-- @csrf--}}
|
||||||
{{-- @method('DELETE')--}}
|
{{-- @method('DELETE')--}}
|
||||||
{{-- <x-table.button--}}
|
{{-- <x-table.button--}}
|
||||||
{{-- onclick="return confirm('Please confirm you would like to delete the student {{ $student->full_name() }}');"--}}
|
{{-- onclick="return confirm('Please confirm you would like to delete the student {{ $student->full_name() }}');"--}}
|
||||||
{{-- >Delete</x-table.button>--}}
|
{{-- >Delete</x-table.button>--}}
|
||||||
{{-- </form>--}}
|
{{-- </form>--}}
|
||||||
|
|
||||||
{{-- </x-table.td>--}}
|
{{-- </x-table.td>--}}
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-table.body>
|
</x-table.body>
|
||||||
|
|
@ -61,4 +75,5 @@
|
||||||
</div>
|
</div>
|
||||||
</x-layout.page-section>
|
</x-layout.page-section>
|
||||||
</x-layout.page-section-container>
|
</x-layout.page-section-container>
|
||||||
|
@include('students.student_audition_select_script')
|
||||||
</x-layout.app>
|
</x-layout.app>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
<script>
|
||||||
|
function studentAuditionFilter() {
|
||||||
|
return {
|
||||||
|
selectedStudentId: '',
|
||||||
|
students: [
|
||||||
|
|
||||||
|
@foreach($students as $student)
|
||||||
|
{ id: {{ $student->id }}, name: '{{ $student->full_name() }}', grade: {{ $student->grade }} },
|
||||||
|
@endforeach
|
||||||
|
],
|
||||||
|
auditions: [
|
||||||
|
@foreach($auditions as $audition)
|
||||||
|
{ id: {{ $audition->id }}, name: '{{ $audition->name }}', minGrade: {{ $audition->minimum_grade }}, maxGrade: {{ $audition->maximum_grade }} },
|
||||||
|
@endforeach
|
||||||
|
],
|
||||||
|
filteredAuditions: [],
|
||||||
|
filterAuditions() {
|
||||||
|
const selectedStudent = this.students.find(student => student.id == this.selectedStudentId);
|
||||||
|
if (selectedStudent) {
|
||||||
|
const grade = selectedStudent.grade;
|
||||||
|
this.filteredAuditions = this.auditions.filter(audition => {
|
||||||
|
return grade >= audition.minGrade && grade <= audition.maxGrade;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.filteredAuditions = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
@php use App\Models\School;use App\Models\SchoolEmailDomain;use App\Models\User;use Illuminate\Support\Facades\Auth; @endphp
|
@php use App\Models\Audition;use App\Models\School;use App\Models\SchoolEmailDomain;use App\Models\User;use Illuminate\Support\Facades\Auth; @endphp
|
||||||
<x-layout.app>
|
<x-layout.app>
|
||||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||||
|
|
||||||
@php
|
@php
|
||||||
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
|
||||||
// dd($entries->first()->student->full_name())
|
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
@foreach ($entries as $e)
|
|
||||||
{{ $e->student->full_name() }} is entered on {{ $e->audition->name }}<br/>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
|
|
||||||
</x-layout.app>
|
</x-layout.app>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue