Redesign the Payment view page infolist

Groups fields into Payment/Timeline sections with icons, copyable IDs, and
a money-formatted amount. Drops the permission-gated Gateway Response
section (raw gateway_payload) and its two visibility tests along with it.
This commit is contained in:
Nyan Lin Paing
2026-08-30 15:46:19 +07:00
parent bebcab88fa
commit 95b369174d
2 changed files with 33 additions and 43 deletions
@@ -6,6 +6,7 @@ use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Modules\Payment\Enums\PaymentStatus; use Modules\Payment\Enums\PaymentStatus;
class PaymentInfolist class PaymentInfolist
@@ -15,40 +16,51 @@ class PaymentInfolist
return $schema return $schema
->components([ ->components([
Section::make('Payment') Section::make('Payment')
->icon(Heroicon::OutlinedBanknotes)
->schema([ ->schema([
Grid::make(4) Grid::make(4)
->schema([ ->schema([
TextEntry::make('booking.booking_ref')->label('Booking'), TextEntry::make('booking.booking_ref')
TextEntry::make('gateway')->badge(), ->label('Booking')
->icon(Heroicon::OutlinedTicket)
->copyable(),
TextEntry::make('gateway')
->icon(Heroicon::OutlinedCreditCard)
->badge(),
TextEntry::make('status') TextEntry::make('status')
->icon(Heroicon::OutlinedCheckCircle)
->badge() ->badge()
->color(fn (PaymentStatus $state) => match ($state) { ->color(fn (PaymentStatus $state) => match ($state) {
PaymentStatus::Pending => 'warning', PaymentStatus::Pending => 'warning',
PaymentStatus::Completed => 'success', PaymentStatus::Completed => 'success',
PaymentStatus::Failed => 'danger', PaymentStatus::Failed => 'danger',
}), }),
TextEntry::make('gateway_transaction_id')->label('Gateway Txn ID'), TextEntry::make('amount')
TextEntry::make('amount')->numeric(2), ->label('Amount')
TextEntry::make('currency'), ->icon(Heroicon::OutlinedCurrencyDollar)
TextEntry::make('initiated_at')->dateTime(), ->money(fn ($record) => $record->currency)
TextEntry::make('completed_at')->dateTime()->placeholder('—'), ->weight('bold'),
]), ]),
]), ]),
// Raw gateway response — may include data not meant for the Section::make('Timeline')
// support role, so it's gated the same as refund initiation ->icon(Heroicon::OutlinedClock)
// (process_refunds: admin/super_admin only, domain.md §6).
Section::make('Gateway Response')
->visible(fn () => auth()->user()?->can('process_refunds') ?? false)
->schema([ ->schema([
TextEntry::make('gateway_payload') Grid::make(3)
->label('') ->schema([
->formatStateUsing(fn (mixed $state) => match (true) { TextEntry::make('gateway_transaction_id')
is_array($state) => json_encode($state, JSON_PRETTY_PRINT), ->label('Gateway Txn ID')
is_string($state) && $state !== '' => $state, ->icon(Heroicon::OutlinedHashtag)
default => null, ->copyable()
}) ->placeholder('—'),
->placeholder('—') TextEntry::make('initiated_at')
->columnSpanFull(), ->icon(Heroicon::OutlinedPlayCircle)
->dateTime()
->placeholder('—'),
TextEntry::make('completed_at')
->icon(Heroicon::OutlinedFlag)
->dateTime()
->placeholder('—'),
]),
]), ]),
]); ]);
} }
@@ -56,25 +56,3 @@ test('can view a payment\'s detail page', function () {
->assertSee($booking->booking_ref) ->assertSee($booking->booking_ref)
->assertSee('EVB-VIEWTEST-1'); ->assertSee('EVB-VIEWTEST-1');
}); });
test('the gateway response is visible to a user with process_refunds', function () {
$admin = User::factory()->create()->givePermissionTo(['view_payments', 'process_refunds']);
$this->actingAs($admin);
$payment = Payment::factory()->create(['gateway_payload' => ['prepay_id' => 'PREPAY-SECRET-123']]);
Livewire::test(ViewPayment::class, ['record' => $payment->getRouteKey()])
->assertOk()
->assertSee('PREPAY-SECRET-123');
});
test('the gateway response is hidden from a user without process_refunds', function () {
$support = User::factory()->create()->givePermissionTo('view_payments');
$this->actingAs($support);
$payment = Payment::factory()->create(['gateway_payload' => ['prepay_id' => 'PREPAY-SECRET-123']]);
Livewire::test(ViewPayment::class, ['record' => $payment->getRouteKey()])
->assertOk()
->assertDontSee('PREPAY-SECRET-123');
});