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')
+
+@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());
+ }
+}