feat: add career application support for blog authors and expand blog status workflows

This commit is contained in:
Ümit Tunç
2026-08-07 23:21:17 +03:00
parent 9b91b3c847
commit 32b3f5187d
10 changed files with 75 additions and 23 deletions
@@ -6,6 +6,7 @@ use App\Filament\Admin\Resources\Components\TranslationTabs;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\RichEditor;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\Select;
@@ -80,11 +81,17 @@ class BlogForm
->helperText(__('blog.featured_image_helper'))
->columnSpanFull(),
Placeholder::make('intern_author_info')
->label('Stajyer Yazarı')
->content(fn ($record) => $record?->careerApplication?->name ?? '-')
->visible(fn ($record) => $record?->career_application_id !== null)
->columnSpanFull(),
Select::make('author_id')
->label(__('blog.author_field'))
->relationship('author', 'name')
->default(auth()->id())
->required()
->nullable()
->placeholder('Boş bırakılırsa stajyer yazarı veya Trunçgil')
->columnSpanFull(),
Select::make('category_id')
@@ -110,7 +117,9 @@ class BlogForm
->label(__('blog.status_field'))
->options([
'draft' => __('blog.status_draft'),
'pending' => __('blog.status_pending'),
'published' => __('blog.status_published'),
'rejected' => __('blog.status_rejected'),
'archived' => __('blog.status_archived'),
])
->default('draft')
@@ -76,7 +76,13 @@ class BlogsTable
TextColumn::make('author.name')
->label(__('blog.table_author'))
->searchable()
->formatStateUsing(fn ($state, $record) => $record->author_name)
->searchable(query: function ($query, string $search) {
$query->where(function ($q) use ($search) {
$q->whereHas('author', fn ($sub) => $sub->where('name', 'like', "%{$search}%"))
->orWhereHas('careerApplication', fn ($sub) => $sub->where('name', 'like', "%{$search}%"));
});
})
->sortable(),
TextColumn::make('category.name')
+10 -7
View File
@@ -20,7 +20,7 @@ class BlogController extends Controller
$settings = class_exists(Setting::class) ? (Setting::query()->first()) : null;
$query = class_exists(Blog::class)
? Blog::with(['category', 'author'])
? Blog::with(['category', 'author', 'careerApplication'])
->withCount('comments')
->published()
: null;
@@ -29,6 +29,9 @@ class BlogController extends Controller
if ($query && $request->has('author') && $request->author) {
$query = $query->where('author_id', $request->author);
}
if ($query && $request->has('intern') && $request->intern) {
$query = $query->where('career_application_id', $request->intern);
}
// Category filtresi
if ($query && $request->has('category') && $request->category) {
@@ -130,14 +133,14 @@ class BlogController extends Controller
if (!$request->ajax()) {
if (class_exists(Blog::class)) {
// Karusel: Öne çıkarılan ya da en güncel 5 yazı
$carouselPosts = Blog::with(['category', 'author'])
$carouselPosts = Blog::with(['category', 'author', 'careerApplication'])
->published()
->featured()
->latest('published_at')
->take(5)
->get();
if ($carouselPosts->isEmpty()) {
$carouselPosts = Blog::with(['category', 'author'])
$carouselPosts = Blog::with(['category', 'author', 'careerApplication'])
->published()
->latest('published_at')
->take(5)
@@ -145,7 +148,7 @@ class BlogController extends Controller
}
// Popüler Yazılar: En çok okunan 3 yazı
$popularPosts = Blog::with(['category', 'author'])
$popularPosts = Blog::with(['category', 'author', 'careerApplication'])
->published()
->orderBy('view_count', 'desc')
->take(3)
@@ -224,14 +227,14 @@ class BlogController extends Controller
if (!class_exists(Blog::class)) {
abort(404);
}
$post = Blog::with(['category', 'author'])
$post = Blog::with(['category', 'author', 'careerApplication'])
->withCount('comments')
->published()
->where('slug', $slug)
->firstOrFail();
// İlgili blog gönderilerini al (aynı kategoriden, mevcut gönderi hariç)
$relatedPosts = Blog::with(['category', 'author'])
$relatedPosts = Blog::with(['category', 'author', 'careerApplication'])
->withCount('comments')
->published()
->where('id', '!=', $post->id)
@@ -244,7 +247,7 @@ class BlogController extends Controller
// Eğer aynı kategoriden yeterli gönderi yoksa, diğer kategorilerden ekle
if ($relatedPosts->count() < 4) {
$additionalPosts = Blog::with(['category', 'author'])
$additionalPosts = Blog::with(['category', 'author', 'careerApplication'])
->withCount('comments')
->published()
->where('id', '!=', $post->id)
+30
View File
@@ -82,6 +82,36 @@ class Blog extends Model
return '/blog/' . $this->slug;
}
public function getAuthorNameAttribute()
{
if ($this->author) {
return $this->author->name;
}
if ($this->careerApplication) {
return $this->careerApplication->name;
}
return __('blog.default_author');
}
public function getAuthorRoleAttribute()
{
if ($this->author && $this->author->role) {
return $this->author->role;
}
if ($this->careerApplication) {
return 'Stajyer Yazılım Geliştirici';
}
return 'Trunçgil Teknoloji Editörü';
}
public function getAuthorAvatarUrlAttribute()
{
if ($this->author && $this->author->avatar) {
return asset('storage/' . $this->author->avatar);
}
return asset('assets/img/avatars/u5.webp');
}
public function getFeaturedImageUrlAttribute()
{
if ($this->featured_image) {
+1 -1
View File
@@ -61,7 +61,7 @@ class BlogStructuredData extends StructuredData
'inLanguage' => app()->getLocale(),
'author' => [
'@type' => 'Person',
'name' => $post->author->name ?? __('blog.default_author'),
'name' => $post->author_name,
],
'publisher' => self::publisherNode(),
'datePublished' => $publishedAt->toIso8601String(),
+2
View File
@@ -61,7 +61,9 @@ return [
// Status options
'status_draft' => 'Draft',
'status_pending' => 'Pending Approval',
'status_published' => 'Published',
'status_rejected' => 'Revision Requested',
'status_archived' => 'Archived',
// Messages
+2
View File
@@ -61,7 +61,9 @@ return [
// Status options
'status_draft' => 'Taslak',
'status_pending' => 'Onay Bekliyor',
'status_published' => 'Yayınlandı',
'status_rejected' => 'Revize İstendi',
'status_archived' => 'Arşivlendi',
// Messages
+3 -3
View File
@@ -37,11 +37,11 @@
<i class="uil uil-calendar-alt pr-[0.2rem] align-[-.05rem] before:content-['\e9ba']"></i>
<span>{{ $cDate }}</span>
</li>
@if($cPost->author)
@if($cPost->author || $cPost->careerApplication)
<li class="post-author inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
<span class="!text-[#aab0bc]">
<i class="uil uil-user pr-[0.2rem] align-[-.05rem] before:content-['\ed6f']"></i>
<span>{{ $cPost->author->name }}</span>
<span>{{ $cPost->author_name }}</span>
</span>
</li>
@endif
@@ -349,7 +349,7 @@
"datePublished" => $p->published_at ? $p->published_at->toIso8601String() : $p->created_at->toIso8601String(),
"author" => [
"@type" => "Person",
"name" => $p->author ? $p->author->name : 'Trunçgil'
"name" => $p->author_name
]
];
}
+8 -8
View File
@@ -22,7 +22,7 @@
<li class="post-author inline-block before:content-[''] before:inline-block before:w-[0.2rem] before:h-[0.2rem] before:opacity-50 before:m-[0_.6rem_0_.4rem] before:rounded-[100%] before:align-[.15rem] before:bg-[#aab0bc]">
<span class="!text-[0.8rem] !text-[#aab0bc]">
<i class="uil uil-user pr-[0.2rem] align-[-.05rem] before:content-['\ed6f']"></i>
<span>{{ $post->author ? $post->author->name : 'Trunçgil' }}</span>
<span>{{ $post->author_name }}</span>
</span>
</li>
</ul>
@@ -84,15 +84,15 @@
<div class="author-info xl:!flex lg:!flex md:!flex items-center !mb-3">
<div class="flex items-center">
<figure class="w-12 h-12 !relative !mr-4 rounded-[100%]">
<img class="rounded-[50%]" alt="image" src="{{ $post->author && $post->author->avatar ? asset('storage/' . $post->author->avatar) : asset('assets/img/avatars/u5.webp') }}" onerror="this.src='{{ asset('assets/img/avatars/u5.webp') }}'" loading="lazy">
<img class="rounded-[50%]" alt="image" src="{{ $post->author_avatar_url }}" onerror="this.src='{{ asset('assets/img/avatars/u5.webp') }}'" loading="lazy">
</figure>
<div>
<h6><a href="#" class="!text-[#343f52] hover:!text-[#e31e24]">{{ $post->author ? $post->author->name : 'Trunçgil' }}</a></h6>
<span class="!text-[0.75rem] !text-[#aab0bc] m-0 p-0 list-none">{{ $post->author && $post->author->role ? $post->author->role : 'Trunçgil Teknoloji Editörü' }}</span>
<h6><a href="#" class="!text-[#343f52] hover:!text-[#e31e24]">{{ $post->author_name }}</a></h6>
<span class="!text-[0.75rem] !text-[#aab0bc] m-0 p-0 list-none">{{ $post->author_role }}</span>
</div>
</div>
<div class="!mt-3 xl:!mt-0 lg:!mt-0 md:!mt-0 !ml-auto">
<a href="{{ route('blog.index', ['author' => $post->author_id]) }}" class="btn btn-sm btn-soft-ash !rounded-[50rem] btn-icon btn-icon-start !mb-0 hover:translate-y-[-0.15rem] hover:shadow-[0_0.25rem_0.75rem_rgba(30,34,40,0.15)]"><i class="uil uil-file-alt !mr-[0.3rem] before:content-['\eaec'] text-[.8rem]"></i> Tüm Yazıları</a>
<a href="{{ $post->author_id ? route('blog.index', ['author' => $post->author_id]) : ($post->career_application_id ? route('blog.index', ['intern' => $post->career_application_id]) : route('blog.index')) }}" class="btn btn-sm btn-soft-ash !rounded-[50rem] btn-icon btn-icon-start !mb-0 hover:translate-y-[-0.15rem] hover:shadow-[0_0.25rem_0.75rem_rgba(30,34,40,0.15)]"><i class="uil uil-file-alt !mr-[0.3rem] before:content-['\eaec'] text-[.8rem]"></i> Tüm Yazıları</a>
</div>
</div>
<p>Trunçgil Teknoloji editörleri tarafından kaleme alınmış bu makalede teknoloji, yazılım geliştirme ve dijital dönüşüm konularına dair güncel gelişmeleri incelediniz. Destek ve sorularınız için bizimle iletişime geçebilirsiniz.</p>
@@ -181,9 +181,9 @@
$publishedDate = $post->published_at ? $post->published_at->toIso8601String() : $post->created_at->toIso8601String();
$modifiedDate = $post->updated_at ? $post->updated_at->toIso8601String() : $publishedDate;
$authorName = $post->author ? $post->author->name : 'Trunçgil';
$authorRole = $post->author && $post->author->role ? $post->author->role : 'Trunçgil Teknoloji Editörü';
$authorUrl = route('blog.index', ['author' => $post->author_id ?? 1]);
$authorName = $post->author_name;
$authorRole = $post->author_role;
$authorUrl = $post->author_id ? route('blog.index', ['author' => $post->author_id]) : ($post->career_application_id ? route('blog.index', ['intern' => $post->career_application_id]) : route('blog.index'));
$siteName = setting('site_name', 'Trunçgil Teknoloji');
$siteLogo = setting('site_logo') ? (str_starts_with(setting('site_logo'), 'http') ? setting('site_logo') : asset('storage/' . ltrim(setting('site_logo'), '/'))) : asset('assets/img/logo.png');
@@ -1,6 +1,6 @@
@php
// Blog modelinden published içerikleri çek
$blogs = \App\Models\Blog::with(['category', 'author'])
$blogs = \App\Models\Blog::with(['category', 'author', 'careerApplication'])
->withCount('comments')
->published()
->latest('published_at')