diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml deleted file mode 100644 index 4f8104c..0000000 --- a/.idea/phpunit.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/Console/Commands/GenerateSitemap.php b/app/Console/Commands/GenerateSitemap.php index bfe61d8..11c4981 100644 --- a/app/Console/Commands/GenerateSitemap.php +++ b/app/Console/Commands/GenerateSitemap.php @@ -2,10 +2,19 @@ namespace App\Console\Commands; +use App\Enums\EducationalProgramStatus; use App\Enums\PostStatus; +use App\Models\AcademicJournal; +use App\Models\AdditionalEducation; +use App\Models\Department; +use App\Models\Division; +use App\Models\EducationalProgram; use App\Models\Event; +use App\Models\Faculty; +use App\Models\LibraryNews; use App\Models\Page; use App\Models\Post; +use App\Models\VirtualExhibition; use Illuminate\Console\Command; use Spatie\Sitemap\Sitemap; use Spatie\Sitemap\Tags\Url; @@ -36,6 +45,14 @@ class GenerateSitemap extends Command $this->generatePages($sitemap); $this->generatePosts($sitemap); $this->generateEvents($sitemap); + $this->generateFaculties($sitemap); + $this->generateDepartments($sitemap); + $this->generateDivisisons($sitemap); + $this->generateEducationalPrograms($sitemap); + $this->generateAdditionalPrograms($sitemap); + $this->generateAcademicJournals($sitemap); + $this->generateVirtualExhibitions($sitemap); + $this->generateLibraryNews($sitemap); $sitemap->writeToFile(public_path('sitemap.xml')); } @@ -63,7 +80,7 @@ class GenerateSitemap extends Command $this->addUrlsToSitemap($sitemap, $events, function($event) { return [ - 'path' => "/events/{$event->slug}", + 'path' => route('client.event.show', $event->slug, false), 'lastModificationDate' => $event->updated_at, 'priority' => 0.5, ]; @@ -78,13 +95,140 @@ class GenerateSitemap extends Command $this->addUrlsToSitemap($sitemap, $posts, function($post) { return [ - 'path' => "/news/{$post->slug}", + 'path' => route('client.post.show', $post->slug, false), 'lastModificationDate' => $post->updated_at, 'priority' => 0.5, ]; }); } + protected function generateEducationalPrograms(Sitemap $sitemap) + { + $posts = EducationalProgram::query() + ->where('status', EducationalProgramStatus::PUBLISHED) + ->whereHas('admission_plans') + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($program) { + return [ + 'path' => route('client.program.show', $program->slug, false), + 'lastModificationDate' => $program->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateAdditionalPrograms(Sitemap $sitemap) + { + $posts = AdditionalEducation::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($program) { + return [ + 'path' => route('client.additionalProgram.show', $program->slug, false), + 'lastModificationDate' => $program->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateFaculties(Sitemap $sitemap) + { + $posts = Faculty::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($faculty) { + return [ + 'path' => route('client.faculty.show', $faculty->slug, false), + 'lastModificationDate' => $faculty->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateDepartments(Sitemap $sitemap) + { + $posts = Department::query() + ->with('faculty') + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($department) { + return [ + 'path' => route('client.department.show', [ + 'facultySlug' => $department->faculty->slug, + 'departmentSlug' => $department->slug, + ], false), + 'lastModificationDate' => $department->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateDivisisons(Sitemap $sitemap) + { + $posts = Division::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($division) { + return [ + 'path' => route('client.division.show', $division->slug, false), + 'lastModificationDate' => $division->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateAcademicJournals(Sitemap $sitemap) + { + $posts = AcademicJournal::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($journal) { + return [ + 'path' => route('client.academicJournal.show', $journal->slug, false), + 'lastModificationDate' => $journal->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateLibraryNews(Sitemap $sitemap) + { + $posts = LibraryNews::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($journal) { + return [ + 'path' => route('client.library.news.show', $journal->slug, false), + 'lastModificationDate' => $journal->updated_at, + 'priority' => 0.5, + ]; + }); + } + + protected function generateVirtualExhibitions(Sitemap $sitemap) + { + $posts = VirtualExhibition::query() + ->where('is_active', true) + ->get(); + + $this->addUrlsToSitemap($sitemap, $posts, function($exhibition) { + return [ + 'path' => route('client.library.exhibition.show', $exhibition->slug, false), + 'lastModificationDate' => $exhibition->updated_at, + 'priority' => 0.5, + ]; + }); + } + + + protected function addUrlsToSitemap(Sitemap $sitemap, $items, callable $callback) { foreach ($items as $item) { diff --git a/app/Filament/Resources/AcademicJournalResource/Pages/CreateAcademicJournal.php b/app/Filament/Resources/AcademicJournalResource/Pages/CreateAcademicJournal.php index d126b2c..6b4a999 100644 --- a/app/Filament/Resources/AcademicJournalResource/Pages/CreateAcademicJournal.php +++ b/app/Filament/Resources/AcademicJournalResource/Pages/CreateAcademicJournal.php @@ -17,7 +17,7 @@ class CreateAcademicJournal extends CreateRecord protected function mutateFormDataBeforeCreate(array $data): array { $this->seoData = $this->generateSeo($data); - $data['search_data'] = $this->generateSearchData($data['about_program']); + $data['search_data'] = $this->generateSearchData($data['main_info']); return $data; } diff --git a/app/Filament/Resources/AcademicJournalResource/Pages/EditAcademicJournal.php b/app/Filament/Resources/AcademicJournalResource/Pages/EditAcademicJournal.php index 4a19754..3787d15 100644 --- a/app/Filament/Resources/AcademicJournalResource/Pages/EditAcademicJournal.php +++ b/app/Filament/Resources/AcademicJournalResource/Pages/EditAcademicJournal.php @@ -17,7 +17,7 @@ class EditAcademicJournal extends EditRecord protected function mutateFormDataBeforeSave(array $data): array { $this->seoData = $this->generateSeo($data); - $data['search_data'] = $this->generateSearchData($data['about_program']); + $data['search_data'] = $this->generateSearchData($data['main_info']); return $data; } diff --git a/app/Filament/Resources/EducationalProgramResource.php b/app/Filament/Resources/EducationalProgramResource.php index b299d0a..51a6b95 100644 --- a/app/Filament/Resources/EducationalProgramResource.php +++ b/app/Filament/Resources/EducationalProgramResource.php @@ -241,7 +241,7 @@ class EducationalProgramResource extends Resource { return $table ->columns([ - Tables\Columns\TextColumn::make('name')->sortable(), + Tables\Columns\TextColumn::make('name')->sortable()->searchable(), Tables\Columns\TextColumn::make('code_napr'), Tables\Columns\TextColumn::make('directionStudy.lvl_edu')->limit(30), ]) diff --git a/app/Filament/Resources/UserResource/Pages/CreateUser.php b/app/Filament/Resources/UserResource/Pages/CreateUser.php index 73aa46d..b05f57c 100644 --- a/app/Filament/Resources/UserResource/Pages/CreateUser.php +++ b/app/Filament/Resources/UserResource/Pages/CreateUser.php @@ -3,10 +3,38 @@ namespace App\Filament\Resources\UserResource\Pages; use App\Filament\Resources\UserResource; +use App\Models\User; use Filament\Actions; use Filament\Resources\Pages\CreateRecord; +use Illuminate\Support\Str; class CreateUser extends CreateRecord { protected static string $resource = UserResource::class; + + protected function mutateFormDataBeforeCreate(array $data): array + { + $data['slug'] = $this->generateUniqueSlug($data['name']); + + return $data; + } + + private function generateUniqueSlug(string $name): string + { + // Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру) + $slug = Str::slug($name); + + // Проверяем, существует ли slug в базе данных + $count = 1; + $baseSlug = $slug; + + while (User::where('slug', $slug)->exists()) { + // Если slug существует, добавляем суффикс + $slug = $baseSlug . '-' . $count; + $count++; + } + + return $slug; + } + } diff --git a/app/Filament/Resources/UserResource/Pages/EditUser.php b/app/Filament/Resources/UserResource/Pages/EditUser.php index 716dc52..fbca289 100644 --- a/app/Filament/Resources/UserResource/Pages/EditUser.php +++ b/app/Filament/Resources/UserResource/Pages/EditUser.php @@ -3,13 +3,42 @@ namespace App\Filament\Resources\UserResource\Pages; use App\Filament\Resources\UserResource; +use App\Models\User; use Filament\Actions; use Filament\Resources\Pages\EditRecord; +use Illuminate\Support\Str; class EditUser extends EditRecord { protected static string $resource = UserResource::class; + protected function mutateFormDataBeforeSave(array $data): array + { + $data['slug'] = $this->generateUniqueSlug($data['name']); + + return $data; + } + + private function generateUniqueSlug(string $name): string + { + // Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру) + $slug = Str::slug($name); + + // Проверяем, существует ли slug в базе данных + $count = 1; + $baseSlug = $slug; + + while (User::where('slug', $slug)->exists()) { + // Если slug существует, добавляем суффикс + $slug = $baseSlug . '-' . $count; + $count++; + } + + return $slug; + } + + + protected function getHeaderActions(): array { return [ diff --git a/app/Http/Controllers/ClientLibraryNewsController.php b/app/Http/Controllers/ClientLibraryNewsController.php index 2f2ee53..fe717a1 100644 --- a/app/Http/Controllers/ClientLibraryNewsController.php +++ b/app/Http/Controllers/ClientLibraryNewsController.php @@ -18,9 +18,9 @@ class ClientLibraryNewsController extends Controller return Inertia::render('Client/Library-news/Index', compact('posts')); } - public function show(string $id) + public function show(string $slug) { - $post = new ClientLibraryPostListResource(LibraryNews::query()->find($id)); + $post = new ClientLibraryPostListResource(LibraryNews::query()->where('slug', $slug)->firstOrFail()); return Inertia::render('Client/Library-news/Show', compact('post')); } } diff --git a/app/Http/Controllers/ClientProgramController.php b/app/Http/Controllers/ClientProgramController.php index 9dccd2b..b249ad0 100644 --- a/app/Http/Controllers/ClientProgramController.php +++ b/app/Http/Controllers/ClientProgramController.php @@ -113,14 +113,15 @@ class ClientProgramController extends Controller public function show(string $slug) { - $program = new EducationalProgramFullResource(EducationalProgram::query()->where('slug', $slug)->with(['admission_plans', 'directionStudy'])->first()); + $program = new EducationalProgramFullResource(EducationalProgram::query()->where('slug', $slug)->with(['admission_plans', 'directionStudy'])->firstOrFail()); $formsEducational = BudgetEducation::cases(); $formsEducational = collect($formsEducational); $formsEdu = $formsEducational->mapWithKeys(function ($formEducational) { return [$formEducational->value => $formEducational->getLabel()]; }); - $seo = $this->seo; + dd($program); + $seo = $program->seo; return Inertia::render('Client/Programs/Show', compact('program', 'formsEdu', 'seo')); } @@ -158,41 +159,5 @@ class ClientProgramController extends Controller }); }]); } -// public function bakalavriat() -// { -// $naprs = DirectionStudyResource::collection( -// DirectionStudy::forBachelorLevel() -// ->withActiveAdmissionCampaign() -// ->withActivePrograms() -// ->get() -// ); -// $campaignName = $this->getAdmissionCampaignName(); -// return Inertia::render('Client/Programs/Index', compact('naprs', 'campaignName')); -// } -// -// public function spo() -// { -// $naprs = DirectionStudyResource::collection( -// DirectionStudy::forMiddleLevel() -// ->withActiveAdmissionCampaign() -// ->withActivePrograms() -// ->get() -// ); -// $campaignName = $this->getAdmissionCampaignName(); -// return Inertia::render('Client/Programs/Index', compact('naprs', 'campaignName')); -// -// } -// -// public function magistratura() -// { -// $naprs = DirectionStudyResource::collection( -// DirectionStudy::forMasterLevel() -// ->withActiveAdmissionCampaign() -// ->withActivePrograms() -// ->get() -// ); -// $campaignName = $this->getAdmissionCampaignName(); -// return Inertia::render('Client/Programs/Index', compact('naprs', 'campaignName')); -// -// } + } diff --git a/app/Http/Controllers/ClientVirtualExhibitionController.php b/app/Http/Controllers/ClientVirtualExhibitionController.php index 179ba13..9914c12 100644 --- a/app/Http/Controllers/ClientVirtualExhibitionController.php +++ b/app/Http/Controllers/ClientVirtualExhibitionController.php @@ -18,9 +18,9 @@ class ClientVirtualExhibitionController extends Controller return Inertia::render('Client/Library-exhibitions/Index', compact('exhibitions')); } - public function show(string $id) + public function show(string $slug) { - $exhibition = new ClientVirtualExhibitionListResource(VirtualExhibition::query()->find($id)); + $exhibition = new ClientVirtualExhibitionListResource(VirtualExhibition::query()->where('slug', $slug)->firstOrFail()); return Inertia::render('Client/Library-exhibitions/Show', compact('exhibition')); } } diff --git a/app/Http/Controllers/GenerateSitemapController.php b/app/Http/Controllers/GenerateSitemapController.php index e1052e1..0af0642 100644 --- a/app/Http/Controllers/GenerateSitemapController.php +++ b/app/Http/Controllers/GenerateSitemapController.php @@ -12,12 +12,8 @@ class GenerateSitemapController extends Controller { public function index() { - $sitemap = Sitemap::create(); - $this->generatePages($sitemap); - $this->generatePosts($sitemap); - $sitemap->writeToFile(public_path('sitemap.xml')); } protected function generatePages(Sitemap $sitemap) diff --git a/app/Http/Controllers/MainController.php b/app/Http/Controllers/MainController.php index 7b50f51..754f5d8 100644 --- a/app/Http/Controllers/MainController.php +++ b/app/Http/Controllers/MainController.php @@ -43,7 +43,7 @@ class MainController extends Controller $path = route('index', null, false); $page = Page::where('path', $path)->first(); - $seo = $page->seo; + $seo = $page->seo ?? null; return Inertia::render('Main', compact('posts', 'events', 'sliders', 'educations', 'seo')); } diff --git a/app/Http/Controllers/PersonController.php b/app/Http/Controllers/PersonController.php index 95f0e31..1b0146c 100644 --- a/app/Http/Controllers/PersonController.php +++ b/app/Http/Controllers/PersonController.php @@ -24,9 +24,9 @@ class PersonController extends Controller return Inertia::render('Client/Persons/Index', compact('persons', 'filters')); } - public function show(string $id) + public function show(string $slug) { - $person = new ClientFullInfoPersonResource(User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties'])->where('id', $id)->firstOrFail()); + $person = new ClientFullInfoPersonResource(User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties'])->where('slug', $slug)->firstOrFail()); return Inertia::render('Client/Persons/Show', compact('person')); } } diff --git a/app/Models/AcademicJournal.php b/app/Models/AcademicJournal.php index 5813610..9edc9e4 100644 --- a/app/Models/AcademicJournal.php +++ b/app/Models/AcademicJournal.php @@ -22,4 +22,9 @@ class AcademicJournal extends Model { return $this->hasMany(JournalIssue::class); } + + public function seo() + { + return $this->morphOne(Seo::class, 'seoable'); + } } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index a6ecc0a..c441d47 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -19,6 +19,7 @@ class UserFactory extends Factory { return [ 'name' => fake()->name(), + 'slug' => fake()->slug(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password diff --git a/database/migrations/000_2024_11_07_120748_add_slug_to_users.php b/database/migrations/000_2024_11_07_120748_add_slug_to_users.php new file mode 100644 index 0000000..406b4c0 --- /dev/null +++ b/database/migrations/000_2024_11_07_120748_add_slug_to_users.php @@ -0,0 +1,28 @@ +string('slug')->unique()->nullable()->after('name'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('slug'); + }); + } +}; diff --git a/database/migrations/2024_11_07_105549_add_slug_to_library_news.php b/database/migrations/2024_11_07_105549_add_slug_to_library_news.php new file mode 100644 index 0000000..f72a68d --- /dev/null +++ b/database/migrations/2024_11_07_105549_add_slug_to_library_news.php @@ -0,0 +1,28 @@ +string('slug')->unique()->after('title'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('library_news', function (Blueprint $table) { + $table->dropColumn('slug'); + }); + } +}; diff --git a/database/migrations/2024_11_07_105637_add_slug_to_virtual_exhibitions.php b/database/migrations/2024_11_07_105637_add_slug_to_virtual_exhibitions.php new file mode 100644 index 0000000..099894f --- /dev/null +++ b/database/migrations/2024_11_07_105637_add_slug_to_virtual_exhibitions.php @@ -0,0 +1,28 @@ +string('slug')->unique()->after('title'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('virtual_exhibitions', function (Blueprint $table) { + $table->dropColumn('slug'); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index b9b7b3a..3227c7a 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -28,6 +28,7 @@ class DatabaseSeeder extends Seeder User::create([ 'name' => 'Failj', 'email' => 'Failj@bk.ru', + 'slug' => 'failj', 'password' => "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi", ]); User::factory()->count(50)->has(UserDetail::factory())->create(); diff --git a/resources/js/Components/BuilderUi/Persons/PersonAvatarBlock.vue b/resources/js/Components/BuilderUi/Persons/PersonAvatarBlock.vue new file mode 100644 index 0000000..9ac4c26 --- /dev/null +++ b/resources/js/Components/BuilderUi/Persons/PersonAvatarBlock.vue @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/resources/js/Components/BuilderUi/Persons/PersonBreadcrumbs.vue b/resources/js/Components/BuilderUi/Persons/PersonBreadcrumbs.vue new file mode 100644 index 0000000..549400e --- /dev/null +++ b/resources/js/Components/BuilderUi/Persons/PersonBreadcrumbs.vue @@ -0,0 +1,194 @@ + + + + + + \ No newline at end of file diff --git a/resources/js/Components/PersonCards/ClientDepartmentTeacherCard.vue b/resources/js/Components/PersonCards/ClientDepartmentTeacherCard.vue index 801394b..fd174df 100644 --- a/resources/js/Components/PersonCards/ClientDepartmentTeacherCard.vue +++ b/resources/js/Components/PersonCards/ClientDepartmentTeacherCard.vue @@ -4,7 +4,7 @@
Image Description
- + {{ teacher.position }}: {{ teacher.name }}

diff --git a/resources/js/Components/PersonCards/ClientDepartmentWorkerCard.vue b/resources/js/Components/PersonCards/ClientDepartmentWorkerCard.vue index c3eaca1..d41a224 100644 --- a/resources/js/Components/PersonCards/ClientDepartmentWorkerCard.vue +++ b/resources/js/Components/PersonCards/ClientDepartmentWorkerCard.vue @@ -4,7 +4,7 @@

Image Description
- + {{ worker.position }}: {{ worker.name }}

diff --git a/resources/js/Components/PersonCards/ClientFacultyWorkerCard.vue b/resources/js/Components/PersonCards/ClientFacultyWorkerCard.vue index 3a72d67..b8b9bc4 100644 --- a/resources/js/Components/PersonCards/ClientFacultyWorkerCard.vue +++ b/resources/js/Components/PersonCards/ClientFacultyWorkerCard.vue @@ -4,7 +4,7 @@

Image Description
- + {{ worker.position }}: {{ worker.name }}

diff --git a/resources/js/Pages/Client/Divisions/Show.vue b/resources/js/Pages/Client/Divisions/Show.vue index 28e068c..50580d8 100644 --- a/resources/js/Pages/Client/Divisions/Show.vue +++ b/resources/js/Pages/Client/Divisions/Show.vue @@ -81,7 +81,7 @@

Image Description
- + {{ worker.administrativePosition }}: {{ worker.name }}

diff --git a/resources/js/Pages/Client/Persons/Show.vue b/resources/js/Pages/Client/Persons/Show.vue index 21f35e1..5798689 100644 --- a/resources/js/Pages/Client/Persons/Show.vue +++ b/resources/js/Pages/Client/Persons/Show.vue @@ -1,8 +1,8 @@