Files
fuel-price/livewire.md
Ovidiu U 02d4c9d888
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Add comprehensive project documentation and architecture guidelines
Establishes core rules and conventions for the FuelAlert Laravel application: architecture patterns (fat services, thin controllers), database schema with partitioned station_prices table, multi-tier notification system with Vonage and OneSignal, 4-signal scoring engine for fuel price recommendations, Stripe subscription tiers, Livewire classic component structure, and Pest testing standards.
2026-04-03 16:49:19 +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"