Files
fuel-price/docs/superpowers/specs/2026-04-11-homepage-search-design.md
2026-04-11 17:15:23 +01:00

2.8 KiB

Homepage Search — Design Spec

Date: 2026-04-11
Status: Approved

Overview

Wire up the SearchBar on the homepage so it performs a live station search and renders a map + station list inline, below the search bar. No navigation away from the page. All existing components (LeafletMap, StationList, useStations) are reused as-is, with minimal targeted changes.


Component Changes

SearchBar.vue

  • Add a fuel type <select> with options: E10, E5, Diesel (B7), Premium Diesel (B7), B10, HVO
  • Add a radius <select> with options: 2, 5, 10, 20 miles (default: 10)
  • Change the search emit payload from a bare postcode string to { postcode, fuelType, radius }
  • Remove the debounced onInput handler — search fires on button click only (debounce on a multi-param form causes confusing mid-type fetches)
  • Button stays disabled when postcode is empty

LeafletMap.vue

  • Add a defaultOpen Boolean prop (default false) for backwards compatibility
  • When defaultOpen is true, initialise the map on onMounted instead of waiting for the toggle
  • Toggle button remains so users can collapse the map
  • Auto-renders markers when stations prop is populated after mount

Home.vue

  • Import useStations and hold sort ref (default 'price')
  • On @search from SearchBar, call useStations.search({ postcode, fuelType, radius, sort })
  • Add a results <section> directly below the hero section — full width, max-w-7xl container, px-6 py-10 padding
  • Results section only renders when a search has been attempted (stations.length || loading || error)
  • Results layout (top to bottom):
    1. LeafletMap with :stations="stations" and :default-open="true"h-80 height
    2. StationList with :stations="stations" :current-sort="sort" @sort="onSort"
  • Loading state: spinner centred in the results section, replaces map+list
  • Error state: inline error message (error.general[0] or fallback text), replaces map+list
  • onSort handler updates sort ref and re-runs search() with last used params (store params in a lastParams ref)

Data Flow

SearchBar emits { postcode, fuelType, radius }
  → Home.vue calls useStations.search({ ...params, sort })
    → API GET /stations?postcode=...&fuel_type=...&radius=...&sort=...
      → stations ref populated
        → LeafletMap renders markers (auto-open)
        → StationList renders cards

What Is Not Changing

  • StationCard.vue — no changes
  • useStations.js — no changes
  • API layer — no changes
  • Dashboard usage of LeafletMap and StationList — unaffected (defaultOpen defaults to false)

Out of Scope

  • Saving/favouriting stations from homepage (dashboard feature)
  • Geolocation "use my location" button
  • Pagination of results