User side entry process complete
This commit is contained in:
parent
83e9c8fbd5
commit
695a0130c0
|
|
@ -4,12 +4,15 @@ namespace App\Actions\Fortify;
|
|||
|
||||
use A6digital\Image\DefaultProfileImage;
|
||||
use App\Models\User;
|
||||
use App\Rules\ValidRegistrationCode;
|
||||
use App\Settings;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Laravel\Fortify\Contracts\CreatesNewUsers;
|
||||
use function mb_substr;
|
||||
use function sendMessage;
|
||||
|
||||
class CreateNewUser implements CreatesNewUsers
|
||||
{
|
||||
|
|
@ -22,7 +25,9 @@ class CreateNewUser implements CreatesNewUsers
|
|||
*/
|
||||
public function create(array $input): User
|
||||
{
|
||||
|
||||
Validator::make($input, [
|
||||
'registration_code' => [new ValidRegistrationCode],
|
||||
'first_name' => ['required', 'string', 'max:255'],
|
||||
'last_name' => ['required', 'string', 'max:255'],
|
||||
'judging_preference' => ['required', 'string', 'max:255'],
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use function dd;
|
||||
use function redirect;
|
||||
|
||||
class DashboardController extends Controller
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class EntryController extends Controller
|
|||
{
|
||||
|
||||
$entries = Auth::user()->entries()->with(['student','audition'])->get();
|
||||
$auditions = Audition::all();
|
||||
$auditions = Audition::deadlineNotPast();
|
||||
$students = Auth::user()->students;
|
||||
|
||||
return view('entries.index',['entries' => $entries, 'students' => $students, 'auditions' => $auditions]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Settings;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class LoadAuditionSettings
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
Settings::loadSettings();
|
||||
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,4 +15,9 @@ class Audition extends Model
|
|||
{
|
||||
return $this->belongsTo(Event::class);
|
||||
}
|
||||
|
||||
public static function deadlineNotPast()
|
||||
{
|
||||
return Audition::where('entry_deadline', '>=', now())->get();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use App\Settings;
|
||||
use Closure;
|
||||
use Hamcrest\Core\Set;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
class ValidRegistrationCode implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
if ($value !== Settings::get('registrationCode')) {
|
||||
$fail('Incorrect registration code provided');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Middleware\LoadAuditionSettings;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
|
|
@ -11,6 +12,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||
health: '/up',
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
$middleware->append(LoadAuditionSettings::class);
|
||||
$middleware->redirectUsersTo('/dashboard');
|
||||
$middleware->redirectGuestsTo('/');
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</div>
|
||||
<form class="space-y-6" action="/forgot-password" method="POST">
|
||||
@csrf
|
||||
<x-form.field name="email" label="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="email" label_text="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.button>Send Password Reset</x-form.button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<div class="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
||||
<form class="space-y-6" action="/login" method="POST">
|
||||
@csrf
|
||||
<x-form.field name="email" label="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="password" label="Password" type="password" required />
|
||||
<x-form.field name="email" label_text="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="password" label_text="Password" type="password" required />
|
||||
<x-auth.rememberme-forgotpassword />
|
||||
<x-form.button>Log In</x-form.button>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
@php use App\Settings; @endphp
|
||||
<x-layout.guest>
|
||||
<x-slot:heading>Create an Account</x-slot:heading>
|
||||
<x-slot:heading>{{ Settings::get('auditionAbbreviation') }} - Create an Account</x-slot:heading>
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px]">
|
||||
<div class="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
||||
<form class="space-y-6" action="/register" method="POST">
|
||||
@csrf
|
||||
<x-form.field name="first_name" label="First Name" type="text" autocomplete="given-name" required />
|
||||
<x-form.field name="last_name" label="Last Name" type="text" autocomplete="family-name" required />
|
||||
<x-form.field name="email" label="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="cell_phone" label="Cell Phone Number" type="tel" autocomplete="tel-national" />
|
||||
<x-form.field name="judging_preference" label="Judging Preference" type="text" />
|
||||
<x-form.field name="password" label="Password" type="password" autocomplete="new-password" required />
|
||||
<x-form.field name="password_confirmation" label="Confirm Password" autocomplete="new-password" type="password" required />
|
||||
<x-form.field name="registration_code" label_text="Registration Code" type="text" required />
|
||||
<x-form.field name="first_name" label_text="First Name" type="text" autocomplete="given-name" required />
|
||||
<x-form.field name="last_name" label_text="Last Name" type="text" autocomplete="family-name" required />
|
||||
<x-form.field name="email" label_text="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="cell_phone" label_text="Cell Phone Number" type="tel" autocomplete="tel-national" />
|
||||
<x-form.field name="judging_preference" label_text="Judging Preference" type="text" />
|
||||
<x-form.field name="password" label_text="Password" type="password" autocomplete="new-password" required />
|
||||
<x-form.field name="password_confirmation" label_text="Confirm Password" autocomplete="new-password" type="password" required />
|
||||
<x-form.button>Create Account</x-form.button>
|
||||
</form>
|
||||
<div class="pt-4 border-t border-gray-900/10 mt-4">
|
||||
Already have an account? <a href="/login" class="font-semibold text-indigo-600 hover:text-indigo-500"> Click here to Log In.
|
||||
Already have an account? <a href="/login" class="font-semibold text-indigo-600 hover:text-indigo-500"> Click here to Log In.</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
<div class="bg-white px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
||||
<form class="space-y-6" action="/reset-password" method="POST">
|
||||
@csrf
|
||||
<x-form.field name="email" label="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="password" label="Password" type="password" required />
|
||||
<x-form.field name="password_confirmation" label="Confirm Password" type="password" required />
|
||||
<x-form.field name="email" label_text="Email address" type="email" autocomplete="email" required />
|
||||
<x-form.field name="password" label_text="Password" type="password" required />
|
||||
<x-form.field name="password_confirmation" label_text="Confirm Password" type="password" required />
|
||||
<input type="hidden" name="token" id="token" value="{{ request()->route('token') }}" >
|
||||
<x-form.button>Reset Password</x-form.button>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -38,4 +38,7 @@
|
|||
<label for="{{ $name }}" class="{{ $label_classes }}">{{ $label_text }}</label>
|
||||
@endif
|
||||
<input {{ $attributes->merge($inputAttributes) }}>
|
||||
@error($name)
|
||||
<p class="text-xs text-red-500 font-semibold mt-1 ml-3">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
'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',
|
||||
'class' => '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
|
||||
]
|
||||
|
|
|
|||
|
|
@ -35,6 +35,13 @@
|
|||
</x-card.list.row>
|
||||
</form>
|
||||
@endforeach
|
||||
<x-card.list.row>
|
||||
<x-card.list.row-text-subtext>
|
||||
Create new school
|
||||
<x-slot:subtext>My school isn't listed</x-slot:subtext>
|
||||
</x-card.list.row-text-subtext>
|
||||
<x-slot:right_link_button href="/schools/create">Create new school</x-slot:right_link_button>
|
||||
</x-card.list.row>
|
||||
</x-card.list.body>
|
||||
</x-card.card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
<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>
|
||||
{{-- TODO block deletion of entries past the deadline--}}
|
||||
<x-table.td for_button>
|
||||
<form method="POST" action="/entries/{{ $entry->id }}" class="inline">
|
||||
@csrf
|
||||
|
|
|
|||
|
|
@ -1,24 +1,56 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Create School</x-slot:page_title>
|
||||
<div class="space-y-10 divide-y divide-gray-900/10">
|
||||
<x-layout.page-section
|
||||
section_name="School Information"
|
||||
section_description=""
|
||||
:first="true">
|
||||
|
||||
<x-form.card
|
||||
submit-button-text="Create School"
|
||||
method="POST"
|
||||
action="/schools"
|
||||
cols="9"
|
||||
>
|
||||
<x-form.field name="name" label="School Name" div_classes="sm:col-span-6"/>
|
||||
<x-form.field name="address" label="School Address" div_classes="sm:col-span-6"/>
|
||||
<x-form.field name="city" label="City" div_classes="sm:col-span-3"/>
|
||||
<x-form.field name="state" label="State" div_classes="sm:col-span-2"/>
|
||||
<x-form.field name="zip" label="Zip" div_classes="sm:col-span-1"/>
|
||||
</x-form.card>
|
||||
<x-card.card class="mx-auto max-w-lg">
|
||||
<x-card.heading>
|
||||
New School
|
||||
</x-card.heading>
|
||||
<x-form.form method="POST" action="/schools" class="-mt-5">
|
||||
<x-form.body-grid columns="6" class="max-w-full">
|
||||
<x-form.field name="name" label_text="School Name" colspan="6"/>
|
||||
<x-form.field name="address" label_text="School Address" colspan="6"/>
|
||||
<x-form.field name="city" label_text="City" colspan="3"/>
|
||||
<x-form.field name="state" label_text="State" colspan="2"/>
|
||||
<x-form.field name="zip" label_text="Zip"/>
|
||||
</x-form.body-grid>
|
||||
<x-form.footer submit-button-text="Create School"/>
|
||||
</x-form.form>
|
||||
</x-card.card>
|
||||
{{-- <x-slot:page_title>Create School</x-slot:page_title>--}}
|
||||
{{-- <div class="space-y-10 divide-y divide-gray-900/10">--}}
|
||||
{{-- <x-layout.page-section :first="true">--}}
|
||||
{{-- <x-slot:section_name>School Information</x-slot:section_name>--}}
|
||||
{{-- <x-form.form method="POST" action="/schools">--}}
|
||||
{{-- <x-form.body-grid columns="6" class="max-w-full">--}}
|
||||
{{-- <x-form.field name="name" label_text="School Name" colspan="6"/>--}}
|
||||
{{-- <x-form.field name="address" label_text="School Address" colspan="6"/>--}}
|
||||
{{-- <x-form.field name="city" label_text="City" colspan="3"/>--}}
|
||||
{{-- <x-form.field name="state" label_text="State" colspan="2"/>--}}
|
||||
{{-- <x-form.field name="zip" label_text="Zip"/>--}}
|
||||
{{-- </x-form.body-grid>--}}
|
||||
{{-- </x-form.form>--}}
|
||||
|
||||
</x-layout.page-section>
|
||||
</div>
|
||||
{{-- </x-layout.page-section>--}}
|
||||
|
||||
|
||||
{{-- <x-layout.page-section--}}
|
||||
{{-- :first="true">--}}
|
||||
|
||||
{{-- <x-slot:section_name>School Information</x-slot:section_name>--}}
|
||||
|
||||
|
||||
{{-- <x-form.card--}}
|
||||
{{-- submit-button-text="Create School"--}}
|
||||
{{-- method="POST"--}}
|
||||
{{-- action="/schools"--}}
|
||||
{{-- cols="9"--}}
|
||||
{{-- >--}}
|
||||
{{-- <x-form.field name="name" label_text="School Name" div_classes="sm:col-span-6"/>--}}
|
||||
{{-- <x-form.field name="address" label_text="School Address" div_classes="sm:col-span-6"/>--}}
|
||||
{{-- <x-form.field name="city" label_text="City" div_classes="sm:col-span-3"/>--}}
|
||||
{{-- <x-form.field name="state" label_text="State" div_classes="sm:col-span-2"/>--}}
|
||||
{{-- <x-form.field name="zip" label_text="Zip" div_classes="sm:col-span-1"/>--}}
|
||||
{{-- </x-form.card>--}}
|
||||
|
||||
{{-- </x-layout.page-section>--}}
|
||||
{{-- </div>--}}
|
||||
</x-layout.app>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@php use Illuminate\Support\Facades\Auth; @endphp
|
||||
@php use App\Models\Audition;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>
|
||||
|
|
@ -13,8 +13,17 @@
|
|||
<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.field name="grade" label_text="Grade" colspan="1" />--}}
|
||||
|
||||
<x-form.select name="grade">
|
||||
<x-slot:label>Grade</x-slot:label>
|
||||
@php($n = Audition::min('minimum_grade'))
|
||||
@php($maxGrade = Audition::max('maximum_grade'))
|
||||
@while($n <= $maxGrade)
|
||||
<option value="{{ $n }}">{{ $n }}</option>
|
||||
@php($n++);
|
||||
@endwhile
|
||||
</x-form.select>
|
||||
<x-form.button class="mt-6">Save</x-form.button>
|
||||
</x-form.body-grid>
|
||||
</x-form.form>
|
||||
|
|
@ -42,16 +51,17 @@
|
|||
<x-table.td>{{ $student->grade }}</x-table.td>
|
||||
<x-table.td>{{ $student->entries->count() }}</x-table.td>
|
||||
<x-table.td for_button>
|
||||
@can('delete', $student)
|
||||
@if( $student->entries->count() > 0)
|
||||
<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>
|
||||
>Delete
|
||||
</x-table.button>
|
||||
</form>
|
||||
|
|
||||
@endcan
|
||||
@endif
|
||||
<x-table.button href="/students/{{ $student->id }}/edit">Edit</x-table.button>
|
||||
</x-table.td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
<x-layout.app>
|
||||
<x-slot:page_title>Test Page</x-slot:page_title>
|
||||
|
||||
@php( Settings::set('auditionName','Somewhere Band Directors Association'))
|
||||
@php( Settings::set('auditionAbbreviation','SBDA'))
|
||||
{{ Audition::max('maximum_grade') }} is the oldest grade used. <br>
|
||||
{{ Audition::min('minimum_grade') }} is the youngest grade.
|
||||
|
||||
{{ Settings::get('auditionName') }}
|
||||
|
||||
</x-layout.app>
|
||||
d
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Route::middleware(['auth','verified'])->group(function () {
|
|||
});
|
||||
|
||||
// Entry Related Routes
|
||||
Route::middleware(['auth','verified'])->controller(EntryController::class)->group(function() {
|
||||
Route::middleware(['auth','verified','can:create,App\Models\Entry'])->controller(EntryController::class)->group(function() {
|
||||
Route::get('/entries','index');
|
||||
Route::get('/entries/create','create');
|
||||
Route::post('/entries', 'store');
|
||||
|
|
@ -35,7 +35,7 @@ Route::middleware(['auth','verified'])->controller(UserController::class)->group
|
|||
});
|
||||
|
||||
// Student Related Routes
|
||||
Route::middleware(['auth','verified'])->controller(StudentController::class)->group(function() {
|
||||
Route::middleware(['auth','verified','can:create,App\Models\Student'])->controller(StudentController::class)->group(function() {
|
||||
Route::get('/students','index');
|
||||
Route::post('students', 'store');
|
||||
Route::get('/students/{student}/edit','edit');
|
||||
|
|
|
|||
Loading…
Reference in New Issue