docs: add homepage search design spec
This commit is contained in:
70
docs/superpowers/specs/2026-04-11-homepage-search-design.md
Normal file
70
docs/superpowers/specs/2026-04-11-homepage-search-design.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user