From 7761eaed2efa856c0738838dd58158e0196b0596 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Tue, 27 Jan 2026 23:43:50 +0700 Subject: [PATCH] feat: Extract contact reply action into a dedicated class and add a reply status filter to the contact table. --- .../Manage/Contacts/Actions/ReplyAction.php | 49 +++++++++++++++ .../Manage/Contacts/ContactResource.php | 60 +++++-------------- 2 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 app/Filament/Resources/Manage/Contacts/Actions/ReplyAction.php diff --git a/app/Filament/Resources/Manage/Contacts/Actions/ReplyAction.php b/app/Filament/Resources/Manage/Contacts/Actions/ReplyAction.php new file mode 100644 index 0000000..154aeae --- /dev/null +++ b/app/Filament/Resources/Manage/Contacts/Actions/ReplyAction.php @@ -0,0 +1,49 @@ +label('Balas') + ->icon(Heroicon::ChatBubbleLeftRight) + ->color('success') + ->modalHeading('Balas Pesan Kontak') + ->modalDescription('Pesan balasan tidak bisa diubah setelah dikirim.') + ->schema([ + Textarea::make('reply_message') + ->label('Pesan Balasan') + ->placeholder(fn (Contact $record): string => "Halo {$record->name}, ...") + ->required() + ->rows(5) + ->autocomplete(false) + ->autofocus(), + ]) + ->action(function (Contact $record, array $data): void { + Mail::to($record->email)->send(new ContactReplyMail($record, $data['reply_message'])); + + $record->update([ + 'reply_message' => $data['reply_message'], + 'replied_at' => now(), + 'replied_by' => auth()->id(), + ]); + + CheerfulNotification::success( + 'Balasan Terkirim! 🚀✉️', + 'Pesan balasan Anda sudah meluncur ke email pengirim. Semoga membantu mereka ya! 😊' + )->send(); + }) + ->visible(fn (Contact $record): bool => $record->replied_at === null); + } +} diff --git a/app/Filament/Resources/Manage/Contacts/ContactResource.php b/app/Filament/Resources/Manage/Contacts/ContactResource.php index 2a773a8..b488fc3 100644 --- a/app/Filament/Resources/Manage/Contacts/ContactResource.php +++ b/app/Filament/Resources/Manage/Contacts/ContactResource.php @@ -4,15 +4,12 @@ use App\Filament\Actions\Cheerful\DeleteAction; use App\Filament\Actions\DefaultBulkActions; +use App\Filament\Resources\Manage\Contacts\Actions\ReplyAction; use App\Filament\Resources\Manage\Contacts\Pages\ManageContacts; -use App\Filament\Support\CheerfulNotification; -use App\Mail\ContactReplyMail; use App\Models\Contact; use BackedEnum; -use Filament\Actions\Action; use Filament\Actions\BulkActionGroup; use Filament\Actions\ViewAction; -use Filament\Forms\Components\Textarea; use Filament\Infolists\Components\TextEntry; use Filament\Resources\Resource; use Filament\Schemas\Components\Grid; @@ -21,8 +18,8 @@ use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Filters\TernaryFilter; use Filament\Tables\Table; -use Illuminate\Support\Facades\Mail; use UnitEnum; class ContactResource extends Resource @@ -48,14 +45,6 @@ public static function getNavigationBadge(): ?string return static::getModel()::where('replied_at', null)->count(); } - public static function form(Schema $schema): Schema - { - return $schema - ->components([ - // Form usually not needed as we use View/Reply - ]); - } - public static function infolist(Schema $schema): Schema { return $schema @@ -142,42 +131,22 @@ public static function table(Table $table): Table ->sortable(), ]) ->filters([ - // + TernaryFilter::make('replied_at') + ->label('Status Balasan') + ->placeholder('Semua Pesan') + ->trueLabel('Sudah Dibalas') + ->falseLabel('Belum Dibalas') + ->queries( + true: fn ($query) => $query->whereNotNull('replied_at'), + false: fn ($query) => $query->whereNull('replied_at'), + ) + ->native(false), ]) ->recordActions([ ViewAction::make() ->label('Lihat'), - Action::make('reply') - ->label('Balas') - ->icon(Heroicon::ChatBubbleLeftRight) - ->color('success') - ->modalHeading('Balas Pesan Kontak') - ->modalDescription('Pesan balasan tidak bisa diubah setelah dikirim.') - ->schema([ - Textarea::make('reply_message') - ->label('Pesan Balasan') - ->placeholder(fn (Contact $record): string => "Halo {$record->name}, ...") - ->required() - ->rows(5) - ->autocomplete(false) - ->autofocus(), - ]) - ->action(function (Contact $record, array $data): void { - Mail::to($record->email)->send(new ContactReplyMail($record, $data['reply_message'])); - - $record->update([ - 'reply_message' => $data['reply_message'], - 'replied_at' => now(), - 'replied_by' => auth()->id(), - ]); - - CheerfulNotification::success( - 'Balasan Terkirim! 🚀✉️', - 'Pesan balasan Anda sudah meluncur ke email pengirim. Semoga membantu mereka ya! 😊' - )->send(); - }) - ->visible(fn (Contact $record): bool => $record->replied_at === null), + ReplyAction::make('reply'), DeleteAction::make() ->label('Hapus'), @@ -190,8 +159,7 @@ public static function table(Table $table): Table ->emptyStateIcon(Heroicon::Envelope) ->emptyStateDescription('Belum ada kontak atau pesan masuk.') ->defaultSort('created_at', 'desc') - ->deferFilters(false) - ->reorderable('sort_order'); + ->deferFilters(false); } public static function getPages(): array