feat: extract fuel.station-list Livewire component

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ovidiu U
2026-04-07 22:02:08 +01:00
parent 266051c52b
commit a576ef6b4a
3 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Livewire\Public\Fuel;
use Illuminate\View\View;
use Livewire\Attributes\On;
use Livewire\Component;
final class StationList extends Component
{
public array $results = [];
public array $meta = [];
public bool $hasSearched = false;
public string $search = '';
public int $radius = 5;
#[On('stations-found')]
public function handle(array $results, array $meta, int $radius = 5, ?array $prediction = null): void
{
$this->results = $results;
$this->meta = $meta;
$this->radius = $radius;
$this->hasSearched = true;
}
public function render(): View
{
return view('livewire.public.fuel.station-list');
}
}

View File

@@ -0,0 +1,24 @@
<div>
@if ($hasSearched)
<div class="px-5 pb-5">
@if (! empty($meta))
<div class="mb-3 flex items-center justify-between">
<h3 class="text-base font-bold text-text-base">Stations Nearby</h3>
<span class="text-[10px] font-bold uppercase tracking-widest text-text-muted">
{{ $meta['count'] ?? 0 }} {{ str('Result')->plural($meta['count'] ?? 0) }}
</span>
</div>
@endif
@forelse ($results as $station)
<div class="mb-2">
<x-fuel.station-card :station="$station" />
</div>
@empty
<p class="text-sm text-text-muted">
No stations found within {{ $radius }} {{ str('mile')->plural($radius) }} of "{{ $search }}".
</p>
@endforelse
</div>
@endif
</div>

View File

@@ -0,0 +1,73 @@
<?php
use App\Livewire\Public\Fuel\StationList;
use Livewire\Livewire;
it('renders empty state before any search', function () {
Livewire::test(StationList::class)
->assertStatus(200)
->assertSet('hasSearched', false)
->assertDontSee('Stations Nearby');
});
it('shows station cards after stations-found event', function () {
$station = [
'station_id' => 'abc123',
'name' => 'BP Garage',
'brand' => 'BP',
'is_supermarket' => false,
'address' => '1 High Street',
'postcode' => 'SW1A 1AA',
'lat' => 51.5074,
'lng' => -0.1278,
'distance_km' => 1.5,
'fuel_type' => 'e10',
'price_pence' => 14390,
'price' => 143.9,
'price_updated_at' => '2026-04-05T08:00:00.000Z',
'price_classification' => 'current',
'price_classification_label' => 'Current',
];
$meta = ['count' => 1, 'lowest_pence' => 14390, 'avg_pence' => 14390.0];
Livewire::test(StationList::class)
->dispatch('stations-found', results: [$station], meta: $meta, prediction: null, radius: 5)
->assertSet('hasSearched', true)
->assertSee('Stations Nearby')
->assertSee('BP Garage')
->assertSee('1 Result');
});
it('shows empty state message when stations-found has no results', function () {
Livewire::test(StationList::class)
->set('search', 'ZZ99 9ZZ')
->dispatch('stations-found', results: [], meta: ['count' => 0], prediction: null, radius: 5)
->assertSet('hasSearched', true)
->assertSee('No stations found');
});
it('updates results when stations-found fires again', function () {
$station = [
'station_id' => 'abc123',
'name' => 'BP Garage',
'brand' => 'BP',
'is_supermarket' => false,
'address' => '1 High Street',
'postcode' => 'SW1A 1AA',
'lat' => 51.5074,
'lng' => -0.1278,
'distance_km' => 1.5,
'fuel_type' => 'e10',
'price_pence' => 14390,
'price' => 143.9,
'price_updated_at' => '2026-04-05T08:00:00.000Z',
'price_classification' => 'current',
'price_classification_label' => 'Current',
];
Livewire::test(StationList::class)
->dispatch('stations-found', results: [$station], meta: ['count' => 1], prediction: null, radius: 5)
->assertSee('BP Garage')
->dispatch('stations-found', results: [], meta: ['count' => 0], prediction: null, radius: 5)
->assertDontSee('BP Garage');
});