feat: Extract contact reply action into a dedicated class and add a reply status filter to the contact table.
This commit is contained in:
parent
829b857ce9
commit
7761eaed2e
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\Manage\Contacts\Actions;
|
||||
|
||||
use App\Filament\Support\CheerfulNotification;
|
||||
use App\Mail\ContactReplyMail;
|
||||
use App\Models\Contact;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class ReplyAction extends Action
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->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);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user