Refactor News management features: replace author text input with a searchable select component in NewsResource, update NewsPageController to fetch news with authors and recent articles, and enhance the news show view to display author details and comments more effectively.

This commit is contained in:
2025-07-28 21:05:24 +05:00
parent 1b4989b440
commit 6b0c92d838
12 changed files with 360 additions and 52 deletions

View File

@@ -0,0 +1,98 @@
<?php
namespace App\Filament\Resources;
use App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource\RelationManagers;
use App\Models\Author;
use Filament\Forms;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\ImageColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class AuthorResource extends Resource
{
protected static ?string $model = Author::class;
protected static ?string $navigationIcon = 'heroicon-o-users';
protected static ?string $navigationGroup = 'News';
public static function form(Form $form):
Form
{
return $form
->schema([
Forms\Components\Card::make()
->schema([
TextInput::make('name')
->required()
->maxLength(255),
FileUpload::make('profile_image')
->label('Profile Image 400x400')
->image()
->directory('authors')
->nullable(),
RichEditor::make('description')
->nullable()
->columnSpanFull(),
])->columns(1),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
ImageColumn::make('profile_image')
->square()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('name')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListAuthors::route('/'),
'create' => Pages\CreateAuthor::route('/create'),
'edit' => Pages\EditAuthor::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
class CreateAuthor extends CreateRecord
{
protected static string $resource = AuthorResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditAuthor extends EditRecord
{
protected static string $resource = AuthorResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\AuthorResource\Pages;
use App\Filament\Resources\AuthorResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListAuthors extends ListRecords
{
protected static string $resource = AuthorResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -9,6 +9,7 @@ use Filament\Forms;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Resources\Resource;
@@ -48,9 +49,11 @@ class NewsResource extends Resource
->directory('news')
->nullable()
->columnSpanFull(),
TextInput::make('author')
->required()
->maxLength(255),
Select::make('author_id')
->relationship('author', 'name')
->searchable()
->preload()
->required(),
RichEditor::make('content')
->required()
->columnSpanFull(),
@@ -75,7 +78,8 @@ class NewsResource extends Resource
Tables\Columns\TextColumn::make('slug')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('author')
Tables\Columns\TextColumn::make('author.name')
->label('Author Name')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('published_at')

View File

@@ -9,14 +9,17 @@ class NewsPageController extends Controller
{
public function index()
{
$allNews = News::all();
$allNews = News::query()->with('author')->latest()->get();
return view('web.pages.news.index', compact('allNews'));
}
public function show(News $news)
public function show($news)
{
return view('web.pages.news.show', compact('news'));
$news = News::where('slug', $news)->with('author', 'comments')->first();
$recentNews = News::query()->with('author')->latest()->limit(3)->get();
return view('web.pages.news.show', compact('news', 'recentNews'));
}
public function storeComment(Request $request, News $news)

23
app/Models/Author.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Author extends Model
{
use HasFactory;
protected $fillable = [
'name',
'description',
'profile_image',
];
public function news(): HasMany
{
return $this->hasMany(News::class);
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class News extends Model
@@ -16,11 +17,16 @@ class News extends Model
'content',
'image',
'published_at',
'author',
'author_id',
];
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}
}