Files
fuel-price/.claude/rules/livewire.md
Ovidiu U 5ad89e977d Add fuel API ingestion and historic storage design spec
Includes verified API authentication flow, correct base URL, all DB
table schemas for stations, current prices, history, and archive.
Fuel types corrected to match live API (B7_STANDARD, B7_PREMIUM).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 18:09:50 +01:00

2.2 KiB

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:

<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"