diff --git a/app/Http/Controllers/Admin/AuditionSettings.php b/app/Http/Controllers/Admin/AuditionSettings.php new file mode 100644 index 0000000..8481279 --- /dev/null +++ b/app/Http/Controllers/Admin/AuditionSettings.php @@ -0,0 +1,34 @@ +validate([ + 'auditionName' => ['required'], + 'auditionAbbreviation' => ['required', 'max:8'], + 'organizerName' => ['required'], + 'organizerEmail' => ['required', 'email'], + 'registrationCode' => ['required'], + 'late_fee' => ['nullable', 'numeric'], + 'school_fee' => ['nullable', 'numeric'], + ]); + // TODO implement olympic scoring + foreach ($validData as $key => $value) { + Settings::set($key, $value); + } + + return view('admin.audition-settings')->with('success', 'Settings Saved'); + } +} diff --git a/app/Http/Controllers/Admin/EventController.php b/app/Http/Controllers/Admin/EventController.php index e75f1df..42a28f2 100644 --- a/app/Http/Controllers/Admin/EventController.php +++ b/app/Http/Controllers/Admin/EventController.php @@ -6,19 +6,24 @@ use App\Http\Controllers\Controller; use App\Models\Event; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; + use function abort; use function compact; class EventController extends Controller { - public function index() { + public function index() + { $events = Event::all(); - return view('admin.event.index',compact('events')); + + return view('admin.event.index', compact('events')); } public function store(Request $request) { - if(! Auth::user()->is_admin) abort(403); + if (! Auth::user()->is_admin) { + abort(403); + } request()->validate([ 'name' => ['required', 'unique:events,name'], ]); @@ -27,13 +32,16 @@ class EventController extends Controller 'name' => request('name'), ]); - return redirect()->route('admin.events.index')->with('success','Event created successfully'); + return redirect()->route('admin.events.index')->with('success', 'Event created successfully'); } public function destroy(Request $request, Event $event) { - if(! Auth::user()->is_admin) abort(403); + if (! Auth::user()->is_admin) { + abort(403); + } $event->delete(); - return redirect()->route('admin.events.index')->with('success','Event deleted successfully'); + + return redirect()->route('admin.events.index')->with('success', 'Event deleted successfully'); } } diff --git a/app/helpers.php b/app/helpers.php index 050f508..ef50236 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,7 @@ + Audition Settings + + + + + Group Information + + + + + + + + + + Registration Settings + If students cannot advance to further honor groups, leave next event name blank + + + + + + + + Scoring Settings + If students cannot advance to further honor groups, leave next event name blank + +
+ Enable score entry by judges +
+
+ Olympic scoring +
+
+
+ + + Financial Settings + If students cannot advance to further honor groups, leave next event name blank + + + + Fee Structure + + + + + + + + + + +
+
+ Save Settings +
+
+
+
+ diff --git a/resources/views/components/layout/navbar/menus/setup.blade.php b/resources/views/components/layout/navbar/menus/setup.blade.php index 9b2f1d1..d4f51c8 100644 --- a/resources/views/components/layout/navbar/menus/setup.blade.php +++ b/resources/views/components/layout/navbar/menus/setup.blade.php @@ -21,6 +21,7 @@ {{-- TODO convert to named routes --}}
+ Audition Settings Events Auditions Ensembles diff --git a/resources/views/dashboard/profile.blade.php b/resources/views/dashboard/profile.blade.php index 7a0de19..0512bea 100644 --- a/resources/views/dashboard/profile.blade.php +++ b/resources/views/dashboard/profile.blade.php @@ -5,7 +5,7 @@ User Information Use a permanent address where you receive mail - + diff --git a/resources/views/test.blade.php b/resources/views/test.blade.php index e4ea0d8..cf848a5 100644 --- a/resources/views/test.blade.php +++ b/resources/views/test.blade.php @@ -16,7 +16,7 @@ Test Page @php - dump($auditionService->getPublishedAuditions()); + dump(auditionSetting('auditionName')); @endphp diff --git a/routes/admin.php b/routes/admin.php new file mode 100644 index 0000000..9e5f9f8 --- /dev/null +++ b/routes/admin.php @@ -0,0 +1,112 @@ +prefix('admin/')->group(function () { + Route::view('/', 'admin.dashboard'); + + Route::post('/auditions/roomUpdate', [\App\Http\Controllers\Admin\AuditionController::class, 'roomUpdate']); // Endpoint for JS assigning auditions to rooms + Route::post('/scoring/assign_guide_to_audition', [\App\Http\Controllers\Admin\AuditionController::class, 'scoringGuideUpdate']); // Endpoint for JS assigning scoring guides to auditions + + Route::get('/settings', [\App\Http\Controllers\Admin\AuditionSettings::class, 'index'])->name('audition-settings'); + Route::post('/settings', [\App\Http\Controllers\Admin\AuditionSettings::class, 'save'])->name('audition-settings-save'); + + // Admin Ensemble Routes + Route::prefix('ensembles')->controller(\App\Http\Controllers\Admin\EnsembleController::class)->group(function () { + Route::get('/', 'index')->name('admin.ensembles.index'); + Route::post('/', 'store')->name('admin.ensembles.store'); + Route::delete('/{ensemble}', 'destroy')->name('admin.ensembles.destroy'); + Route::post('/updateEnsembleRank', 'updateEnsembleRank')->name('admin.ensembles.updateEnsembleRank'); + Route::patch('/{ensemble}', 'updateEnsemble')->name('admin.ensembles.updateEnsemble'); + Route::get('/seating-limits', 'seatingLimits')->name('admin.ensembles.seatingLimits'); + Route::get('/seating-limits/{ensemble}', 'seatingLimits')->name('admin.ensembles.seatingLimits.ensemble'); + Route::post('/seating-limits/{ensemble}', 'seatingLimitsSet')->name('admin.ensembles.seatingLimits.ensemble.set'); + }); + + // Admin Event Routes + Route::prefix('events')->controller(\App\Http\Controllers\Admin\EventController::class)->group(function () { + Route::get('/', 'index')->name('admin.events.index'); + Route::post('/', 'store')->name('admin.events.store'); + Route::delete('/{event}', 'destroy')->name('admin.events.destroy'); + }); + + // Admin Rooms Routes + Route::prefix('rooms')->controller(\App\Http\Controllers\Admin\RoomController::class)->group(function () { + Route::get('/', 'index')->name('admin.rooms.index'); + Route::get('/create', 'create')->name('admin.rooms.create'); + Route::post('/', 'store')->name('admin.rooms.store'); + Route::post('/{room}/edit', 'edit')->name('admin.rooms.edit'); + Route::patch('/{room}', 'update')->name('admin.rooms.update'); + Route::delete('/{room}', 'destroy')->name('admin.rooms.destroy'); + Route::get('/judging_assignments', 'judgingAssignment')->name('admin.rooms.judgingAssignment'); // Screen to assign judges to rooms + Route::match(['post', 'delete'], '/{room}/judge', 'updateJudgeAssignment')->name('admin.rooms.updateJudgeAssignment'); + + }); + + // Admin Scoring Guides + Route::prefix('scoring')->controller(\App\Http\Controllers\Admin\ScoringGuideController::class)->group(function () { + Route::get('/', 'index')->name('admin.scoring.index'); // Scoring Setup Homepage + Route::post('/guides', 'store')->name('admin.scoring.store'); // Save a new scoring guide + Route::get('/guides/{guide}/edit', 'edit')->name('admin.scoring.edit'); // Edit scoring guide + Route::patch('/guides/{guide}/edit', 'update')->name('admin.scoring.update'); // Save changes to audition guide (rename) + Route::post('/guides/{guide}/subscore', 'subscore_store')->name('admin.scoring.subscore_store'); // Save a new subscore + Route::post('/reorder-display', 'reorder_display')->name('admin.scoring.reorder_display'); + Route::post('/reorder-tiebreak', 'reorder_tiebreak')->name('admin.scoring.reorder_tiebreak'); + }); + + // Admin Auditions Routes + Route::prefix('auditions')->controller(\App\Http\Controllers\Admin\AuditionController::class)->group(function () { + Route::get('/', 'index')->name('admin.auditions.index'); + Route::get('/create', 'create')->name('admin.auditions.create'); + Route::post('/', 'store')->name('admin.auditions.store'); + Route::get('/{audition}/edit', 'edit')->name('admin.auditions.edit'); + Route::patch('/{audition}', 'update')->name('admin.auditions.update'); + Route::post('/reorder', 'reorder')->name('admin.auditions.reorder'); + Route::delete('/{audition}', 'destroy')->name('admin.auditions.destroy'); + Route::get('/run_draw', 'prepareDraw')->name('admin.auditions.prepareDraw'); + Route::post('/run_draw', 'runDraw')->name('admin.auditions.runDraw'); + }); + + // Admin Entries Routes + Route::prefix('entries')->controller(\App\Http\Controllers\Admin\EntryController::class)->group(function () { + Route::get('/', 'index'); + Route::get('/create', 'create'); + Route::post('/', 'store'); + Route::get('/{entry}/edit', 'edit'); + Route::patch('/{entry}', 'update'); + + }); + + // Admin Student Routes + Route::prefix('students')->controller(\App\Http\Controllers\Admin\StudentController::class)->group(function () { + Route::get('/', 'index'); + Route::get('/create', 'create'); + Route::post('/', 'store'); + Route::get('/{student}/edit', 'edit'); + Route::patch('/{student}', 'update'); + }); + + // Admin School Routes + Route::prefix('schools')->controller(\App\Http\Controllers\Admin\SchoolController::class)->group(function () { + Route::post('/{school}/add_domain', 'add_domain'); + Route::get('/', 'index'); + Route::get('/create', 'create'); + Route::get('/{school}/edit', 'edit'); + Route::patch('/{school}', 'update'); + Route::post('/', 'store'); + Route::delete('/domain/{domain}', 'destroy_domain'); + + }); + + // Admin User Routes + Route::prefix('users')->controller(\App\Http\Controllers\Admin\UserController::class)->group(function () { + Route::get('/', 'index'); + Route::get('/create', 'create'); + Route::post('/', 'store'); + Route::get('/{user}/edit', 'edit'); + Route::patch('/{user}', 'update'); + Route::delete('/{user}', 'destroy'); + }); +}); diff --git a/routes/judging.php b/routes/judging.php new file mode 100644 index 0000000..b8be7dc --- /dev/null +++ b/routes/judging.php @@ -0,0 +1,13 @@ +prefix('judging')->controller(JudgingController::class)->group(function () { + Route::get('/', 'index'); + Route::get('/audition/{audition}', 'auditionEntryList'); + Route::get('/entry/{entry}', 'entryScoreSheet'); + Route::post('/entry/{entry}', 'saveScoreSheet'); + Route::patch('/entry/{entry}', 'updateScoreSheet'); +}); diff --git a/routes/tabulation.php b/routes/tabulation.php new file mode 100644 index 0000000..82a9b58 --- /dev/null +++ b/routes/tabulation.php @@ -0,0 +1,31 @@ +group(function () { + + // Score Management + Route::prefix('scores/')->controller(\App\Http\Controllers\Tabulation\ScoreController::class)->group(function () { + Route::get('/choose_entry', 'chooseEntry')->name('scores.chooseEntry'); + Route::get('/entry', 'entryScoreSheet')->name('scores.entryScoreSheet'); + Route::post('/entry/{entry}', 'saveEntryScoreSheet')->name('scores.saveEntryScoreSheet'); + Route::delete('/{score}', [\App\Http\Controllers\Tabulation\ScoreController::class, 'destroyScore'])->name('scores.destroy'); + }); + + // Generic Tabulation Routes + Route::prefix('tabulation/')->controller(\App\Http\Controllers\Tabulation\TabulationController::class)->group(function () { + Route::get('/status', 'status'); + Route::match(['get', 'post'], '/auditions/{audition}', 'auditionSeating')->name('tabulation.audition.seat'); + Route::post('/auditions/{audition}/publish-seats', 'publishSeats')->name('tabulation.seat.publish'); + Route::post('/auditions/{audition}/unpublish-seats', 'unpublishSeats')->name('tabulation.seat.unpublish'); + }); + + // Doubler decision routes + Route::prefix('doubler-decision')->controller(DoublerDecisionController::class)->group(function () { + Route::post('{entry}/accept', 'accept')->name('doubler.accept'); + Route::post('{entry}/decline', 'decline')->name('doubler.decline'); + }); + +}); diff --git a/routes/user.php b/routes/user.php new file mode 100644 index 0000000..7bbe0c0 --- /dev/null +++ b/routes/user.php @@ -0,0 +1,47 @@ +group(function () { + Route::get('/dashboard', [DashboardController::class, 'dashboard'])->name('dashboard'); + Route::get('/profile', [DashboardController::class, 'profile']); + Route::get('/my_school', [DashboardController::class, 'my_school']); +}); + +// Entry Related Routes +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'); + Route::delete('/entries/{entry}', 'destroy'); +}); + +// User Related Routes +Route::middleware(['auth', 'verified'])->controller(UserController::class)->group(function () { + Route::patch('/users/{user}/set_school', 'set_school'); + Route::patch('/users/{$user}', 'update'); +}); + +// Student Related Routes +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'); + Route::patch('/students/{student}', 'update'); + Route::delete('/students/{student}', 'destroy'); +}); + +// School Related Routes +Route::middleware(['auth', 'verified'])->controller(SchoolController::class)->group(function () { + Route::get('/schools/create', 'create'); + Route::post('/schools', 'store'); + Route::get('/schools/{school}/edit', 'edit'); + Route::get('/schools/{school}', 'show'); + Route::patch('/schools/{school}', 'update'); +}); diff --git a/routes/web.php b/routes/web.php index 51a5039..8afe07f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -15,195 +15,16 @@ use App\Http\Middleware\CheckIfCanTab; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Route; - +require __DIR__.'/admin.php'; +require __DIR__.'/judging.php'; +require __DIR__.'/tabulation.php'; +require __DIR__.'/user.php'; Route::get('/test', [TestController::class, 'flashTest'])->middleware('auth', 'verified'); Route::view('/', 'welcome')->middleware('guest')->name('home'); Route::get('/results', [App\Http\Controllers\ResultsPage::class, '__invoke'])->name('results'); - - -// Judging Routes -Route::middleware(['auth', 'verified', CheckIfCanJudge::class])->prefix('judging')->controller(JudgingController::class)->group(function () { - Route::get('/', 'index'); - Route::get('/audition/{audition}', 'auditionEntryList'); - Route::get('/entry/{entry}', 'entryScoreSheet'); - Route::post('/entry/{entry}', 'saveScoreSheet'); - Route::patch('/entry/{entry}', 'updateScoreSheet'); -}); - -// Tabulation Routes -Route::middleware(['auth', 'verified', CheckIfCanTab::class])->group(function () { - - // Score Management - Route::prefix('scores/')->controller(\App\Http\Controllers\Tabulation\ScoreController::class)->group(function () { - Route::get('/choose_entry', 'chooseEntry')->name('scores.chooseEntry'); - Route::get('/entry', 'entryScoreSheet')->name('scores.entryScoreSheet'); - Route::post('/entry/{entry}', 'saveEntryScoreSheet')->name('scores.saveEntryScoreSheet'); - Route::delete('/{score}', [\App\Http\Controllers\Tabulation\ScoreController::class, 'destroyScore'])->name('scores.destroy'); - }); - - // Generic Tabulation Routes - Route::prefix('tabulation/')->controller(\App\Http\Controllers\Tabulation\TabulationController::class)->group(function () { - Route::get('/status', 'status'); - Route::match(['get', 'post'], '/auditions/{audition}', 'auditionSeating')->name('tabulation.audition.seat'); - Route::post('/auditions/{audition}/publish-seats', 'publishSeats')->name('tabulation.seat.publish'); - Route::post('/auditions/{audition}/unpublish-seats', 'unpublishSeats')->name('tabulation.seat.unpublish'); - }); - - // Doubler decision routes - Route::prefix('doubler-decision')->controller(DoublerDecisionController::class)->group(function () { - Route::post('{entry}/accept', 'accept')->name('doubler.accept'); - Route::post('{entry}/decline', 'decline')->name('doubler.decline'); - }); - -}); - -// Admin Routes -Route::middleware(['auth', 'verified', CheckIfAdmin::class])->prefix('admin/')->group(function () { - Route::view('/', 'admin.dashboard'); - - Route::post('/auditions/roomUpdate', [\App\Http\Controllers\Admin\AuditionController::class, 'roomUpdate']); // Endpoint for JS assigning auditions to rooms - Route::post('/scoring/assign_guide_to_audition', [\App\Http\Controllers\Admin\AuditionController::class, 'scoringGuideUpdate']); // Endpoint for JS assigning scoring guides to auditions - - // Admin Ensemble Routes - Route::prefix('ensembles')->controller(\App\Http\Controllers\Admin\EnsembleController::class)->group(function () { - Route::get('/', 'index')->name('admin.ensembles.index'); - Route::post('/', 'store')->name('admin.ensembles.store'); - Route::delete('/{ensemble}', 'destroy')->name('admin.ensembles.destroy'); - Route::post('/updateEnsembleRank', 'updateEnsembleRank')->name('admin.ensembles.updateEnsembleRank'); - Route::patch('/{ensemble}', 'updateEnsemble')->name('admin.ensembles.updateEnsemble'); - Route::get('/seating-limits', 'seatingLimits')->name('admin.ensembles.seatingLimits'); - Route::get('/seating-limits/{ensemble}', 'seatingLimits')->name('admin.ensembles.seatingLimits.ensemble'); - Route::post('/seating-limits/{ensemble}', 'seatingLimitsSet')->name('admin.ensembles.seatingLimits.ensemble.set'); - }); - - // Admin Event Routes - Route::prefix('events')->controller(\App\Http\Controllers\Admin\EventController::class)->group(function () { - Route::get('/', 'index')->name('admin.events.index'); - Route::post('/', 'store')->name('admin.events.store'); - Route::delete('/{event}', 'destroy')->name('admin.events.destroy'); - }); - - // Admin Rooms Routes - Route::prefix('rooms')->controller(\App\Http\Controllers\Admin\RoomController::class)->group(function () { - Route::get('/', 'index')->name('admin.rooms.index'); - Route::get('/create', 'create')->name('admin.rooms.create'); - Route::post('/', 'store')->name('admin.rooms.store'); - Route::post('/{room}/edit', 'edit')->name('admin.rooms.edit'); - Route::patch('/{room}', 'update')->name('admin.rooms.update'); - Route::delete('/{room}', 'destroy')->name('admin.rooms.destroy'); - Route::get('/judging_assignments', 'judgingAssignment')->name('admin.rooms.judgingAssignment'); // Screen to assign judges to rooms - Route::match(['post', 'delete'], '/{room}/judge', 'updateJudgeAssignment')->name('admin.rooms.updateJudgeAssignment'); - - }); - - // Admin Scoring Guides - Route::prefix('scoring')->controller(\App\Http\Controllers\Admin\ScoringGuideController::class)->group(function () { - Route::get('/', 'index')->name('admin.scoring.index'); // Scoring Setup Homepage - Route::post('/guides', 'store')->name('admin.scoring.store'); // Save a new scoring guide - Route::get('/guides/{guide}/edit', 'edit')->name('admin.scoring.edit'); // Edit scoring guide - Route::patch('/guides/{guide}/edit', 'update')->name('admin.scoring.update'); // Save changes to audition guide (rename) - Route::post('/guides/{guide}/subscore', 'subscore_store')->name('admin.scoring.subscore_store'); // Save a new subscore - Route::post('/reorder-display', 'reorder_display')->name('admin.scoring.reorder_display'); - Route::post('/reorder-tiebreak', 'reorder_tiebreak')->name('admin.scoring.reorder_tiebreak'); - }); - - // Admin Auditions Routes - Route::prefix('auditions')->controller(\App\Http\Controllers\Admin\AuditionController::class)->group(function () { - Route::get('/', 'index')->name('admin.auditions.index'); - Route::get('/create', 'create')->name('admin.auditions.create'); - Route::post('/', 'store')->name('admin.auditions.store'); - Route::get('/{audition}/edit', 'edit')->name('admin.auditions.edit'); - Route::patch('/{audition}', 'update')->name('admin.auditions.update'); - Route::post('/reorder', 'reorder')->name('admin.auditions.reorder'); - Route::delete('/{audition}', 'destroy')->name('admin.auditions.destroy'); - Route::get('/run_draw', 'prepareDraw')->name('admin.auditions.prepareDraw'); - Route::post('/run_draw', 'runDraw')->name('admin.auditions.runDraw'); - }); - - // Admin Entries Routes - Route::prefix('entries')->controller(\App\Http\Controllers\Admin\EntryController::class)->group(function () { - Route::get('/', 'index'); - Route::get('/create', 'create'); - Route::post('/', 'store'); - Route::get('/{entry}/edit', 'edit'); - Route::patch('/{entry}', 'update'); - - }); - - // Admin Student Routes - Route::prefix('students')->controller(\App\Http\Controllers\Admin\StudentController::class)->group(function () { - Route::get('/', 'index'); - Route::get('/create', 'create'); - Route::post('/', 'store'); - Route::get('/{student}/edit', 'edit'); - Route::patch('/{student}', 'update'); - }); - - // Admin School Routes - Route::prefix('schools')->controller(\App\Http\Controllers\Admin\SchoolController::class)->group(function () { - Route::post('/{school}/add_domain', 'add_domain'); - Route::get('/', 'index'); - Route::get('/create', 'create'); - Route::get('/{school}/edit', 'edit'); - Route::patch('/{school}', 'update'); - Route::post('/', 'store'); - Route::delete('/domain/{domain}', 'destroy_domain'); - - }); - - // Admin User Routes - Route::prefix('users')->controller(\App\Http\Controllers\Admin\UserController::class)->group(function () { - Route::get('/', 'index'); - Route::get('/create', 'create'); - Route::post('/', 'store'); - Route::get('/{user}/edit', 'edit'); - Route::patch('/{user}', 'update'); - Route::delete('/{user}', 'destroy'); - }); -}); - -// Dashboard Related Routes -Route::middleware(['auth', 'verified'])->group(function () { - Route::get('/dashboard', [DashboardController::class, 'dashboard'])->name('dashboard'); - Route::get('/profile', [DashboardController::class, 'profile']); - Route::get('/my_school', [DashboardController::class, 'my_school']); -}); - -// Entry Related Routes -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'); - Route::delete('/entries/{entry}', 'destroy'); -}); - -// User Related Routes -Route::middleware(['auth', 'verified'])->controller(UserController::class)->group(function () { - Route::patch('/users/{user}/set_school', 'set_school'); - Route::patch('/users/{$user}', 'update'); -}); - -// Student Related Routes -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'); - Route::patch('/students/{student}', 'update'); - Route::delete('/students/{student}', 'destroy'); -}); - -// School Related Routes -Route::middleware(['auth', 'verified'])->controller(SchoolController::class)->group(function () { - Route::get('/schools/create', 'create'); - Route::post('/schools', 'store'); - Route::get('/schools/{school}/edit', 'edit'); - Route::get('/schools/{school}', 'show'); - Route::patch('/schools/{school}', 'update'); -}); - // Filter Related Routes Route::prefix('filters')->middleware(['auth', 'verified'])->controller(FilterController::class)->group(function () { Route::post('/admin_entry_filter', 'adminEntryFilter');