diff --git a/app/Http/Controllers/admin/Catalog/Direction/DirectionProfileController.php b/app/Http/Controllers/admin/Catalog/Direction/DirectionProfileController.php new file mode 100644 index 0000000..6d53583 --- /dev/null +++ b/app/Http/Controllers/admin/Catalog/Direction/DirectionProfileController.php @@ -0,0 +1,75 @@ +validated(); + + $directionProfile = new DirectionProfile(); + $directionProfile->name = $validated['name']; + $directionProfile->description = $validated['description']; + $directionProfile->slug = $validated['slug']; + $directionProfile->position = $validated['position']; + $directionProfile->direction_id = $validated['direction_id']; + $directionProfile->save(); + + return redirect()->route('direction_profiles.index'); + } + + public function show(DirectionProfile $directionProfile): View + { + return view('admin.catalog.direction.direction_profile.show', compact('directionProfile')); + } + + public function edit(DirectionProfile $directionProfile): View + { + $directions = Direction::pluck('name', 'id'); + return view( + 'admin.catalog.direction.direction_profile.edit', + compact('directionProfile','directions') + ); + } + + public function update(UpdateDirectionProfileRequest $request, DirectionProfile $directionProfile): RedirectResponse + { + $validated = $request->validated(); + + $directionProfile->name = $validated['name']; + $directionProfile->description = $validated['description']; + $directionProfile->slug = $validated['slug']; + $directionProfile->position = $validated['position']; + $directionProfile->direction_id = $validated['direction_id']; + $directionProfile->save(); + + return redirect()->route('direction_profiles.index'); + } + + public function destroy(DirectionProfile $directionProfile): RedirectResponse + { + $directionProfile->delete(); + return redirect()->route('direction_profiles.index'); + } +} diff --git a/app/Http/Requests/admin/Catalog/Direction/StoreDirectionProfileRequest.php b/app/Http/Requests/admin/Catalog/Direction/StoreDirectionProfileRequest.php new file mode 100644 index 0000000..1b19fe3 --- /dev/null +++ b/app/Http/Requests/admin/Catalog/Direction/StoreDirectionProfileRequest.php @@ -0,0 +1,24 @@ + 'required|string|max:255|unique:direction_profiles,name', + 'description' => 'string', + 'slug' => 'required|string|max:255|unique:direction_profiles,slug', + 'direction_id' => 'required|int|numeric|max:255', + 'position' => 'required|int|numeric|max:255', + ]; + } +} diff --git a/app/Http/Requests/admin/Catalog/Direction/UpdateDirectionProfileRequest.php b/app/Http/Requests/admin/Catalog/Direction/UpdateDirectionProfileRequest.php new file mode 100644 index 0000000..f9f3dcb --- /dev/null +++ b/app/Http/Requests/admin/Catalog/Direction/UpdateDirectionProfileRequest.php @@ -0,0 +1,24 @@ + "required|string|max:255|unique:direction_profiles,name,{$this->direction_profile->id}", + 'description' => 'string', + 'slug' => "required|string|max:255|unique:direction_profiles,slug,{$this->direction_profile->id}", + 'direction_id' => 'required|int|numeric|max:255', + 'position' => 'required|int|numeric|max:255', + ]; + } +} diff --git a/app/Models/Direction.php b/app/Models/Direction.php index 05b57e8..6e0abca 100644 --- a/app/Models/Direction.php +++ b/app/Models/Direction.php @@ -49,4 +49,9 @@ class Direction extends Model { return $this->hasMany('App\Models\Cost', 'direction_id'); } + + public function directionProfiles(): HasMany + { + return $this->hasMany('App\Models\DirectionProfile', 'direction_id'); + } } diff --git a/app/Models/DirectionProfile.php b/app/Models/DirectionProfile.php new file mode 100644 index 0000000..e651bf7 --- /dev/null +++ b/app/Models/DirectionProfile.php @@ -0,0 +1,26 @@ +belongsTo(Direction::class); + } +} diff --git a/database/factories/DirectionProfileFactory.php b/database/factories/DirectionProfileFactory.php new file mode 100644 index 0000000..82c42ed --- /dev/null +++ b/database/factories/DirectionProfileFactory.php @@ -0,0 +1,19 @@ + fake()->name(), + 'description' => fake()->text(), + 'slug' => fake()->slug(), + 'position' => 1, + 'direction_id' => 1, + ]; + } +} diff --git a/database/migrations/2024_02_26_064138_create_direction_profiles_table.php b/database/migrations/2024_02_26_064138_create_direction_profiles_table.php new file mode 100644 index 0000000..31e4e3f --- /dev/null +++ b/database/migrations/2024_02_26_064138_create_direction_profiles_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('name'); + $table->text('description')->nullable(); + $table->string('slug'); + $table->string('position'); + $table->foreignId('direction_id')->constrained('directions'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('direction_profiles'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index c61277f..2b8fb9c 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -35,6 +35,7 @@ class DatabaseSeeder extends Seeder PlaceTypeSeeder::class, PlaceSeeder::class, CostSeeder::class, + DirectionProfileSeeder::class, ]); $this->call([ diff --git a/database/seeders/DirectionProfileSeeder.php b/database/seeders/DirectionProfileSeeder.php new file mode 100644 index 0000000..2f9d648 --- /dev/null +++ b/database/seeders/DirectionProfileSeeder.php @@ -0,0 +1,37 @@ +insert([ + [ + 'name' => 'Государственно-правовой', + 'description' => 'Государственно-правовой профиль', + 'slug' => 'the-state-legal', + 'position' => 1, + 'direction_id' => 1, + ], + [ + 'name' => 'Условно-правовой', + 'description' => 'Условно-правовой профиль', + 'slug' => 'probationary-profile', + 'position' => 2, + 'direction_id' => 1, + ], + [ + 'name' => 'Цифровой Юрист', + 'description' => 'Цифровой Юрист профиль', + 'slug' => 'digital-lawyer', + 'position' => 3, + 'direction_id' => 1, + ], + ]); + } +} diff --git a/resources/views/admin/catalog/direction/direction_profile/create.blade.php b/resources/views/admin/catalog/direction/direction_profile/create.blade.php new file mode 100644 index 0000000..f0f1614 --- /dev/null +++ b/resources/views/admin/catalog/direction/direction_profile/create.blade.php @@ -0,0 +1,77 @@ +@extends('layouts.admin_layout') +@section('content') + @auth() +
+
+

Создать Профиль Подготовки

+ {{ Form::open(['url' => route('direction_profiles.store'), 'method' => 'POST', 'class' => '']) }} +
+
+ {{ Form::label('name', 'Название') }} +
+
+ {{ Form::text('name', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('name') }} + @endif +
+ +
+ {{ Form::label('direction_id', 'Направление подготовки') }} +
+
+ {{ Form::select('direction_id', $directions, null, ['class' => 'form-select']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('direction_id') }} + @endif +
+ +
+ {{ Form::label('description', 'Описание') }} +
+
+ {{ Form::text('description', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('description') }} + @endif +
+ +
+ {{ Form::label('slug', 'URL') }} +
+
+ {{ Form::text('slug', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('slug') }} + @endif +
+ +
+ {{ Form::label('position', 'Позиция') }} +
+
+ {{ Form::text('position', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('position') }} + @endif +
+ +
+ {{ Form::submit('Создать', ['class' => 'btn btn-primary']) }} +
+
+ {{ Form::close() }} +
+
+ @endauth +@endsection diff --git a/resources/views/admin/catalog/direction/direction_profile/edit.blade.php b/resources/views/admin/catalog/direction/direction_profile/edit.blade.php new file mode 100644 index 0000000..882e8ae --- /dev/null +++ b/resources/views/admin/catalog/direction/direction_profile/edit.blade.php @@ -0,0 +1,77 @@ +@extends('layouts.admin_layout') +@section('content') + @auth() +
+
+

Изменить Профиль Подготовки

+ {{ Form::open(['url' => route('direction_profiles.update', $directionProfile), 'method' => 'PATCH', 'class' => '']) }} +
+
+ {{ Form::label('name', 'Название') }} +
+
+ {{ Form::text('name', $directionProfile->name, ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('name') }} + @endif +
+ +
+ {{ Form::label('direction_id', 'Направление подготовки') }} +
+
+ {{ Form::select('direction_id', $directions, $directionProfile->direction->id, ['class' => 'form-select']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('direction_id') }} + @endif +
+ +
+ {{ Form::label('description', 'Описание') }} +
+
+ {{ Form::text('description', $directionProfile->description, ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('description') }} + @endif +
+ +
+ {{ Form::label('slug', 'URL') }} +
+
+ {{ Form::text('slug', $directionProfile->slug, ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('slug') }} + @endif +
+ +
+ {{ Form::label('position', 'Позиция') }} +
+
+ {{ Form::text('position', $directionProfile->position, ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('position') }} + @endif +
+ +
+ {{ Form::submit('Изменить', ['class' => 'btn btn-primary']) }} +
+
+ {{ Form::close() }} +
+
+ @endauth +@endsection diff --git a/resources/views/admin/catalog/direction/direction_profile/index.blade.php b/resources/views/admin/catalog/direction/direction_profile/index.blade.php new file mode 100644 index 0000000..15d296a --- /dev/null +++ b/resources/views/admin/catalog/direction/direction_profile/index.blade.php @@ -0,0 +1,43 @@ +@extends('layouts.admin_layout') +@section('content') +
+

Профили образования

+
+ Создать Профиль образования +
+
+ + + + + + + + + + + + + + @foreach($directionProfiles as $directionProfile) + + + + + + + + + @endforeach + +
НазваниеНаправление подготовкиОписаниеПозицияURLдействия
{{ $directionProfile->name }}{{ $directionProfile->direction->name }}{{ Str::words($directionProfile->description, 10, '...') }}{{ $directionProfile->position }}{{ $directionProfile->slug }} + редактировать + удалить +
+
+
+
+@endsection diff --git a/resources/views/admin/catalog/direction/direction_profile/show.blade.php b/resources/views/admin/catalog/direction/direction_profile/show.blade.php new file mode 100644 index 0000000..7a09700 --- /dev/null +++ b/resources/views/admin/catalog/direction/direction_profile/show.blade.php @@ -0,0 +1,17 @@ +@extends('layouts.admin_layout') +@section('content') + @auth() +
+

Название

+

{{ $directionProfile->name }}

+

Направление подготовки

+

{{ $directionProfile->direction->name }}

+

Описание

+

{{ $directionProfile->description }}

+

Позиция

+

{{ $directionProfile->position }}

+

URL

+

{{ $directionProfile->slug }}

+
+ @endauth +@endsection diff --git a/resources/views/layouts/admin_layout.blade.php b/resources/views/layouts/admin_layout.blade.php index a758b34..b06451c 100644 --- a/resources/views/layouts/admin_layout.blade.php +++ b/resources/views/layouts/admin_layout.blade.php @@ -65,6 +65,7 @@
  • Кол-во Мест
  • Типы Мест
  • Стоимость об.
  • +
  • Профили подготовки
  • @yield('content')
    diff --git a/routes/admin.php b/routes/admin.php index 3a506ba..6537b0c 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -3,6 +3,7 @@ use App\Http\Controllers\admin\AdmissionController; use App\Http\Controllers\admin\Catalog\DepartmentController; use App\Http\Controllers\admin\Catalog\Direction\CostController; +use App\Http\Controllers\admin\Catalog\Direction\DirectionProfileController; use App\Http\Controllers\admin\Catalog\Direction\EducationFormController; use App\Http\Controllers\admin\Catalog\Direction\EducationLevelController; use App\Http\Controllers\admin\Catalog\Direction\EntranceExaminationController; @@ -65,6 +66,9 @@ Route::middleware(['auth', 'verified'])->prefix('admin')->group(function () { Route::resource('/places', PlaceController::class); Route::resource('/costs', CostController::class); + Route::resource('/direction_profiles', DirectionProfileController::class) + ->scoped(['direction_profile' => 'slug']); + Route::resources([ '/documents' => DocumentController::class, '/users' => UserController::class, diff --git a/tests/Feature/admin/catalog/direction/DirectionProfileTest.php b/tests/Feature/admin/catalog/direction/DirectionProfileTest.php new file mode 100644 index 0000000..b67ce14 --- /dev/null +++ b/tests/Feature/admin/catalog/direction/DirectionProfileTest.php @@ -0,0 +1,117 @@ +create(); + Faculty::factory()->create(); + Department::factory()->create(); + EducationLevel::factory()->create(); + EducationForm::factory()->create(); + Direction::factory()->create(); + + $this->directionProfile = DirectionProfile::factory()->create(); + + $this->data = DirectionProfile::factory()->make()->only([ + 'name', + 'position', + 'description', + 'slug', + 'direction_id', + ]); + + $this->user = User::factory()->create([ + 'name' => 'admin', + 'email' => 'test@example.com', + 'password' => 123456 + ]); + } + + public function testIndexDirectionProfilesPage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('direction_profiles.index')); + + $response->assertOk(); + } + + public function testCreateDirectionProfilePage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('direction_profiles.create')); + + $response->assertOk(); + } + + public function testStoreDirectionProfile(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->post(route('direction_profiles.store', $this->data)); + + $response->assertRedirect(route('direction_profiles.index')); + + $this->assertDatabaseHas('direction_profiles', $this->data); + } + + public function testShowDirectionProfilePage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('direction_profiles.show', $this->directionProfile)); + + $response->assertOk(); + } + + public function testEditDirectionProfilePage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('direction_profiles.edit', $this->directionProfile)); + + $response->assertOk(); + } + + public function testUpdateDirectionProfile(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->patch(route('direction_profiles.update', $this->directionProfile), $this->data); + + $response->assertRedirect(route('direction_profiles.index')); + + $this->assertDatabaseHas('direction_profiles', $this->data); + } + + public function testDestroyDirectionProfile(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->delete(route('direction_profiles.destroy', $this->directionProfile)); + + $response->assertRedirect(route('direction_profiles.index')); + + $this->assertDatabaseMissing('direction_profiles', $this->directionProfile->toArray()); + } +}