diff --git a/app/Http/Controllers/ContestController.php b/app/Http/Controllers/ContestController.php index 5d595d44..8d9ef008 100644 --- a/app/Http/Controllers/ContestController.php +++ b/app/Http/Controllers/ContestController.php @@ -18,7 +18,11 @@ class ContestController extends Controller { public function index(): Response { - $schools = School::all()->sortBy("name"); + $schools = School::query() + ->where("is_disabled", false) + ->where("is_admin_school", false) + ->orderBy("name") + ->get(); return Inertia::render("Home", ["schools" => SchoolResource::collection($schools)]); } diff --git a/app/Http/Controllers/SchoolsController.php b/app/Http/Controllers/SchoolsController.php index 999bd1cb..ce720fc0 100644 --- a/app/Http/Controllers/SchoolsController.php +++ b/app/Http/Controllers/SchoolsController.php @@ -14,6 +14,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Cache; use Inertia\Inertia; @@ -26,15 +27,18 @@ class SchoolsController extends Controller { - public function index(SortHelper $sorter): Response + public function index(SortHelper $sorter, Request $request): Response { - $query = $sorter->sort(School::query(), ["id", "name", "regon", "updated_at", "created_at"], ["students", "address"]); + $query = School::query()->where("is_admin_school", false); + $query = $sorter->sort($query, ["id", "name", "regon", "updated_at", "created_at"], ["students", "address"]); $query = $this->sortByStudents($query, $sorter); $query = $this->sortByAddress($query, $sorter); + $query = $this->filterDisabledSchools($query, $request); $query = $sorter->search($query, "name"); - $schools = $sorter->paginate($query); - return Inertia::render("Admin/SchoolsPanel", ["schools" => SchoolResource::collection($schools)]); + return Inertia::render("Admin/SchoolsPanel", [ + "schools" => SchoolResource::collection($sorter->paginate($query)), + ]); } public function store(SchoolRequest $request): RedirectResponse @@ -59,7 +63,30 @@ public function destroy(School $school): RedirectResponse $school->delete(); return redirect() - ->back(); + ->back() + ->with("status", "Szkoła została usunięta."); + } + + public function disable(School $school): RedirectResponse + { + return $this->toggleDisable($school, true); + } + + public function enable(School $school): RedirectResponse + { + return $this->toggleDisable($school, false); + } + + public function toggleDisable(School $school, bool $value): RedirectResponse + { + $school->is_disabled = $value; + $school->save(); + + $message = $value ? "Szkoła została zablokowana." : "Szkoła została odblokowana."; + + return redirect() + ->back() + ->with("status", $message); } /** @@ -131,4 +158,15 @@ private function sortByAddress(Builder $query, SortHelper $sorter): Builder return $query; } + + private function filterDisabledSchools(Builder $query, Request $request): Builder + { + $showDisabled = $request->query("disabled", "false") === "true"; + + if (!$showDisabled) { + return $query->where("is_disabled", false); + } + + return $query; + } } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 328a9322..2a0f672e 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -5,9 +5,7 @@ namespace App\Http\Controllers; use App\Http\Requests\UserRequest; -use App\Http\Resources\SchoolResource; use App\Http\Resources\UserResource; -use App\Models\School; use App\Models\User; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -25,16 +23,6 @@ public function index(Request $request): Response ]); } - public function edit(User $user): Response - { - $this->authorize("update", $user); - - return Inertia::render("Admin/EditUser", [ - "user" => UserResource::make($user), - "schools" => SchoolResource::collection(School::all()), - ]); - } - public function update(UserRequest $request, User $user): RedirectResponse { $this->authorize("update", $user); diff --git a/app/Http/Requests/Auth/RegisterUserRequest.php b/app/Http/Requests/Auth/RegisterUserRequest.php index d9aacfb8..fe5a6fed 100644 --- a/app/Http/Requests/Auth/RegisterUserRequest.php +++ b/app/Http/Requests/Auth/RegisterUserRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests\Auth; +use App\Rules\IsSchoolValidForRegularUsers; use Illuminate\Foundation\Http\FormRequest; class RegisterUserRequest extends FormRequest @@ -20,7 +21,7 @@ public function rules(): array "firstname" => ["required", "string", "max:255"], "surname" => ["required", "string", "max:255"], "password" => ["required", "string", "min:8"], - "school_id" => ["required", "integer", "exists:schools,id"], + "school_id" => ["required", "integer", "exists:schools,id", new IsSchoolValidForRegularUsers()], ]; } } diff --git a/app/Http/Requests/UserRequest.php b/app/Http/Requests/UserRequest.php index 1ee2b303..06eadd8d 100644 --- a/app/Http/Requests/UserRequest.php +++ b/app/Http/Requests/UserRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests; +use App\Rules\IsSchoolValidForRegularUsers; use Illuminate\Foundation\Http\FormRequest; class UserRequest extends FormRequest @@ -19,7 +20,7 @@ public function rules(): array "email" => ["required", "string", "email", "max:255", "unique:users,email," . $this->user->id], "firstname" => ["required", "string", "max:255"], "surname" => ["required", "string", "max:255"], - "school_id" => ["required", "integer", "exists:schools,id"], + "school_id" => ["required", "integer", "exists:schools,id", new IsSchoolValidForRegularUsers()], ]; } } diff --git a/app/Http/Resources/SchoolResource.php b/app/Http/Resources/SchoolResource.php index eee4b506..d255f0e1 100644 --- a/app/Http/Resources/SchoolResource.php +++ b/app/Http/Resources/SchoolResource.php @@ -20,6 +20,7 @@ public function toArray(Request $request): array "regon" => $this->regon, "city" => $this->city, "street" => $this->street, + "isDisabled" => $this->is_disabled, "buildingNumber" => $this->building_number, "apartmentNumber" => $this->apartment_number, "zipCode" => $this->zip_code, diff --git a/app/Models/School.php b/app/Models/School.php index 7c357a54..9a0f40f1 100644 --- a/app/Models/School.php +++ b/app/Models/School.php @@ -19,6 +19,8 @@ * @property string $building_number * @property string $apartment_number * @property string $zip_code + * @property boolean $is_disabled + * @property boolean $is_admin_school * @property Carbon $created_at * @property Carbon $updated_at * @property Collection $users diff --git a/app/Policies/SchoolPolicy.php b/app/Policies/SchoolPolicy.php new file mode 100644 index 00000000..91f3116b --- /dev/null +++ b/app/Policies/SchoolPolicy.php @@ -0,0 +1,31 @@ +is_admin_school && !$school->is_disabled; + } + + public function delete(User $user, School $school): bool + { + return $school->users()->count() === 0 && !$school->is_disabled && !$school->is_admin_school; + } + + public function disable(User $user, School $school): bool + { + return !$school->is_disabled && !$school->is_admin_school; + } + + public function enable(User $user, School $school): bool + { + return $school->is_disabled && !$school->is_admin_school; + } +} diff --git a/app/Rules/IsSchoolValidForRegularUsers.php b/app/Rules/IsSchoolValidForRegularUsers.php new file mode 100644 index 00000000..be132aff --- /dev/null +++ b/app/Rules/IsSchoolValidForRegularUsers.php @@ -0,0 +1,26 @@ +find($value); + + if (!$school) { + return; + } + + if ($school->is_disabled | $school->is_admin_school) { + $fail(Lang::get("validation.custom.school_id.exists")); + } + } +} diff --git a/database/factories/SchoolFactory.php b/database/factories/SchoolFactory.php index 0d121b9c..7f8ded0d 100644 --- a/database/factories/SchoolFactory.php +++ b/database/factories/SchoolFactory.php @@ -28,9 +28,25 @@ public function definition(): array "building_number" => fake()->buildingNumber(), "apartment_number" => fake()->buildingNumber(), "zip_code" => fake()->randomNumber(2) . "-" . fake()->randomNumber(3), + "is_disabled" => false, + "is_admin_school" => false, ]; } + public function disabled() + { + return $this->state(fn(array $attributes): array => [ + "is_disabled" => true, + ]); + } + + public function adminSchool() + { + return $this->state(fn(array $attributes): array => [ + "is_admin_school" => true, + ]); + } + public function withoutApartment(): static { return $this->state(fn(array $attributes): array => [ diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 5f34af2f..b85055e1 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -25,6 +25,7 @@ public function up(): void $table->string("token"); $table->timestamp("created_at")->nullable(); }); + Schema::create("sessions", function (Blueprint $table): void { $table->string("id")->primary(); $table->foreignId("user_id")->nullable()->index(); diff --git a/database/migrations/2024_08_08_113859_create_schools_table.php b/database/migrations/2024_08_08_113859_create_schools_table.php index 67d89e7f..a2247ff0 100644 --- a/database/migrations/2024_08_08_113859_create_schools_table.php +++ b/database/migrations/2024_08_08_113859_create_schools_table.php @@ -18,6 +18,8 @@ public function up(): void $table->string("building_number"); $table->string("apartment_number")->nullable(); $table->string("zip_code"); + $table->boolean("is_disabled")->default(false); + $table->boolean("is_admin_school")->default(false); $table->timestamps(); }); } diff --git a/database/seeders/AdminSeeder.php b/database/seeders/AdminSeeder.php index 44cea50a..497d6064 100644 --- a/database/seeders/AdminSeeder.php +++ b/database/seeders/AdminSeeder.php @@ -15,6 +15,20 @@ class AdminSeeder extends Seeder { public function run(): void { + $school = School::firstOrCreate( + ["is_admin_school" => true], + [ + "name" => "Admin school", + "regon" => "", + "city" => "", + "street" => "", + "building_number" => "", + "zip_code" => "", + "is_disabled" => true, + "is_admin_school" => true, + ], + ); + $superAdmin = User::firstOrCreate( ["email" => "superadmin@example.com"], [ @@ -23,7 +37,7 @@ public function run(): void "email_verified_at" => Carbon::now(), "password" => Hash::make("password"), "remember_token" => Str::random(10), - "school_id" => School::factory()->create()->id, + "school_id" => $school->id, ], ); $superAdmin->syncRoles("super_admin"); @@ -36,7 +50,7 @@ public function run(): void "email_verified_at" => Carbon::now(), "password" => Hash::make("password"), "remember_token" => Str::random(10), - "school_id" => School::factory()->create()->id, + "school_id" => $school->id, ], ); $admin->syncRoles("admin"); diff --git a/resources/js/Pages/Admin/CreateAdmin.vue b/resources/js/Pages/Admin/CreateAdmin.vue deleted file mode 100644 index 0ad8c3d0..00000000 --- a/resources/js/Pages/Admin/CreateAdmin.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/Admin/EditAdmin.vue b/resources/js/Pages/Admin/EditAdmin.vue deleted file mode 100644 index ddee353f..00000000 --- a/resources/js/Pages/Admin/EditAdmin.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/Admin/EditUser.vue b/resources/js/Pages/Admin/EditUser.vue deleted file mode 100644 index 22ca2d90..00000000 --- a/resources/js/Pages/Admin/EditUser.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/Admin/SchoolsPanel.vue b/resources/js/Pages/Admin/SchoolsPanel.vue index ec15bb87..5f26eb61 100644 --- a/resources/js/Pages/Admin/SchoolsPanel.vue +++ b/resources/js/Pages/Admin/SchoolsPanel.vue @@ -1,6 +1,7 @@