diff --git a/resources/js/components/LeafletMap.vue b/resources/js/components/LeafletMap.vue index 6e7abcb..fc1aa92 100644 --- a/resources/js/components/LeafletMap.vue +++ b/resources/js/components/LeafletMap.vue @@ -40,7 +40,6 @@ import {ref, watch, onMounted, onUnmounted, nextTick} from 'vue' import L from 'leaflet' import 'leaflet/dist/leaflet.css' -import {zoom} from "leaflet/src/control/Control.Zoom.js"; const CLASSIFICATION_COLOURS = { current: '#22c55e', @@ -56,37 +55,28 @@ const CLASSIFICATION_BORDER_COLOURS = { outdated: '#dc2626', } -function buildMarkerHtml(station, index, colour, borderColour) { +function buildDirectionsUrl(station, origin) { + const base = `https://www.google.com/maps/dir/?api=1&destination=${station.lat},${station.lng}` + if (origin?.lat != null && origin?.lng != null) { + return `${base}&origin=${origin.lat},${origin.lng}` + } + return base +} + +function buildMarkerHtml(station, index, colour, borderColour, origin) { const isFirst = index === 0 - const w = isFirst ? 63 : 59 - const h = isFirst ? 58 : 51 - const bw = isFirst ? 56 : 52 - const bh = isFirst ? 43 : 38 - const br = isFirst ? 17 : 15 - const tailTop = isFirst ? 45 : 40 - const tailW = isFirst ? 9 : 7 - const tailH = isFirst ? 11 : 9 - const badgeSize = isFirst ? 18 : 16 - const badgeFontSize = isFirst ? 10 : 8 - const priceFontSize = isFirst ? 12 : 11 + const h = isFirst ? 20 : 18 + const fontSize = isFirst ? 11 : 10 + const iconSize = isFirst ? 11 : 10 + const star = isFirst + ? `` + : '' - const initial = escHtml((station.brand || station.name || '?')[0].toUpperCase()) + const directionsUrl = escHtml(buildDirectionsUrl(station, origin)) + const navSvg = `` - const badge = isFirst - ? `
` - : `
${index + 1}
` - - return `
- ${badge} -
-
- ${initial} -
-
- ${Number(station.price).toFixed(1)}p -
-
-
+ return `
+ ${star}${Number(station.price).toFixed(1)}${navSvg}
` } @@ -102,6 +92,7 @@ const props = defineProps({ stations: {type: Array, required: true}, defaultOpen: {type: Boolean, default: false}, radiusMiles: {type: Number, default: 10}, + origin: {type: Object, default: null}, }) const mapContainer = ref(null) @@ -216,22 +207,29 @@ function renderMarkers() { ` const isFirst = index === 0 - const w = isFirst ? 63 : 59 - const h = isFirst ? 58 : 51 + const w = isFirst ? 65 : 56 + const h = isFirst ? 20 : 18 const icon = L.divIcon({ className: '', iconSize: [w, h], - iconAnchor: [w / 2, h], - html: buildMarkerHtml(station, index, colour, borderColour), + iconAnchor: [w / 2, h / 2], + html: buildMarkerHtml(station, index, colour, borderColour, props.origin), }) const marker = L.marker([station.lat, station.lng], {icon}).bindPopup(popup) + marker.on('click', () => { + const target = Math.max(mapInstance.getZoom(), 16) + mapInstance.setView([station.lat, station.lng], target, {animate: true}) + }) + markersLayer.addLayer(marker) bounds.push([station.lat, station.lng]) }) + const zoom = getZoomForRadius(props.radiusMiles) + if (bounds.length === 1) { mapInstance.setView(bounds[0], zoom) } else { diff --git a/resources/js/components/SearchBar.vue b/resources/js/components/SearchBar.vue index b381017..4c60714 100644 --- a/resources/js/components/SearchBar.vue +++ b/resources/js/components/SearchBar.vue @@ -20,14 +20,14 @@ id="postcode-input" v-model="postcode" type="text" - placeholder="Enter postcode, e.g. SW1A 1AA" + :placeholder="coords ? 'Using your current location' : 'Enter postcode, e.g. SW1A 1AA'" class="w-full h-14 pr-28 pl-4 bg-white border border-zinc-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-accent shadow-inner text-base" @keyup.enter="onSearch" />