diff --git a/app/Filament/Resources/AuthorResource.php b/app/Filament/Resources/AuthorResource.php new file mode 100644 index 0000000..5affaa8 --- /dev/null +++ b/app/Filament/Resources/AuthorResource.php @@ -0,0 +1,98 @@ +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'), + ]; + } +} diff --git a/app/Filament/Resources/AuthorResource/Pages/CreateAuthor.php b/app/Filament/Resources/AuthorResource/Pages/CreateAuthor.php new file mode 100644 index 0000000..e4ba5ca --- /dev/null +++ b/app/Filament/Resources/AuthorResource/Pages/CreateAuthor.php @@ -0,0 +1,12 @@ +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') diff --git a/app/Http/Controllers/NewsPageController.php b/app/Http/Controllers/NewsPageController.php index 5b12913..98f4bb1 100644 --- a/app/Http/Controllers/NewsPageController.php +++ b/app/Http/Controllers/NewsPageController.php @@ -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) diff --git a/app/Models/Author.php b/app/Models/Author.php new file mode 100644 index 0000000..7df0e27 --- /dev/null +++ b/app/Models/Author.php @@ -0,0 +1,23 @@ +hasMany(News::class); + } +} diff --git a/app/Models/News.php b/app/Models/News.php index 8b8a0fc..eac6d8a 100644 --- a/app/Models/News.php +++ b/app/Models/News.php @@ -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); + } } diff --git a/database/migrations/2025_07_28_203958_add_author_description_to_news_table.php b/database/migrations/2025_07_28_203958_add_author_description_to_news_table.php new file mode 100644 index 0000000..b096cbb --- /dev/null +++ b/database/migrations/2025_07_28_203958_add_author_description_to_news_table.php @@ -0,0 +1,28 @@ +longText('author_description')->nullable()->after('author'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('news', function (Blueprint $table) { + $table->dropColumn('author_description'); + }); + } +}; diff --git a/database/migrations/2025_07_28_204249_create_authors_table.php b/database/migrations/2025_07_28_204249_create_authors_table.php new file mode 100644 index 0000000..458171f --- /dev/null +++ b/database/migrations/2025_07_28_204249_create_authors_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('name'); + $table->longText('description')->nullable(); + $table->string('profile_image')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('authors'); + } +}; diff --git a/database/migrations/2025_07_28_204324_add_author_id_to_news_table.php b/database/migrations/2025_07_28_204324_add_author_id_to_news_table.php new file mode 100644 index 0000000..13aa016 --- /dev/null +++ b/database/migrations/2025_07_28_204324_add_author_id_to_news_table.php @@ -0,0 +1,33 @@ +foreignId('author_id')->nullable()->constrained()->onDelete('set null'); + $table->dropColumn('author'); + $table->dropColumn('author_description'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('news', function (Blueprint $table) { + $table->dropForeign(['author_id']); + $table->dropColumn('author_id'); + $table->string('author')->nullable(); + $table->string('author_description')->nullable(); + }); + } +}; diff --git a/resources/views/web/pages/news/show.blade.php b/resources/views/web/pages/news/show.blade.php index f72ca5e..5ad0d92 100644 --- a/resources/views/web/pages/news/show.blade.php +++ b/resources/views/web/pages/news/show.blade.php @@ -20,68 +20,101 @@ - -
Comments ({{ $news->comments->count() }})
-{{ $comment->title }}
- By {{ $comment->author_name ?? 'Anonymous' }} on {{ \Carbon\Carbon::parse($comment->created_at)->format('d M, Y') }} -{{ $comment->message }}
-Comments ({{ $news->comments->count() }})
+ @forelse ($news->comments as $comment) +{{ $comment->title ?? '-' }}
+ Submitted {{ $comment->created_at->diffForHumans() }} by {{ $comment->author_name ?? 'Anonymous' }} +{{ $comment->message }}
Leave a Comment
-No comments yet
+ @endforelse +Post Comment
+Required fields are marked
+