# Livewire Components

## Classic two-file components only

Do NOT use Volt single-file syntax for new components.
Volt files created by the Livewire starter kit (auth screens) are left untouched.

## Component locations

```
app/Livewire/
├── Dashboard/
│   ├── FuelRecommendation.php    # Main fill-up/wait card
│   ├── NearbyStations.php        # Map + station list
│   └── PriceHistory.php          # 14-day trend chart
├── Account/
│   ├── NotificationSettings.php  # Channel prefs + WhatsApp OTP
│   ├── SubscriptionManager.php   # Upgrade/downgrade UI
│   └── FuelPreferences.php       # Fuel type, postcode
└── Public/
    └── PriceWatchdog.php         # Public-facing local price watchdog
```

## Component conventions

- Component properties that are shown in the view must be `public`
- Use `#[Computed]` attribute for derived values — not re-computed on every render
- Validate with `#[Validate]` attribute on properties, not in separate rules array
- Never put Service instantiation in the component — inject via method parameter or mount()
- Dispatch browser events with `$this->dispatch()` not `$this->emit()` (Livewire 3 syntax)
- Use `wire:loading` on all buttons that trigger server actions

## Alpine.js usage

Alpine.js handles local UI state only: dropdowns, modals, tab switching, copy-to-clipboard.
Do not replicate server state in Alpine — use Livewire for anything that needs PHP.
Alpine components stay inline in Blade (`x-data="{}"`), not in separate JS files unless reused 3+ times.

## Map (Leaflet.js)

Leaflet is a plain JS drop-in, not a Livewire component.
Station data is fetched from a dedicated Livewire endpoint and passed to Leaflet via Alpine:
```blade
<div
    x-data="stationMap(@entangle('stations'))"
    id="map"
    style="height: 400px"
></div>
```
Map initialisation lives in `resources/js/maps/station-map.js`.

## Page routing

Livewire full-page components are mounted in `routes/web.php` using `Route::get()->component()`.
No separate view files for pages — the Livewire component IS the page.

---
paths:
  - "app/Livewire/**/*.php"
  - "resources/views/livewire/**/*.blade.php"
---
