feat: extract fuel.station-list Livewire component
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
34
app/Livewire/Public/Fuel/StationList.php
Normal file
34
app/Livewire/Public/Fuel/StationList.php
Normal 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');
|
||||
}
|
||||
}
|
||||
24
resources/views/livewire/public/fuel/station-list.blade.php
Normal file
24
resources/views/livewire/public/fuel/station-list.blade.php
Normal 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>
|
||||
73
tests/Feature/Livewire/Fuel/StationListTest.php
Normal file
73
tests/Feature/Livewire/Fuel/StationListTest.php
Normal 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');
|
||||
});
|
||||
Reference in New Issue
Block a user