Entries listing page nearly complete
This commit is contained in:
parent
a452234c44
commit
7edf166985
|
|
@ -3,8 +3,14 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class EntryController extends Controller
|
||||
{
|
||||
//
|
||||
// TODO authorization policies
|
||||
public function index()
|
||||
{
|
||||
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
||||
return view('entries.index',['entries' => $entries]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class StudentController extends Controller
|
|||
*/
|
||||
public function index()
|
||||
{
|
||||
$students = Auth::user()->students;
|
||||
$students = Auth::user()->students()->with('entries')->get();
|
||||
return view('students.index',['students' => $students]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Models;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
|
||||
class School extends Model
|
||||
{
|
||||
|
|
@ -36,4 +37,10 @@ class School extends Model
|
|||
{
|
||||
return $this->hasMany(Student::class);
|
||||
}
|
||||
|
||||
public function entries(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(Entry::class,Student::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Models;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
|
||||
|
||||
|
|
@ -22,6 +23,11 @@ class Student extends Model
|
|||
return $this->hasManyThrough(User::class, School::class);
|
||||
}
|
||||
|
||||
public function entries(): HasMany
|
||||
{
|
||||
return $this->hasMany(Entry::class);
|
||||
}
|
||||
|
||||
public function full_name(Bool $last_name_first = false): String
|
||||
{
|
||||
if ($last_name_first) return $this->last_name . ', ' . $this->first_name;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,17 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||
->orderBy('first_name');
|
||||
}
|
||||
|
||||
public function entries(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(
|
||||
Entry::class,
|
||||
Student::class,
|
||||
'school_id',
|
||||
'student_id',
|
||||
'school_id',
|
||||
'id'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of schools using the users email domain
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Policies;
|
|||
use App\Models\Entry;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use function is_null;
|
||||
|
||||
class EntryPolicy
|
||||
{
|
||||
|
|
@ -21,7 +22,8 @@ class EntryPolicy
|
|||
*/
|
||||
public function view(User $user, Entry $entry): bool
|
||||
{
|
||||
//
|
||||
if($user->is_admin) return true;
|
||||
return $user->school_id == $entry->student()->school_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -29,7 +31,8 @@ class EntryPolicy
|
|||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
if($user->is_admin) return true;
|
||||
return ! is_null($user->school_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,7 +40,8 @@ class EntryPolicy
|
|||
*/
|
||||
public function update(User $user, Entry $entry): bool
|
||||
{
|
||||
//
|
||||
if($user->is_admin) return true;
|
||||
return $user->school_id == $entry->student()->school_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,7 +49,8 @@ class EntryPolicy
|
|||
*/
|
||||
public function delete(User $user, Entry $entry): bool
|
||||
{
|
||||
//
|
||||
if($user->is_admin) return true;
|
||||
return $user->school_id == $entry->student()->school_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ class EntryFactory extends Factory
|
|||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
'student_id' => 3,
|
||||
'audition_id' =>3
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ return new class extends Migration
|
|||
$table->id();
|
||||
$table->foreignIdFor(Student::class)->constrained()->restrictOnDelete()->cascadeOnUpdate();
|
||||
$table->foreignIdFor(Audition::class)->constrained()->restrictOnDelete()->cascadeOnUpdate();
|
||||
$table->unique(['student_id','audition_id']);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,13 @@
|
|||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Audition;
|
||||
use App\Models\Entry;
|
||||
use App\Models\Student;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
use function rand;
|
||||
use function random_int;
|
||||
|
||||
class EntrySeeder extends Seeder
|
||||
{
|
||||
|
|
@ -12,6 +17,47 @@ class EntrySeeder extends Seeder
|
|||
*/
|
||||
public function run(): void
|
||||
{
|
||||
//
|
||||
$students = Student::all();
|
||||
$hs_auditions = Audition::where('maximum_grade', '=', '12');
|
||||
$freshman_auditions = Audition::where('maximum_grade', '>', '8');
|
||||
$jh_auditions = Audition::where('maximum_grade', '=', '9');
|
||||
$seventh_auditions = Audition::where('maximum_grade', '=', '7');
|
||||
|
||||
|
||||
foreach ($students as $student) {
|
||||
if($student->grade > 9) $audition = Audition::where('maximum_grade','=','12')->inRandomOrder()->first();
|
||||
if($student->grade == 9) $audition = Audition::where('maximum_grade','>','8')->inRandomOrder()->first();
|
||||
if($student->grade == 8) $audition = Audition::where('maximum_grade','=','9')->inRandomOrder()->first();
|
||||
if($student->grade == 7) $audition = Audition::where('maximum_grade','=','7')->inRandomOrder()->first();
|
||||
|
||||
Entry::factory()->create([
|
||||
'student_id' => $student->id,
|
||||
'audition_id' => $audition->id
|
||||
]);
|
||||
|
||||
if (random_int(1,100) > 80) {
|
||||
if($student->grade > 9) $audition2 = Audition::where('maximum_grade','=','12')->where('id','!=',$audition->id)->inRandomOrder()->first();
|
||||
if($student->grade == 9) $audition2 = Audition::where('maximum_grade','>','8')->where('id','!=',$audition->id)->inRandomOrder()->first();
|
||||
if($student->grade == 8) $audition2 = Audition::where('maximum_grade','=','9')->where('id','!=',$audition->id)->inRandomOrder()->first();
|
||||
if($student->grade == 7) $audition2 = Audition::where('maximum_grade','=','7')->where('id','!=',$audition->id)->inRandomOrder()->first();
|
||||
|
||||
Entry::factory()->create([
|
||||
'student_id' => $student->id,
|
||||
'audition_id' => $audition2->id
|
||||
]);
|
||||
}
|
||||
|
||||
if (random_int(1,100) > 80) {
|
||||
if($student->grade > 9) $audition3 = Audition::where('maximum_grade','=','12')->where('id','!=',$audition->id)->where('id','!=',$audition2->id)->inRandomOrder()->first();
|
||||
if($student->grade == 9) $audition3 = Audition::where('maximum_grade','>','8')->where('id','!=',$audition->id)->where('id','!=',$audition2->id)->inRandomOrder()->first();
|
||||
if($student->grade == 8) $audition3 = Audition::where('maximum_grade','=','9')->where('id','!=',$audition->id)->where('id','!=',$audition2->id)->inRandomOrder()->first();
|
||||
if($student->grade == 7) $audition3 = Audition::where('maximum_grade','=','7')->where('id','!=',$audition->id)->where('id','!=',$audition2->id)->inRandomOrder()->first();
|
||||
|
||||
Entry::factory()->create([
|
||||
'student_id' => $student->id,
|
||||
'audition_id' => $audition3->id
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
@php use Illuminate\Support\Facades\Auth; @endphp
|
||||
@push('scripts')
|
||||
{{-- Code from https://codepen.io/ryangjchandler/pen/WNQQKeR--}}
|
||||
<script src="{{ asset('js/sort_table_by_column.js') }}"></script>
|
||||
@endpush
|
||||
<x-layout.app>
|
||||
<x-slot:page_title>Entries</x-slot:page_title>
|
||||
|
||||
<x-layout.page-section-container>
|
||||
<x-layout.page-section>
|
||||
<x-slot:section_name>Add Entry</x-slot:section_name>
|
||||
<x-form.form method="POST" action="/students">
|
||||
<x-form.body-grid columns="8" class="max-w-full">
|
||||
<x-form.field name="first_name" label_text="First Name" colspan="3" />
|
||||
<x-form.field name="last_name" label_text="Last Name" colspan="3" />
|
||||
<x-form.field name="grade" label_text="Grade" colspan="1" />
|
||||
{{-- TODO make grade a dropdown --}}
|
||||
<x-form.button class="mt-6">Save</x-form.button>
|
||||
</x-form.body-grid>
|
||||
</x-form.form>
|
||||
</x-layout.page-section>
|
||||
|
||||
|
||||
<x-layout.page-section>
|
||||
<x-slot:section_name>Entry Listing</x-slot:section_name>
|
||||
<div class="px-4">
|
||||
<x-table.table>
|
||||
<thead>
|
||||
<tr>
|
||||
<x-table.th first>Name</x-table.th>
|
||||
<x-table.th>Grade</x-table.th>
|
||||
<x-table.th>Audition</x-table.th>
|
||||
<x-table.th spacer_only>
|
||||
<span class="sr-only">Edit</span>
|
||||
</x-table.th>
|
||||
</tr>
|
||||
</thead>
|
||||
<x-table.body>
|
||||
@foreach($entries as $entry)
|
||||
<tr>
|
||||
<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->audition->name }}</x-table.td>
|
||||
{{-- <x-table.td for_button>--}}
|
||||
{{-- <x-table.button href="/students/{{ $student->id }}/edit">Edit</x-table.button>--}}
|
||||
{{-- |--}}
|
||||
|
||||
{{-- <form method="POST" action="/students/{{ $student->id }}" class="inline">--}}
|
||||
{{-- @csrf--}}
|
||||
{{-- @method('DELETE')--}}
|
||||
{{-- <x-table.button--}}
|
||||
{{-- onclick="return confirm('Please confirm you would like to delete the student {{ $student->full_name() }}');"--}}
|
||||
{{-- >Delete</x-table.button>--}}
|
||||
{{-- </form>--}}
|
||||
|
||||
{{-- </x-table.td>--}}
|
||||
</tr>
|
||||
@endforeach
|
||||
</x-table.body>
|
||||
</x-table.table>
|
||||
</div>
|
||||
</x-layout.page-section>
|
||||
</x-layout.page-section-container>
|
||||
</x-layout.app>
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
<tr>
|
||||
<x-table.th first>Name</x-table.th>
|
||||
<x-table.th>Grade</x-table.th>
|
||||
<x-table.th>Entries</x-table.th>
|
||||
<x-table.th spacer_only>
|
||||
<span class="sr-only">Edit</span>
|
||||
</x-table.th>
|
||||
|
|
@ -39,6 +40,7 @@
|
|||
<tr>
|
||||
<x-table.td first>{{ $student->full_name(true) }}</x-table.td>
|
||||
<x-table.td>{{ $student->grade }}</x-table.td>
|
||||
<x-table.td>{{ $student->entries->count() }}</x-table.td>
|
||||
<x-table.td for_button>
|
||||
<x-table.button href="/students/{{ $student->id }}/edit">Edit</x-table.button>
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,49 +1,14 @@
|
|||
@php use App\Models\School;use App\Models\SchoolEmailDomain;use App\Models\User;use Illuminate\Support\Facades\Auth; @endphp
|
||||
<x-layout.app>
|
||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||
@php
|
||||
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
||||
// dd($entries->first()->student->full_name())
|
||||
@endphp
|
||||
|
||||
<x-card.card class="px-4 pt-6" mw="3xl">
|
||||
<x-table.table with_title_area with_button>
|
||||
<x-slot:title>Users</x-slot:title>
|
||||
<x-slot:subtitle>A list of all the users in your account including their name, title, email and role.</x-slot:subtitle>
|
||||
<x-slot:title_block_right><x-form.button>Add User</x-form.button></x-slot:title_block_right>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<x-table.th first>Name</x-table.th>
|
||||
<x-table.th>Title</x-table.th>
|
||||
<x-table.th>Email</x-table.th>
|
||||
<x-table.th>Role</x-table.th>
|
||||
<x-table.th spacer_only>
|
||||
<span class="sr-only">Edit</span>
|
||||
</x-table.th>
|
||||
</tr>
|
||||
</thead>
|
||||
<x-table.body>
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">Lindsay Walton</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">Front-end Developer</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">lindsay.walton@example.com</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">Member</td>
|
||||
<td class="relative whitespace-nowrap py-4 px-3 text-right text-sm sm:pr-0">
|
||||
<a href="#" class="text-indigo-600 hover:text-indigo-900 font-medium">Edit<span class="sr-only">, Lindsay Walton</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<x-table.td first emphasis>Lindsay Walton</x-table.td>
|
||||
<x-table.td>Front-end Developer</x-table.td>
|
||||
<x-table.td>lindsay.walton@example.com</x-table.td>
|
||||
<x-table.td>Member</x-table.td>
|
||||
<x-table.td for_button>
|
||||
<x-table.button href="#" aria_data=", Lindsay Walton">Edit</x-table.button>
|
||||
</x-table.td>
|
||||
</tr>
|
||||
|
||||
<!-- More people... -->
|
||||
</x-table.body>
|
||||
</x-table.table>
|
||||
</x-card.card>
|
||||
@foreach ($entries as $e)
|
||||
{{ $e->student->full_name() }} is entered on {{ $e->audition->name }}<br/>
|
||||
@endforeach
|
||||
|
||||
|
||||
</x-layout.app>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Controllers\DashboardController;
|
||||
use App\Http\Controllers\EntryController;
|
||||
use App\Http\Controllers\SchoolController;
|
||||
use App\Http\Controllers\StudentController;
|
||||
use App\Http\Controllers\UserController;
|
||||
|
|
@ -19,7 +20,15 @@ Route::middleware(['auth','verified'])->group(function () {
|
|||
});
|
||||
|
||||
// Entry Related Routes
|
||||
|
||||
Route::middleware(['auth','verified'])->controller(EntryController::class)->group(function() {
|
||||
Route::get('/entries','index');
|
||||
Route::get('/entries/create','create');
|
||||
Route::get('/entries/{entry}', 'show');
|
||||
Route::post('/entries', 'store');
|
||||
Route::get('/entries/{entry}/edit', 'edit');
|
||||
Route::patch('/entries/{entry}', 'update');
|
||||
Route::delete('/entries/{entry}', 'destroy');
|
||||
});
|
||||
|
||||
// User Related Routes
|
||||
Route::middleware(['auth','verified'])->controller(UserController::class)->group(function() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue