Editing and deleting students working

This commit is contained in:
Matt Young 2024-05-30 19:01:25 -05:00
parent b324ebd763
commit 7791e88ee1
15 changed files with 160 additions and 111 deletions

View File

@ -2,10 +2,13 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\School;
use App\Models\Student; use App\Models\Student;
use App\Models\User; use App\Models\User;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use function abort;
use function redirect;
class StudentController extends Controller class StudentController extends Controller
{ {
@ -54,16 +57,31 @@ class StudentController extends Controller
/** /**
* Update the specified resource in storage. * Update the specified resource in storage.
*/ */
public function update(Request $request, User $user) public function update(Request $request, Student $student)
{ {
// if ($request->user()->cannot('update', $student)) abort(403);
request()->validate([
'first_name' => ['required'],
'last_name' => ['required'],
'grade' => ['required', 'integer'],
]);
$student->update([
'first_name' => request('first_name'),
'last_name' => request('last_name'),
'grade' => request('grade')
]);
return redirect('/students');
} }
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
*/ */
public function destroy(User $user) public function destroy(Request $request, Student $student)
{ {
// if ($request->user()->cannot('delete', $student)) abort(403);
$student->delete();
return redirect('/students');
} }
} }

View File

@ -7,10 +7,11 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasManyThrough;
class Student extends Model class Student extends Model
{ {
use HasFactory; use HasFactory;
protected $guarded = [];
public function school(): BelongsTo public function school(): BelongsTo
{ {
return $this->belongsTo(School::class); return $this->belongsTo(School::class);

View File

@ -53,7 +53,7 @@ class StudentPolicy
*/ */
public function delete(User $user, Student $student): bool public function delete(User $user, Student $student): bool
{ {
// return $user->school_id == $student->school_id;
} }
/** /**

21
app/helpers.php Normal file
View File

@ -0,0 +1,21 @@
<?php
function tw_max_width_class_array() :Array {
$return = [
"xs" => "max-w-xs",
'sm' => 'max-w-sm',
'md' => 'max-w-md',
'lg' => 'max-w-lg',
'xl' => 'max-w-xl',
'2xl' => 'max-w-2xl',
'3xl' => 'max-w-3xl',
'4xl' => 'max-w-4xl',
'5xl' => 'max-w-5xl',
'6xl' => 'max-w-6xl',
'7xl' => 'max-w-7xl',
'full' => 'max-w-full',
'fit' => 'max-w-fit',
'min' => 'max-w-min',
'max' => 'max-w-max',
];
return $return;
}

View File

@ -22,6 +22,9 @@
"spatie/laravel-ignition": "^2.4" "spatie/laravel-ignition": "^2.4"
}, },
"autoload": { "autoload": {
"files": [
"app/helpers.php"
],
"psr-4": { "psr-4": {
"App\\": "app/", "App\\": "app/",
"Database\\Factories\\": "database/factories/", "Database\\Factories\\": "database/factories/",

View File

@ -1,13 +1,6 @@
@props(['mw' => false])
@php @php
$wrapper_classes = 'overflow-hidden bg-white shadow sm:rounded-lg'; $wrapper_classes = 'overflow-hidden bg-white shadow sm:rounded-lg';
if ($mw) {
$wrapper_classes .= ' mx-auto max-w-' . $mw;
}
@endphp @endphp
<div {{ $attributes->merge(['class' => $wrapper_classes]) }}> <div {{ $attributes->merge(['class' => $wrapper_classes]) }}>
{{ $slot }} {{ $slot }}
</div> </div>

View File

@ -37,7 +37,5 @@
@elseif($label_text) @elseif($label_text)
<label for="{{ $name }}" class="{{ $label_classes }}">{{ $label_text }}</label> <label for="{{ $name }}" class="{{ $label_classes }}">{{ $label_text }}</label>
@endif @endif
<div class="mt-2"> <input {{ $attributes->merge($inputAttributes) }}>
<input {{ $attributes->merge($inputAttributes) }}>
</div>
</div> </div>

View File

@ -4,36 +4,38 @@
<x-slot:page_title>Choose School</x-slot:page_title> <x-slot:page_title>Choose School</x-slot:page_title>
{{-- <x-card.card class="mx-auto max-w-xl">--}} {{-- <x-card.card class="mx-auto max-w-xl">--}}
<x-card.card mw="[32rem]"> <div class="mx-auto max-w-lg">
<x-card.heading class=""> <x-card.card>
Choose your school <x-card.heading class="">
<x-slot:subheading> Choose your school
Based on your email address, one of these schools may be yours <x-slot:subheading>
</x-slot:subheading> Based on your email address, one of these schools may be yours
</x-card.heading> </x-slot:subheading>
</x-card.heading>
<x-card.list.body> <x-card.list.body>
@foreach($possibilities as $possibility) @foreach($possibilities as $possibility)
@php $school = $possibility->school; @endphp @php $school = $possibility->school; @endphp
<form method="POST" action="/users/{{ Auth::user()->id }}/set_school"> <form method="POST" action="/users/{{ Auth::user()->id }}/set_school">
@csrf @csrf
@method('PATCH') @method('PATCH')
<input type="hidden" name="school_id" id="school_id" value="{{ $school->id }}"> <input type="hidden" name="school_id" id="school_id" value="{{ $school->id }}">
<x-card.list.row right_link_button_type="button"> <x-card.list.row right_link_button_type="button">
<x-card.list.row-image <x-card.list.row-image
src="{{ $school->initialLetterImageURL() }}" src="{{ $school->initialLetterImageURL() }}"
alt=""/> alt=""/>
<x-card.list.row-text-subtext> <x-card.list.row-text-subtext>
{{ $school->name }} {{ $school->name }}
<x-slot:subtext>{{ $school->city }}, {{ $school->state }}</x-slot:subtext> <x-slot:subtext>{{ $school->city }}, {{ $school->state }}</x-slot:subtext>
</x-card.list.row-text-subtext> </x-card.list.row-text-subtext>
<x-slot:right_link_button <x-slot:right_link_button
onclick="return confirm('Please confirm you are a director at {{ $school->name }}');" onclick="return confirm('Please confirm you are a director at {{ $school->name }}');"
>Choose</x-slot:right_link_button> >Choose</x-slot:right_link_button>
</x-card.list.row> </x-card.list.row>
</form> </form>
@endforeach @endforeach
</x-card.list.body> </x-card.list.body>
</x-card.card> </x-card.card>
</div>
</x-layout.app> </x-layout.app>

View File

@ -1,20 +1,22 @@
<x-layout.app> <x-layout.app>
<x-card.card mw="xl"> <div class="mx-auto max-w-lg">
<x-card.heading> <x-card.card>
Edit School <x-card.heading>
</x-card.heading> Edit School
</x-card.heading>
<x-form.form method="PATCH" action="/schools/{{ $school->id }}"> <x-form.form method="PATCH" action="/schools/{{ $school->id }}">
<x-form.body-grid columns="7"> <x-form.body-grid columns="7">
<x-form.field name="name" type="text" colspan="7" label_text="School Name" value="{{ $school->name }}" /> <x-form.field name="name" type="text" colspan="7" label_text="School Name" value="{{ $school->name }}" />
<x-form.field name="address" type="text" colspan="7" label_text="School Address" value="{{ $school->address }}" /> <x-form.field name="address" type="text" colspan="7" label_text="School Address" value="{{ $school->address }}" />
<x-form.field name="city" type="text" colspan="4" label_text="City" value="{{ $school->city }}" /> <x-form.field name="city" type="text" colspan="4" label_text="City" value="{{ $school->city }}" />
<x-form.field name="state" type="text" colspan="1" label_text="State" value="{{ $school->state }}" /> <x-form.field name="state" type="text" colspan="1" label_text="State" value="{{ $school->state }}" />
<x-form.field name="zip" type="text" colspan="2" label_text="Zip" value="{{ $school->zip }}" /> <x-form.field name="zip" type="text" colspan="2" label_text="Zip" value="{{ $school->zip }}" />
</x-form.body-grid> </x-form.body-grid>
<x-form.footer submit-button-text="Edit School" /> <x-form.footer submit-button-text="Edit School" />
</x-form.form> </x-form.form>
</x-card.card> </x-card.card>
</div>
</x-layout.app> </x-layout.app>
{{--<x-layout.app> {{--<x-layout.app>

View File

@ -1,37 +1,39 @@
<x-layout.app> <x-layout.app>
<x-slot:page_title>School Info - {{ $school->name }}</x-slot:page_title> <x-slot:page_title>School Info - {{ $school->name }}</x-slot:page_title>
<x-card.card mw="xl"> <div class="mx-auto max-w-xl">
<x-card.info.body> <x-card.card>
<x-card.info.row row_name="School Address"> <x-card.info.body>
<div class="md:grid md:grid-cols-3"> <x-card.info.row row_name="School Address">
<div class="md:col-span-2"> <div class="md:grid md:grid-cols-3">
{{ $school->name }}<br /> <div class="md:col-span-2">
{{ $school->address }}<br /> {{ $school->name }}<br />
{{ $school->city }}, {{ $school->state }} {{ $school->zip }} {{ $school->address }}<br />
{{ $school->city }}, {{ $school->state }} {{ $school->zip }}
</div>
<div class="text-indigo-600">
<a href="/schools/{{$school->id}}/edit"> [ Edit School ] </a>
</div>
</div> </div>
<div class="text-indigo-600"> </x-card.info.row>
<a href="/schools/{{$school->id}}/edit"> [ Edit School ] </a>
</div>
</div>
</x-card.info.row>
<x-card.info.row row_name="Directors"> <x-card.info.row row_name="Directors">
<ul> <ul>
@foreach($school->directors as $director) @foreach($school->directors as $director)
<li>{{ $director->full_name() }} - <a class='text-indigo-600' href="mailto:{{ $director->email }}">{{ $director->email }}</a></li> <li>{{ $director->full_name() }} - <a class='text-indigo-600' href="mailto:{{ $director->email }}">{{ $director->email }}</a></li>
@endforeach @endforeach
</ul> </ul>
</x-card.info.row> </x-card.info.row>
<x-card.info.row row_name="Associated Email Domains"> <x-card.info.row row_name="Associated Email Domains">
<ul> <ul>
@foreach($school->emailDomains as $domain) @foreach($school->emailDomains as $domain)
<li>{{ $domain->domain }}</li> <li>{{ $domain->domain }}</li>
@endforeach @endforeach
</ul> </ul>
</x-card.info.row> </x-card.info.row>
</x-card.info.body> </x-card.info.body>
</x-card.card> </x-card.card>
</div>
</x-layout.app> </x-layout.app>

View File

@ -1,5 +1,14 @@
<x-layout.app> <x-layout.app>
<x-card.card mw="xl"> <div class="mx-auto max-w-lg">
boo <x-card.card>
</x-card.card> <x-card.heading>Edit Student</x-card.heading>
<x-form.form method="PATCH" class="!pt-2 !pb-6 !space-y-2" action="/students/{{ $student->id }}">
<x-form.field name="first_name" label_text="First Name" type="text" value="{{ $student->first_name }}"/>
<x-form.field name="last_name" label_text="Last Name" type="text" value="{{ $student->last_name }}"/>
<x-form.field name="grade" label_text="Grade" type="number" class="mb-3" value="{{ $student->grade }}"/>
<x-form.footer submit-button-text="Save Changes" />
</x-form.form>
</x-card.card>
</div>
</x-layout.app> </x-layout.app>

View File

@ -11,11 +11,11 @@
<x-slot:section_name>Add Student</x-slot:section_name> <x-slot:section_name>Add Student</x-slot:section_name>
<x-form.form method="POST" action="/students"> <x-form.form method="POST" action="/students">
<x-form.body-grid columns="8" class="max-w-full"> <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="first_name" label_text="First Name" colspan="3" />
<x-form.field name="last_name" label_text="Last 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" /> <x-form.field name="grade" label_text="Grade" colspan="1" />
{{-- TODO make grade a dropdown --}} {{-- TODO make grade a dropdown --}}
<x-form.button class="mt-8">Save</x-form.button> <x-form.button class="mt-6">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,6 +41,16 @@
<x-table.td>{{ $student->grade }}</x-table.td> <x-table.td>{{ $student->grade }}</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">
@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> </x-table.td>
</tr> </tr>
@endforeach @endforeach
@ -50,18 +60,3 @@
</x-layout.page-section> </x-layout.page-section>
</x-layout.page-section-container> </x-layout.page-section-container>
</x-layout.app> </x-layout.app>
{{--<x-layout.app>--}}
{{-- <x-slot:page_title>Students</x-slot:page_title>--}}
{{-- <x-layout.page-section>--}}
{{-- <x-slot:section_name>Create Student</x-slot:section_name>--}}
{{-- <x-slot:section_description>Student full names must be unique. Add a middle initial to the first name if necessary.</x-slot:section_description>--}}
{{-- <x-form.card method="POST" action="/students/create" submit-button-text="Create Student" >--}}
{{-- <x-form.field name="first_name" label="First Name" div_classes="sm:col-span-3" required />--}}
{{-- <x-form.field name="last_name" label="Last Name" div_classes="sm:col-span-3" required />--}}
{{-- </x-form.card>--}}
{{-- </x-layout.page-section>--}}
{{--</x-layout.app>--}}

View File

@ -2,7 +2,7 @@
<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>
<x-card.card class="px-4 pt-6"> <x-card.card class="px-4 pt-6" mw="3xl">
<x-table.table with_title_area with_button> <x-table.table with_title_area with_button>
<x-slot:title>Users</x-slot:title> <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:subtitle>A list of all the users in your account including their name, title, email and role.</x-slot:subtitle>

View File

@ -28,6 +28,8 @@ Route::middleware(['auth','verified'])->controller(UserController::class)->group
Route::middleware(['auth','verified'])->controller(StudentController::class)->group(function() { Route::middleware(['auth','verified'])->controller(StudentController::class)->group(function() {
Route::get('/students','index'); Route::get('/students','index');
Route::get('/students/{student}/edit','edit'); Route::get('/students/{student}/edit','edit');
Route::patch('/students/{student}','update');
Route::delete('/students/{student}', 'destroy');
}); });

View File

@ -5,6 +5,9 @@ export default {
"./resources/**/*.js", "./resources/**/*.js",
"./resources/**/*.vue", "./resources/**/*.vue",
], ],
safelist: [
{ pattern: /max-w-(xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl)/ },
],
theme: { theme: {
extend: {}, extend: {},
}, },