feat: add user geolocation marker and auto-zoom to map based on search radius
This commit is contained in:
41
docs/theme.md
Normal file
41
docs/theme.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# FuelAlert — Colour Palette
|
||||||
|
|
||||||
|
## Primary — Burnt Sienna
|
||||||
|
| Token | Hex | Usage |
|
||||||
|
|--------------|-----------|------------------------------|
|
||||||
|
| primary | `#bb5b3e` | CTA buttons, focus rings, brand |
|
||||||
|
| primary-dark | `#a34a31` | Hover / pressed state |
|
||||||
|
|
||||||
|
## Neutrals — Warm Brown
|
||||||
|
| Token | Hex | Usage |
|
||||||
|
|-----------|-----------|------------------------------|
|
||||||
|
| text-base | `#4a3f3b` | Body text, headings |
|
||||||
|
| text-muted| `#89726c` | Secondary text, icons |
|
||||||
|
| text-dim | `#6b5a55` | Tertiary / placeholder text |
|
||||||
|
|
||||||
|
## Surfaces — Cream / Linen
|
||||||
|
| Token | Hex | Usage |
|
||||||
|
|----------------|-----------|------------------------------|
|
||||||
|
| surface | `#faf6f3` | Input & card background |
|
||||||
|
| surface-page | `#f5ede5` | Page / app background |
|
||||||
|
| surface-subtle | `#eeeae5` | Subtle surface / hover |
|
||||||
|
| border | `#e5ded7` | Borders & dividers |
|
||||||
|
|
||||||
|
## Accents
|
||||||
|
| Token | Hex | Usage |
|
||||||
|
|--------|-----------|------------------------------|
|
||||||
|
| teal | `#4A7C7E` | Secondary accent (minor) |
|
||||||
|
| mauve | `#8B4860` | Tertiary accent (minor) |
|
||||||
|
| tan | `#9B8B6B` | Warm neutral accent |
|
||||||
|
|
||||||
|
## Status
|
||||||
|
| Token | Hex | Usage |
|
||||||
|
|---------|-----------|------------------------------|
|
||||||
|
| success | `#22c55e` | Price current / good signal |
|
||||||
|
| warning | `#f59e0b` | Stale price / weak signal |
|
||||||
|
| error | `#ef4444` | Outdated price / error state |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Core brand feel: warm terracotta on a cream/linen base.
|
||||||
|
- Teal and mauve are currently used sparingly — confirm role in DaisyUI theme before promoting to named tokens.
|
||||||
|
- Never use cold grays — all neutrals should lean warm.
|
||||||
@@ -26,15 +26,38 @@ const CLASSIFICATION_COLOURS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const UK_CENTRE = [54.0, -2.0];
|
const UK_CENTRE = [54.0, -2.0];
|
||||||
const UK_ZOOM = 6;
|
const UK_ZOOM = 7;
|
||||||
|
|
||||||
export function stationMap(results) {
|
const USER_MARKER_CSS = `
|
||||||
|
@keyframes fuelalert-pulse {
|
||||||
|
0% { transform: scale(1); opacity: 0.6; }
|
||||||
|
70% { transform: scale(2.8); opacity: 0; }
|
||||||
|
100% { transform: scale(1); opacity: 0; }
|
||||||
|
}
|
||||||
|
.fuelalert-user-marker { position: relative; width: 16px; height: 16px; }
|
||||||
|
.fuelalert-user-dot { position: absolute; inset: 0; border-radius: 50%; background: #3b82f6; border: 2px solid #fff; box-shadow: 0 0 0 2px #3b82f6; }
|
||||||
|
.fuelalert-user-ring { position: absolute; inset: 0; border-radius: 50%; background: #3b82f6; animation: fuelalert-pulse 2s ease-out infinite; }
|
||||||
|
`;
|
||||||
|
|
||||||
|
function injectUserMarkerStyles() {
|
||||||
|
if (document.getElementById('fuelalert-user-marker-styles')) return;
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.id = 'fuelalert-user-marker-styles';
|
||||||
|
style.textContent = USER_MARKER_CSS;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stationMap(results, meta, radius) {
|
||||||
return {
|
return {
|
||||||
results,
|
results,
|
||||||
|
meta,
|
||||||
|
radius,
|
||||||
_map: null,
|
_map: null,
|
||||||
_markers: [],
|
_markers: [],
|
||||||
|
_userMarker: null,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
injectUserMarkerStyles();
|
||||||
this._map = L.map(this.$el, { zoomControl: true }).setView(UK_CENTRE, UK_ZOOM);
|
this._map = L.map(this.$el, { zoomControl: true }).setView(UK_CENTRE, UK_ZOOM);
|
||||||
|
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
@@ -47,6 +70,18 @@ export function stationMap(results) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.$watch('results', () => this._plotMarkers());
|
this.$watch('results', () => this._plotMarkers());
|
||||||
|
this.locateUser();
|
||||||
|
},
|
||||||
|
|
||||||
|
getZoomForRadius(radiusMiles) {
|
||||||
|
if (radiusMiles <= 1) return 15;
|
||||||
|
if (radiusMiles <= 2) return 14;
|
||||||
|
if (radiusMiles <= 5) return 12;
|
||||||
|
if (radiusMiles <= 10) return 11;
|
||||||
|
if (radiusMiles <= 15) return 10;
|
||||||
|
if (radiusMiles <= 25) return 9;
|
||||||
|
if (radiusMiles <= 50) return 8;
|
||||||
|
return 7;
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearMarkers() {
|
_clearMarkers() {
|
||||||
@@ -54,11 +89,61 @@ export function stationMap(results) {
|
|||||||
this._markers = [];
|
this._markers = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addUserMarker(lat, lng) {
|
||||||
|
if (this._userMarker) {
|
||||||
|
this._userMarker.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const icon = L.divIcon({
|
||||||
|
className: '',
|
||||||
|
html: '<div class="fuelalert-user-marker"><div class="fuelalert-user-ring"></div><div class="fuelalert-user-dot"></div></div>',
|
||||||
|
iconSize: [16, 16],
|
||||||
|
iconAnchor: [8, 8],
|
||||||
|
});
|
||||||
|
|
||||||
|
this._userMarker = L.marker([lat, lng], { icon, zIndexOffset: 1000 })
|
||||||
|
.bindPopup('Your location')
|
||||||
|
.addTo(this._map);
|
||||||
|
|
||||||
|
console.log(`[stationMap] user marker lat=${lat} lng=${lng}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
locateUser() {
|
||||||
|
if (!navigator.geolocation) {
|
||||||
|
console.warn('[stationMap] Geolocation not supported');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ipFallback = () => {
|
||||||
|
fetch('https://ipapi.co/json/')
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((d) => d.latitude && d.longitude && this.addUserMarker(d.latitude, d.longitude))
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Quick low-accuracy fix first — places the marker immediately.
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
(pos) => {
|
||||||
|
this.addUserMarker(pos.coords.latitude, pos.coords.longitude);
|
||||||
|
|
||||||
|
// Then refine with high accuracy if GPS is available.
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
(precise) => this.addUserMarker(precise.coords.latitude, precise.coords.longitude),
|
||||||
|
() => {},
|
||||||
|
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
() => ipFallback(),
|
||||||
|
{ enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
if (this._map) {
|
if (this._map) {
|
||||||
this._map.remove();
|
this._map.remove();
|
||||||
this._map = null;
|
this._map = null;
|
||||||
this._markers = [];
|
this._markers = [];
|
||||||
|
this._userMarker = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -72,8 +157,6 @@ export function stationMap(results) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bounds = [];
|
|
||||||
|
|
||||||
this.results.forEach((station) => {
|
this.results.forEach((station) => {
|
||||||
const colour = escHtml(CLASSIFICATION_COLOURS[station.price_classification] ?? '#64748b');
|
const colour = escHtml(CLASSIFICATION_COLOURS[station.price_classification] ?? '#64748b');
|
||||||
const miles = (station.distance_km * 0.621371).toFixed(1);
|
const miles = (station.distance_km * 0.621371).toFixed(1);
|
||||||
@@ -101,14 +184,18 @@ export function stationMap(results) {
|
|||||||
|
|
||||||
marker.addTo(this._map);
|
marker.addTo(this._map);
|
||||||
this._markers.push(marker);
|
this._markers.push(marker);
|
||||||
bounds.push([station.lat, station.lng]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (bounds.length === 1) {
|
const map = this._map;
|
||||||
this._map.setView(bounds[0], 14);
|
const lat = this.meta?.lat;
|
||||||
} else {
|
const lng = this.meta?.lng;
|
||||||
this._map.fitBounds(bounds, { padding: [40, 40], maxZoom: 14 });
|
const zoom = this.getZoomForRadius(this.radius);
|
||||||
}
|
|
||||||
|
setTimeout(() => {
|
||||||
|
map.invalidateSize();
|
||||||
|
map.setView([lat, lng], zoom, { animate: true, duration: 0.5 });
|
||||||
|
console.log(`[stationMap] setView lat=${lat} lng=${lng} zoom=${zoom} (radius=${this.radius}mi)`);
|
||||||
|
}, 50);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@props(['results' => []])
|
@props(['results' => []])
|
||||||
|
|
||||||
<div
|
<div
|
||||||
x-data="stationMap(@entangle('results'))"
|
x-data="stationMap(@entangle('results'), @entangle('meta'), @entangle('radius'))"
|
||||||
class="h-56 w-full overflow-hidden border-y border-[#e5ded7] md:h-96"
|
class="h-56 w-full overflow-hidden border-y border-[#e5ded7] md:h-96"
|
||||||
></div>
|
></div>
|
||||||
|
|||||||
@@ -2,53 +2,148 @@
|
|||||||
|
|
||||||
<x-mobile-header />
|
<x-mobile-header />
|
||||||
|
|
||||||
{{-- Scrollable main content, offset for fixed header (~80px) and footer (~80px) --}}
|
{{-- Scrollable main content, offset for fixed header (~112px) and footer (~80px) --}}
|
||||||
<main
|
<main
|
||||||
class="flex-1 overflow-y-auto pt-[80px] pb-[80px]"
|
class="flex-1 overflow-y-auto pt-28 pb-20"
|
||||||
style="-ms-overflow-style:none;scrollbar-width:none;"
|
style="-ms-overflow-style:none;scrollbar-width:none;"
|
||||||
>
|
>
|
||||||
|
|
||||||
{{-- #search --}}
|
{{-- #search --}}
|
||||||
<section class="space-y-3 px-5 pt-5 pb-4">
|
<section class="space-y-3 px-5 pt-5 pb-4">
|
||||||
<form wire:submit="findStations">
|
<form wire:submit="findStations">
|
||||||
<div class="relative mb-3">
|
|
||||||
|
<div
|
||||||
|
x-data="{
|
||||||
|
query: @js($search),
|
||||||
|
locatingUser: false,
|
||||||
|
_usedIpFallback: false,
|
||||||
|
async _postcodeFromLatLng(lat, lng) {
|
||||||
|
const res = await fetch(`https://api.postcodes.io/postcodes?lon=${lng}&lat=${lat}&limit=1&radius=1000`);
|
||||||
|
const data = await res.json();
|
||||||
|
return data?.result?.[0]?.postcode ?? null;
|
||||||
|
},
|
||||||
|
async locateUser() {
|
||||||
|
this.locatingUser = true;
|
||||||
|
this._usedIpFallback = false;
|
||||||
|
try {
|
||||||
|
let lat, lng;
|
||||||
|
try {
|
||||||
|
const pos = await new Promise((resolve, reject) =>
|
||||||
|
navigator.geolocation.getCurrentPosition(resolve, reject, { enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 })
|
||||||
|
);
|
||||||
|
lat = pos.coords.latitude;
|
||||||
|
lng = pos.coords.longitude;
|
||||||
|
} catch (e) {
|
||||||
|
const d = await fetch('https://ipapi.co/json/').then(r => r.json());
|
||||||
|
lat = d.latitude;
|
||||||
|
lng = d.longitude;
|
||||||
|
this._usedIpFallback = true;
|
||||||
|
}
|
||||||
|
const postcode = await this._postcodeFromLatLng(lat, lng);
|
||||||
|
if (postcode) {
|
||||||
|
this.query = postcode;
|
||||||
|
this.$wire.set('search', postcode);
|
||||||
|
this.$wire.findStations();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// silent
|
||||||
|
} finally {
|
||||||
|
this.locatingUser = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
class="relative mb-3"
|
||||||
|
>
|
||||||
<iconify-icon
|
<iconify-icon
|
||||||
icon="lucide:map-pin"
|
icon="lucide:map-pin"
|
||||||
class="absolute left-4 top-1/2 -translate-y-1/2 text-xl text-[#89726c] pointer-events-none"
|
class="absolute left-4 top-1/2 -translate-y-1/2 text-xl text-[#89726c] pointer-events-none"
|
||||||
></iconify-icon>
|
></iconify-icon>
|
||||||
<input
|
<input
|
||||||
wire:model="search"
|
wire:model="search"
|
||||||
|
x-model="query"
|
||||||
|
x-ref="searchInput"
|
||||||
type="text"
|
type="text"
|
||||||
name="search"
|
name="search"
|
||||||
|
@focus="_usedIpFallback = false"
|
||||||
placeholder="Postcode, town or city"
|
placeholder="Postcode, town or city"
|
||||||
class="h-14 w-full rounded-xl border border-[#e5ded7] bg-[#faf6f3] pl-12 pr-4 text-base font-semibold text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e] focus:border-transparent"
|
class="h-14 w-full rounded-xl border border-[#e5ded7] bg-[#faf6f3] pl-12 pr-36 text-base font-semibold text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e] focus:border-transparent"
|
||||||
/>
|
/>
|
||||||
|
{{-- Right-side controls --}}
|
||||||
|
<div class="absolute inset-y-0 right-0 flex items-center gap-2 pr-3">
|
||||||
|
{{-- Clear --}}
|
||||||
|
<button
|
||||||
|
x-show="query.length > 0"
|
||||||
|
x-cloak
|
||||||
|
type="button"
|
||||||
|
@click="query = ''; $wire.set('search', ''); _usedIpFallback = false"
|
||||||
|
class="text-[#89726c] hover:text-[#4a3f3b]"
|
||||||
|
>
|
||||||
|
<iconify-icon icon="lucide:x" class="text-base"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
{{-- Near me pill --}}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
@click="locateUser()"
|
||||||
|
:disabled="locatingUser"
|
||||||
|
class="flex items-center gap-1.5 rounded-full bg-[#e5ded7] px-3 py-1.5 text-sm font-semibold text-[#4a3f3b] disabled:opacity-40"
|
||||||
|
>
|
||||||
|
<iconify-icon x-show="!locatingUser" icon="lucide:locate-fixed" class="text-sm"></iconify-icon>
|
||||||
|
<iconify-icon x-show="locatingUser" icon="lucide:loader-circle" class="text-sm animate-spin"></iconify-icon>
|
||||||
|
<span x-text="locatingUser ? 'Finding...' : 'Near me'">Near me</span>
|
||||||
|
</button>
|
||||||
|
{{-- Search --}}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
wire:loading.attr="disabled"
|
||||||
|
class="text-[#89726c] disabled:opacity-60"
|
||||||
|
>
|
||||||
|
<iconify-icon wire:loading.remove wire:target="findStations" icon="lucide:search" class="text-xl"></iconify-icon>
|
||||||
|
<iconify-icon wire:loading wire:target="findStations" icon="lucide:loader-circle" class="text-xl animate-spin"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{{-- IP fallback nudge --}}
|
||||||
|
<div
|
||||||
|
x-show="_usedIpFallback"
|
||||||
|
x-cloak
|
||||||
|
x-transition:enter="transition ease-out duration-300 delay-500"
|
||||||
|
x-transition:enter-start="opacity-0 -translate-y-2"
|
||||||
|
x-transition:enter-end="opacity-100 translate-y-0"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
class="absolute top-full left-0 right-0 z-40 mt-2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
@click="$refs.searchInput.focus(); _usedIpFallback = false"
|
||||||
|
class="cursor-pointer rounded-xl border border-amber-200 bg-amber-50 px-3 py-2 transition-colors hover:bg-amber-100"
|
||||||
|
>
|
||||||
|
<p class="text-center text-xs text-amber-800">
|
||||||
|
<span class="font-medium">Showing approximate location.</span>
|
||||||
|
<span class="underline">Enter your postcode above</span> for exact results.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@error('search')
|
@error('search')
|
||||||
<p class="mb-2 text-sm text-red-600">{{ $message }}</p>
|
<p class="mb-2 text-sm text-red-600">{{ $message }}</p>
|
||||||
@enderror
|
@enderror
|
||||||
|
|
||||||
{{-- Filter pills (scrollable row) --}}
|
{{-- Filter rows --}}
|
||||||
<div class="flex gap-2 overflow-x-auto pb-1" style="-ms-overflow-style:none;scrollbar-width:none;">
|
<div class="space-y-2 mb-3">
|
||||||
<div class="shrink-0">
|
<div class="flex gap-2">
|
||||||
<x-fuel.type-select wire:model.live="fuelType" />
|
<div class="shrink-0">
|
||||||
|
<x-fuel.type-select wire:model.live="fuelType" />
|
||||||
|
</div>
|
||||||
|
<div class="shrink-0">
|
||||||
|
<x-fuel.sort-select wire:model.live="sort" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="shrink-0">
|
<div class="flex">
|
||||||
<x-fuel.radius-select wire:model.live="radius" />
|
<div class="shrink-0">
|
||||||
</div>
|
<x-fuel.radius-select wire:model.live="radius" />
|
||||||
<div class="shrink-0">
|
</div>
|
||||||
<x-fuel.sort-select wire:model.live="sort" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
wire:loading.attr="disabled"
|
|
||||||
class="mt-3 w-full rounded-xl bg-[#bb5b3e] py-3.5 text-sm font-bold text-white shadow-md disabled:opacity-60"
|
|
||||||
>
|
|
||||||
<span wire:loading.remove wire:target="findStations">Find Stations</span>
|
|
||||||
<span wire:loading wire:target="findStations">Searching…</span>
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@if ($apiError)
|
@if ($apiError)
|
||||||
@@ -59,14 +154,14 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{-- #recommendation --}}
|
{{-- #recommendation --}}
|
||||||
@if ($prediction)
|
{{-- @if ($prediction)
|
||||||
<section class="px-5 pb-5">
|
<section class="px-5 pb-5">
|
||||||
<x-fuel.recommendation :prediction="$prediction" />
|
<x-fuel.recommendation :prediction="$prediction" />
|
||||||
</section>
|
</section>
|
||||||
@endif
|
@endif --}}
|
||||||
|
|
||||||
{{-- #map --}}
|
{{-- #map --}}
|
||||||
<section class="mb-4">
|
<section class="mb-4" wire:ignore>
|
||||||
<x-fuel.station-map :results="$results" />
|
<x-fuel.station-map :results="$results" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
620
resources/views/mobile.blade.php
Normal file
620
resources/views/mobile.blade.php
Normal file
@@ -0,0 +1,620 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>FuelAlert | Stop Overpaying for Fuel</title>
|
||||||
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600;700;800;900&display=swap" rel="stylesheet">
|
||||||
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
color: #4a3f3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4 {
|
||||||
|
font-family: 'Manrope', sans-serif;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-gradient {
|
||||||
|
background: radial-gradient(circle at top right, #bb5b3e15, transparent 50%),
|
||||||
|
radial-gradient(circle at bottom left, #bb5b3e10, transparent 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-card {
|
||||||
|
background: rgba(250, 246, 243, 0.9);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid rgba(229, 222, 215, 0.6);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-[#f5ede5]">
|
||||||
|
|
||||||
|
{{-- Mobile App Layout (hidden on desktop) --}}
|
||||||
|
<div class="flex flex-col h-dvh md:hidden bg-[#f5ede5]">
|
||||||
|
|
||||||
|
{{-- Mobile Header --}}
|
||||||
|
<header class="shrink-0 pt-14 px-5 pb-4 bg-[#faf6f3] border-b border-[#e5ded7] flex items-center justify-between shadow-sm z-50">
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class="w-10 h-10 rounded-lg bg-[#bb5b3e] flex items-center justify-center shadow-md">
|
||||||
|
<iconify-icon icon="lucide:fuel" class="text-white text-xl"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<span class="text-2xl font-black tracking-tighter text-[#bb5b3e]">FuelAlert</span>
|
||||||
|
</div>
|
||||||
|
<button class="w-10 h-10 rounded-full bg-[#f5ede5] border border-[#e5ded7] flex items-center justify-center">
|
||||||
|
<iconify-icon icon="lucide:user" class="text-[#89726c] text-lg"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{{-- Mobile Scrollable Main --}}
|
||||||
|
<main class="flex-1 overflow-y-auto" style="-ms-overflow-style:none;scrollbar-width:none;">
|
||||||
|
|
||||||
|
{{-- Search & Filters --}}
|
||||||
|
<section class="px-5 pt-5 pb-4 space-y-3">
|
||||||
|
<div class="relative">
|
||||||
|
<iconify-icon icon="lucide:map-pin" class="absolute left-4 top-1/2 -translate-y-1/2 text-[#89726c] text-xl pointer-events-none"></iconify-icon>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter postcode (e.g. SW1A)"
|
||||||
|
value="SW1A 1AA"
|
||||||
|
class="w-full h-14 pl-12 pr-4 bg-[#faf6f3] border border-[#e5ded7] rounded-xl text-base font-semibold text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e] focus:border-transparent"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2 overflow-x-auto pb-1" style="-ms-overflow-style:none;scrollbar-width:none;">
|
||||||
|
<button class="flex items-center gap-1.5 px-4 py-2 bg-[#faf6f3] border border-[#e5ded7] rounded-lg shrink-0 text-sm font-semibold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:droplets" class="text-[#bb5b3e]"></iconify-icon>
|
||||||
|
Petrol
|
||||||
|
<iconify-icon icon="lucide:chevron-down" class="text-[#89726c] text-xs"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
<button class="flex items-center gap-1.5 px-4 py-2 bg-[#faf6f3] border border-[#e5ded7] rounded-lg shrink-0 text-sm font-semibold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:maximize" class="text-[#bb5b3e]"></iconify-icon>
|
||||||
|
5 miles
|
||||||
|
<iconify-icon icon="lucide:chevron-down" class="text-[#89726c] text-xs"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
<button class="flex items-center gap-1.5 px-4 py-2 bg-[#faf6f3] border border-[#e5ded7] rounded-lg shrink-0 text-sm font-semibold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:arrow-up-down" class="text-[#bb5b3e]"></iconify-icon>
|
||||||
|
Price
|
||||||
|
<iconify-icon icon="lucide:chevron-down" class="text-[#89726c] text-xs"></iconify-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Recommendation Card --}}
|
||||||
|
<section class="px-5 pb-5">
|
||||||
|
<div class="bg-[#faf6f3] p-5 rounded-2xl border border-[#e5ded7] shadow-sm">
|
||||||
|
<div class="flex items-start justify-between mb-3">
|
||||||
|
<div>
|
||||||
|
<p class="text-[10px] font-bold uppercase tracking-widest text-[#89726c] mb-1">Recommendation</p>
|
||||||
|
<h2 class="text-3xl font-black text-[#8B4860] leading-tight">Fill up now</h2>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-center gap-1">
|
||||||
|
<div class="relative w-12 h-12">
|
||||||
|
<svg class="w-full h-full -rotate-90" viewBox="0 0 48 48">
|
||||||
|
<circle cx="24" cy="24" r="20" stroke="#eeeae5" stroke-width="4" fill="transparent"/>
|
||||||
|
<circle cx="24" cy="24" r="20" stroke="#8B4860" stroke-width="4" fill="transparent"
|
||||||
|
stroke-dasharray="125.6" stroke-dashoffset="25.1" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
<span class="absolute inset-0 flex items-center justify-center text-[11px] font-black text-[#4a3f3b]">80%</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-[9px] font-bold uppercase tracking-wider text-[#89726c]">Confidence</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-[#6b5a55] text-sm leading-relaxed font-medium">
|
||||||
|
Local prices are at a 30-day low. Regional wholesale trends indicate a 3p/litre increase starting Monday. Securing fuel today is highly advised.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Map Section --}}
|
||||||
|
<section class="relative h-56 w-full bg-[#eeeae5] border-y border-[#e5ded7]">
|
||||||
|
{{-- Simulated map grid --}}
|
||||||
|
<div class="absolute inset-0 opacity-10" style="background-image:radial-gradient(#89726c 1px,transparent 1px);background-size:30px 30px;"></div>
|
||||||
|
<div class="absolute inset-0 opacity-20" style="background-image:linear-gradient(0deg,transparent 24%,rgba(137,114,108,.2) 25%,rgba(137,114,108,.2) 26%,transparent 27%,transparent 74%,rgba(137,114,108,.2) 75%,rgba(137,114,108,.2) 76%,transparent 77%,transparent),linear-gradient(90deg,transparent 24%,rgba(137,114,108,.2) 25%,rgba(137,114,108,.2) 26%,transparent 27%,transparent 74%,rgba(137,114,108,.2) 75%,rgba(137,114,108,.2) 76%,transparent 77%,transparent);background-size:100px 100px;"></div>
|
||||||
|
|
||||||
|
{{-- Map Markers --}}
|
||||||
|
<div class="absolute top-1/4 left-1/4 flex flex-col items-center">
|
||||||
|
<div class="px-1.5 py-0.5 bg-white border-2 border-[#22c55e] rounded text-[10px] font-bold text-[#4a3f3b] mb-0.5 shadow-sm">142.9p</div>
|
||||||
|
<iconify-icon icon="mdi:map-marker" class="text-[#22c55e] text-3xl"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<div class="absolute top-1/2 left-3/4 flex flex-col items-center">
|
||||||
|
<div class="px-1.5 py-0.5 bg-white border-2 border-[#89726c] rounded text-[10px] font-bold text-[#4a3f3b] mb-0.5 shadow-sm">145.7p</div>
|
||||||
|
<iconify-icon icon="mdi:map-marker" class="text-[#89726c] text-3xl"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<div class="absolute bottom-1/4 left-1/2 flex flex-col items-center">
|
||||||
|
<div class="px-1.5 py-0.5 bg-white border-2 border-[#f59e0b] rounded text-[10px] font-bold text-[#4a3f3b] mb-0.5 shadow-sm">148.9p</div>
|
||||||
|
<iconify-icon icon="mdi:map-marker" class="text-[#f59e0b] text-3xl"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Legend --}}
|
||||||
|
<div class="absolute bottom-3 left-3 bg-[#faf6f3]/90 backdrop-blur-sm border border-[#e5ded7] rounded-lg px-3 py-2 flex gap-3">
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-[#22c55e] shrink-0"></span>
|
||||||
|
<span class="text-[9px] font-bold uppercase text-[#4a3f3b]">Current</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-[#89726c] shrink-0"></span>
|
||||||
|
<span class="text-[9px] font-bold uppercase text-[#4a3f3b]">Recent</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-1.5">
|
||||||
|
<span class="w-2 h-2 rounded-full bg-[#f59e0b] shrink-0"></span>
|
||||||
|
<span class="text-[9px] font-bold uppercase text-[#4a3f3b]">Stale</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Nearby Stations --}}
|
||||||
|
<section class="px-5 py-5">
|
||||||
|
<div class="flex items-center justify-between mb-3">
|
||||||
|
<h3 class="text-base font-bold text-[#4a3f3b]">Stations Nearby</h3>
|
||||||
|
<span class="text-[10px] font-bold uppercase tracking-widest text-[#89726c]">26 Results</span>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex items-center justify-between bg-[#faf6f3] px-4 py-3.5 rounded-xl border border-[#e5ded7]">
|
||||||
|
<h4 class="font-bold text-sm text-[#4a3f3b]">Tesco Superstore</h4>
|
||||||
|
<div class="text-xl font-black text-[#22c55e]">142.9<span class="text-xs font-bold ml-0.5">p</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between bg-[#faf6f3] px-4 py-3.5 rounded-xl border border-[#e5ded7]">
|
||||||
|
<h4 class="font-bold text-sm text-[#4a3f3b]">Sainsbury's Fuel</h4>
|
||||||
|
<div class="text-xl font-black text-[#22c55e]">143.1<span class="text-xs font-bold ml-0.5">p</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between bg-[#faf6f3] px-4 py-3.5 rounded-xl border border-[#e5ded7]">
|
||||||
|
<h4 class="font-bold text-sm text-[#4a3f3b]">BP Connect</h4>
|
||||||
|
<div class="text-xl font-black text-[#89726c]">145.7<span class="text-xs font-bold ml-0.5">p</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between bg-[#faf6f3] px-4 py-3.5 rounded-xl border border-[#e5ded7]">
|
||||||
|
<h4 class="font-bold text-sm text-[#4a3f3b]">Shell V-Power</h4>
|
||||||
|
<div class="text-xl font-black text-[#f59e0b]">148.9<span class="text-xs font-bold ml-0.5">p</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between bg-[#faf6f3] px-4 py-3.5 rounded-xl border border-[#e5ded7]">
|
||||||
|
<h4 class="font-bold text-sm text-[#4a3f3b]">Esso Express</h4>
|
||||||
|
<div class="text-xl font-black text-[#ef4444]">151.2<span class="text-xs font-bold ml-0.5">p</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- 14-Day Forecast (Pro) --}}
|
||||||
|
<section class="px-5 pb-8">
|
||||||
|
<div class="relative bg-[#faf6f3] border border-[#e5ded7] rounded-2xl overflow-hidden">
|
||||||
|
<div class="p-5">
|
||||||
|
<div class="flex items-center justify-between mb-5">
|
||||||
|
<h3 class="text-base font-bold text-[#4a3f3b]">14-Day Forecast</h3>
|
||||||
|
<div class="flex items-center gap-1 px-2 py-0.5 bg-[#bb5b3e]/10 text-[#bb5b3e] rounded text-[10px] font-bold uppercase tracking-wide">
|
||||||
|
<iconify-icon icon="lucide:sparkles"></iconify-icon>
|
||||||
|
Pro
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relative h-20 w-full">
|
||||||
|
<svg class="w-full h-full" viewBox="0 0 100 40" preserveAspectRatio="none">
|
||||||
|
<path d="M0 35 Q 10 32, 20 36 T 40 30 T 60 38 T 80 25 T 100 32"
|
||||||
|
fill="none" stroke="#bb5b3e" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
<div class="absolute inset-y-0 right-0 w-3/5 flex items-center justify-center"
|
||||||
|
style="background:linear-gradient(to right,transparent,rgba(250,246,243,0.85) 30%,#faf6f3);backdrop-filter:blur(3px);">
|
||||||
|
<button class="flex items-center gap-1.5 px-4 py-2 bg-[#bb5b3e] text-white rounded-full text-xs font-bold shadow-lg">
|
||||||
|
<iconify-icon icon="lucide:lock-keyhole"></iconify-icon>
|
||||||
|
Unlock Forecast
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{{-- Mobile Tab Bar --}}
|
||||||
|
<footer class="shrink-0 bg-[#faf6f3] border-t border-[#e5ded7] pb-8">
|
||||||
|
<nav class="flex justify-around items-center pt-3">
|
||||||
|
<a href="#" class="flex flex-col items-center gap-1 text-[#bb5b3e]">
|
||||||
|
<iconify-icon icon="lucide:search" class="text-2xl"></iconify-icon>
|
||||||
|
<span class="text-[9px] font-bold uppercase tracking-wide">Prices</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex flex-col items-center gap-1 text-[#89726c]">
|
||||||
|
<iconify-icon icon="lucide:bell" class="text-2xl"></iconify-icon>
|
||||||
|
<span class="text-[9px] font-bold uppercase tracking-wide">Alerts</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex flex-col items-center gap-1 text-[#89726c]">
|
||||||
|
<iconify-icon icon="lucide:map" class="text-2xl"></iconify-icon>
|
||||||
|
<span class="text-[9px] font-bold uppercase tracking-wide">Forecourts</span>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex flex-col items-center gap-1 text-[#89726c]">
|
||||||
|
<iconify-icon icon="lucide:bar-chart-3" class="text-2xl"></iconify-icon>
|
||||||
|
<span class="text-[9px] font-bold uppercase tracking-wide">Trends</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>{{-- end mobile layout --}}
|
||||||
|
|
||||||
|
{{-- Desktop Layout (hidden on mobile) --}}
|
||||||
|
<div class="hidden md:block">
|
||||||
|
|
||||||
|
{{-- Navigation --}}
|
||||||
|
<nav class="fixed top-0 w-full z-50 bg-[#faf6f3] border-b border-[#e5ded7] px-6 py-4 md:px-12">
|
||||||
|
<div class="max-w-7xl mx-auto flex items-center justify-between">
|
||||||
|
<a href="{{ route('home') }}" class="flex items-center gap-3">
|
||||||
|
<div class="w-10 h-10 md:w-12 md:h-12 rounded-lg bg-[#bb5b3e] flex items-center justify-center shadow-md">
|
||||||
|
<iconify-icon icon="lucide:fuel" class="text-white text-xl md:text-2xl"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<span class="text-2xl md:text-3xl font-black tracking-tighter text-[#bb5b3e]">FuelAlert</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="hidden md:flex items-center gap-10">
|
||||||
|
<a href="#how-it-works" class="text-sm font-semibold text-[#89726c] hover:text-[#bb5b3e] transition-colors">How it Works</a>
|
||||||
|
<a href="#features" class="text-sm font-semibold text-[#89726c] hover:text-[#bb5b3e] transition-colors">Features</a>
|
||||||
|
<a href="#pricing" class="text-sm font-semibold text-[#89726c] hover:text-[#bb5b3e] transition-colors">Pricing</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
@auth
|
||||||
|
<a href="{{ route('dashboard') }}" class="text-sm font-bold text-[#89726c] hover:text-[#4a3f3b] transition-colors">Dashboard</a>
|
||||||
|
@else
|
||||||
|
<a href="{{ route('login') }}" class="text-sm font-bold text-[#89726c] hover:text-[#4a3f3b] transition-colors">Login</a>
|
||||||
|
<a href="{{ route('register') }}" class="bg-[#bb5b3e] text-white px-6 py-2.5 rounded-full text-sm font-bold shadow-lg hover:bg-[#a34a31] transition-all transform hover:scale-105 active:scale-95">Get Started</a>
|
||||||
|
@endauth
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{-- Hero Section --}}
|
||||||
|
<section class="relative pt-40 pb-24 px-6 hero-gradient overflow-hidden">
|
||||||
|
<div class="max-w-7xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
|
||||||
|
<div class="space-y-8">
|
||||||
|
<div class="inline-flex items-center gap-2 px-3 py-1 bg-[#bb5b3e]/10 text-[#bb5b3e] rounded-full text-xs font-bold uppercase tracking-wider">
|
||||||
|
<iconify-icon icon="lucide:sparkles"></iconify-icon>
|
||||||
|
Save up to £250/year on fuel
|
||||||
|
</div>
|
||||||
|
<h1 class="text-5xl md:text-7xl font-black text-[#4a3f3b] leading-[1.1] tracking-tighter">
|
||||||
|
Stop Overpaying <br><span class="text-[#bb5b3e]">for Fuel.</span>
|
||||||
|
</h1>
|
||||||
|
<p class="text-xl text-[#89726c] max-w-lg leading-relaxed">
|
||||||
|
Join 50,000+ UK drivers using real-time insights to find the cheapest petrol and time their fill-ups perfectly.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form action="{{ route('stations.search') }}" method="GET" class="flex flex-col sm:flex-row gap-3 max-w-md">
|
||||||
|
<div class="relative flex-1">
|
||||||
|
<iconify-icon icon="lucide:map-pin" class="absolute left-4 top-1/2 -translate-y-1/2 text-[#89726c] text-xl pointer-events-none"></iconify-icon>
|
||||||
|
<input type="text" name="postcode" placeholder="Enter Postcode" class="w-full h-14 pl-12 pr-4 bg-white border border-[#e5ded7] rounded-xl focus:outline-none focus:ring-2 focus:ring-[#bb5b3e] shadow-inner text-lg text-[#4a3f3b]">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="h-14 px-8 bg-[#bb5b3e] text-white rounded-xl font-bold text-lg shadow-xl hover:bg-[#a34a31] transition-all">Find Prices</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-4 pt-4">
|
||||||
|
<div class="flex -space-x-2">
|
||||||
|
<div class="w-8 h-8 rounded-full border-2 border-white bg-[#bb5b3e]/20 flex items-center justify-center text-xs font-bold text-[#bb5b3e]">JR</div>
|
||||||
|
<div class="w-8 h-8 rounded-full border-2 border-white bg-[#4A7C7E]/20 flex items-center justify-center text-xs font-bold text-[#4A7C7E]">SM</div>
|
||||||
|
<div class="w-8 h-8 rounded-full border-2 border-white bg-[#9B8B6B]/20 flex items-center justify-center text-xs font-bold text-[#9B8B6B]">DK</div>
|
||||||
|
</div>
|
||||||
|
<span class="text-sm text-[#89726c] font-medium italic">"Saved me £12 on my first tank!"</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Visual Mockup --}}
|
||||||
|
<div class="relative hidden lg:block">
|
||||||
|
<div class="absolute -inset-4 bg-[#bb5b3e]/5 rounded-[2.5rem] blur-2xl"></div>
|
||||||
|
<div class="relative glass-card p-6 rounded-[2rem] shadow-2xl space-y-4 max-w-md mx-auto transform rotate-2">
|
||||||
|
<div class="flex justify-between items-center mb-4">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<div class="w-8 h-8 rounded bg-[#bb5b3e] flex items-center justify-center">
|
||||||
|
<iconify-icon icon="lucide:fuel" class="text-white"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<span class="font-black text-[#bb5b3e]">FuelAlert</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs font-bold text-[#89726c]">SW1A 1AA</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-[#faf6f3] p-4 rounded-xl border border-[#e5ded7] shadow-sm">
|
||||||
|
<p class="text-[10px] font-bold uppercase tracking-widest text-[#89726c] mb-1">Recommendation</p>
|
||||||
|
<h3 class="text-2xl font-black text-[#8B4860]">Fill up now</h3>
|
||||||
|
<div class="mt-2 h-1.5 w-full bg-[#eeeae5] rounded-full overflow-hidden">
|
||||||
|
<div class="h-full bg-[#8B4860] w-4/5"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div class="flex justify-between items-center p-3 bg-white rounded-lg border border-[#eeeae5]">
|
||||||
|
<span class="font-bold text-sm text-[#4a3f3b]">Tesco Superstore</span>
|
||||||
|
<span class="font-black text-[#22c55e]">142.9p</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between items-center p-3 bg-white rounded-lg border border-[#eeeae5]">
|
||||||
|
<span class="font-bold text-sm text-[#4a3f3b]">Sainsbury's Fuel</span>
|
||||||
|
<span class="font-black text-[#22c55e]">143.1p</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between items-center p-3 bg-white rounded-lg border border-[#eeeae5]">
|
||||||
|
<span class="font-bold text-sm text-[#4a3f3b]">Shell V-Power</span>
|
||||||
|
<span class="font-black text-[#89726c]">148.9p</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- How It Works --}}
|
||||||
|
<section id="how-it-works" class="py-24 px-6 bg-[#faf6f3]">
|
||||||
|
<div class="max-w-7xl mx-auto">
|
||||||
|
<div class="text-center mb-16 space-y-4">
|
||||||
|
<h2 class="text-4xl md:text-5xl font-black text-[#4a3f3b]">Smart Savings in 3 Steps</h2>
|
||||||
|
<p class="text-[#89726c] text-lg max-w-2xl mx-auto">Stop guessing when to fill up. Our engine analyses thousands of data points daily to save you money.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid md:grid-cols-3 gap-12">
|
||||||
|
<div class="text-center space-y-4">
|
||||||
|
<div class="w-16 h-16 bg-[#bb5b3e]/10 text-[#bb5b3e] rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
||||||
|
<iconify-icon icon="lucide:search"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="text-2xl font-bold text-[#4a3f3b]">1. Search</h3>
|
||||||
|
<p class="text-[#89726c]">Enter your postcode to find every forecourt within a 5–20 mile radius instantly.</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-center space-y-4">
|
||||||
|
<div class="w-16 h-16 bg-[#bb5b3e]/10 text-[#bb5b3e] rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
||||||
|
<iconify-icon icon="lucide:trending-up"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="text-2xl font-bold text-[#4a3f3b]">2. Get Advice</h3>
|
||||||
|
<p class="text-[#89726c]">Our engine compares local prices against national wholesale trends to give you a Fill Up / Wait recommendation.</p>
|
||||||
|
</div>
|
||||||
|
<div class="text-center space-y-4">
|
||||||
|
<div class="w-16 h-16 bg-[#bb5b3e]/10 text-[#bb5b3e] rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
||||||
|
<iconify-icon icon="lucide:wallet"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<h3 class="text-2xl font-bold text-[#4a3f3b]">3. Fill Up Smart</h3>
|
||||||
|
<p class="text-[#89726c]">Navigate to the cheapest station and fill up with confidence knowing you've secured the best price.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Features Section --}}
|
||||||
|
<section id="features" class="py-24 px-6 bg-[#f5ede5]">
|
||||||
|
<div class="max-w-7xl mx-auto">
|
||||||
|
<div class="grid lg:grid-cols-2 gap-20 items-center">
|
||||||
|
<div class="order-2 lg:order-1">
|
||||||
|
<div class="grid grid-cols-2 gap-6">
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl space-y-3">
|
||||||
|
<iconify-icon icon="lucide:zap" class="text-3xl text-[#bb5b3e]"></iconify-icon>
|
||||||
|
<h4 class="font-bold text-lg text-[#4a3f3b]">Real-Time Prices</h4>
|
||||||
|
<p class="text-sm text-[#89726c]">Verified daily prices from thousands of UK forecourts updated every 15 minutes.</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl space-y-3">
|
||||||
|
<iconify-icon icon="lucide:calendar" class="text-3xl text-[#bb5b3e]"></iconify-icon>
|
||||||
|
<h4 class="font-bold text-lg text-[#4a3f3b]">Timing Predictions</h4>
|
||||||
|
<p class="text-sm text-[#89726c]">Proprietary 14-day forecasts for petrol and diesel trends near you.</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl space-y-3">
|
||||||
|
<iconify-icon icon="lucide:shopping-bag" class="text-3xl text-[#bb5b3e]"></iconify-icon>
|
||||||
|
<h4 class="font-bold text-lg text-[#4a3f3b]">Supermarket Anchors</h4>
|
||||||
|
<p class="text-sm text-[#89726c]">Track local supermarkets — they set the floor price that independents must follow.</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl space-y-3">
|
||||||
|
<iconify-icon icon="lucide:bell-ring" class="text-3xl text-[#bb5b3e]"></iconify-icon>
|
||||||
|
<h4 class="font-bold text-lg text-[#4a3f3b]">Smart Price Alerts</h4>
|
||||||
|
<p class="text-sm text-[#89726c]">Get notified by email, WhatsApp, or SMS when local prices hit your target.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="order-1 lg:order-2 space-y-8">
|
||||||
|
<h2 class="text-4xl md:text-5xl font-black text-[#4a3f3b]">The ultimate fuel companion.</h2>
|
||||||
|
<p class="text-lg text-[#89726c]">Whether you're a daily commuter, a delivery professional, or just planning a weekend road trip, FuelAlert gives you the edge at the pump.</p>
|
||||||
|
<ul class="space-y-4">
|
||||||
|
<li class="flex items-center gap-3 font-bold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:check-circle-2" class="text-[#bb5b3e] text-xl shrink-0"></iconify-icon>
|
||||||
|
Coverage for 98% of UK Forecourts
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-3 font-bold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:check-circle-2" class="text-[#bb5b3e] text-xl shrink-0"></iconify-icon>
|
||||||
|
Hyper-local Map Visualisation
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-3 font-bold text-[#4a3f3b]">
|
||||||
|
<iconify-icon icon="lucide:check-circle-2" class="text-[#bb5b3e] text-xl shrink-0"></iconify-icon>
|
||||||
|
Historic Price Benchmarking
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ route('stations.search') }}" class="inline-flex items-center gap-2 text-[#bb5b3e] font-black text-lg group">
|
||||||
|
Find prices near you
|
||||||
|
<iconify-icon icon="lucide:arrow-right" class="group-hover:translate-x-1 transition-transform"></iconify-icon>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Pricing Section --}}
|
||||||
|
<section id="pricing" class="py-24 px-6 bg-[#faf6f3]">
|
||||||
|
<div class="max-w-7xl mx-auto">
|
||||||
|
<div class="text-center mb-16">
|
||||||
|
<h2 class="text-4xl md:text-5xl font-black text-[#4a3f3b] mb-4">Pricing for every driver</h2>
|
||||||
|
<p class="text-[#89726c] text-lg">Save hundreds for less than the cost of a coffee.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
{{-- Free --}}
|
||||||
|
<div class="bg-white border border-[#e5ded7] p-8 rounded-3xl flex flex-col h-full">
|
||||||
|
<div class="mb-8">
|
||||||
|
<h4 class="text-xl font-bold mb-2 text-[#4a3f3b]">Free</h4>
|
||||||
|
<div class="flex items-baseline gap-1">
|
||||||
|
<span class="text-4xl font-black text-[#4a3f3b]">£0</span>
|
||||||
|
<span class="text-[#89726c] text-sm">/mo</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="space-y-4 mb-8 flex-1 text-[#4a3f3b]">
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Nationwide station search</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Weekly email digest</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start text-[#89726c]"><iconify-icon icon="lucide:x" class="text-[#e5ded7] shrink-0 mt-0.5"></iconify-icon> No push / SMS alerts</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start text-[#89726c]"><iconify-icon icon="lucide:x" class="text-[#e5ded7] shrink-0 mt-0.5"></iconify-icon> No trend forecasts</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ route('register') }}" class="w-full py-3 px-4 border border-[#e5ded7] rounded-xl text-center font-bold hover:bg-[#faf6f3] transition-colors text-[#4a3f3b]">Get Started</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Basic --}}
|
||||||
|
<div class="bg-white border border-[#e5ded7] p-8 rounded-3xl flex flex-col h-full">
|
||||||
|
<div class="mb-8">
|
||||||
|
<h4 class="text-xl font-bold mb-2 text-[#4a3f3b]">Basic</h4>
|
||||||
|
<div class="flex items-baseline gap-1">
|
||||||
|
<span class="text-4xl font-black text-[#4a3f3b]">£0.99</span>
|
||||||
|
<span class="text-[#89726c] text-sm">/mo</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="space-y-4 mb-8 flex-1 text-[#4a3f3b]">
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Daily email + push alerts</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> WhatsApp price alerts</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> 14-day trend data</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start text-[#89726c]"><iconify-icon icon="lucide:x" class="text-[#e5ded7] shrink-0 mt-0.5"></iconify-icon> No SMS alerts</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ route('register') }}" class="w-full py-3 px-4 border border-[#e5ded7] rounded-xl text-center font-bold hover:bg-[#faf6f3] transition-colors text-[#4a3f3b]">Select Basic</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Plus (highlighted) --}}
|
||||||
|
<div class="bg-white border-2 border-[#bb5b3e] p-8 rounded-3xl flex flex-col h-full relative">
|
||||||
|
<div class="absolute -top-4 left-1/2 -translate-x-1/2 bg-[#bb5b3e] text-white px-4 py-1 rounded-full text-[10px] font-black uppercase tracking-widest whitespace-nowrap">Most Popular</div>
|
||||||
|
<div class="mb-8">
|
||||||
|
<h4 class="text-xl font-bold mb-2 text-[#4a3f3b]">Plus</h4>
|
||||||
|
<div class="flex items-baseline gap-1">
|
||||||
|
<span class="text-4xl font-black text-[#bb5b3e]">£2.49</span>
|
||||||
|
<span class="text-[#89726c] text-sm">/mo</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="space-y-4 mb-8 flex-1 text-[#4a3f3b]">
|
||||||
|
<li class="text-sm flex gap-2 items-start font-bold"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Everything in Basic</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> SMS alerts (up to 1/day)</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Supermarket anchor tracking</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Multi-location tracking</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ route('register') }}" class="w-full py-3 px-4 bg-[#bb5b3e] text-white rounded-xl text-center font-bold shadow-lg hover:bg-[#a34a31] transition-all">Join Plus</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{-- Pro --}}
|
||||||
|
<div class="bg-[#4a3f3b] border border-[#4a3f3b] p-8 rounded-3xl flex flex-col h-full text-white">
|
||||||
|
<div class="mb-8">
|
||||||
|
<h4 class="text-xl font-bold mb-2">Pro</h4>
|
||||||
|
<div class="flex items-baseline gap-1">
|
||||||
|
<span class="text-4xl font-black">£3.99</span>
|
||||||
|
<span class="text-white/60 text-sm">/mo</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul class="space-y-4 mb-8 flex-1">
|
||||||
|
<li class="text-sm flex gap-2 items-start font-bold"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Everything in Plus</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:sparkles" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> AI price predictions</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> SMS alerts (up to 3/day)</li>
|
||||||
|
<li class="text-sm flex gap-2 items-start"><iconify-icon icon="lucide:check" class="text-[#bb5b3e] shrink-0 mt-0.5"></iconify-icon> Exportable price history</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ route('register') }}" class="w-full py-3 px-4 bg-white text-[#4a3f3b] rounded-xl text-center font-bold hover:bg-gray-100 transition-colors">Go Pro</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Social Proof --}}
|
||||||
|
<section class="py-24 px-6 bg-[#f5ede5]">
|
||||||
|
<div class="max-w-7xl mx-auto">
|
||||||
|
<div class="flex flex-col md:flex-row gap-12 items-center">
|
||||||
|
<div class="md:w-1/3">
|
||||||
|
<h2 class="text-4xl font-black text-[#4a3f3b] mb-4">Loved by commuters.</h2>
|
||||||
|
<div class="flex items-center gap-1 text-[#f59e0b] mb-4 text-xl">
|
||||||
|
<iconify-icon icon="lucide:star"></iconify-icon>
|
||||||
|
<iconify-icon icon="lucide:star"></iconify-icon>
|
||||||
|
<iconify-icon icon="lucide:star"></iconify-icon>
|
||||||
|
<iconify-icon icon="lucide:star"></iconify-icon>
|
||||||
|
<iconify-icon icon="lucide:star"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<p class="text-[#89726c]">Join thousands of UK drivers saving every single month.</p>
|
||||||
|
</div>
|
||||||
|
<div class="md:w-2/3 grid sm:grid-cols-2 gap-6">
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl shadow-sm">
|
||||||
|
<p class="italic text-[#4a3f3b]">"I used to just go to the nearest station. Now I check FuelAlert and there's always a station 2 miles away that's 5p cheaper. Over a month it adds up to a free tank per year."</p>
|
||||||
|
<div class="mt-4 flex items-center gap-3">
|
||||||
|
<div class="w-10 h-10 rounded-full bg-[#bb5b3e]/20 flex items-center justify-center text-sm font-bold text-[#bb5b3e]">JR</div>
|
||||||
|
<div>
|
||||||
|
<p class="font-bold text-sm text-[#4a3f3b]">James R.</p>
|
||||||
|
<p class="text-[10px] text-[#89726c] uppercase font-bold tracking-widest">Daily Commuter</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-6 bg-[#faf6f3] border border-[#e5ded7] rounded-2xl shadow-sm">
|
||||||
|
<p class="italic text-[#4a3f3b]">"The predictions are eerily accurate. I was going to fill up Friday, FuelAlert said wait until Monday. Sure enough, my local Tesco dropped 3p. Brilliant."</p>
|
||||||
|
<div class="mt-4 flex items-center gap-3">
|
||||||
|
<div class="w-10 h-10 rounded-full bg-[#4A7C7E]/20 flex items-center justify-center text-sm font-bold text-[#4A7C7E]">SM</div>
|
||||||
|
<div>
|
||||||
|
<p class="font-bold text-sm text-[#4a3f3b]">Sarah M.</p>
|
||||||
|
<p class="text-[10px] text-[#89726c] uppercase font-bold tracking-widest">Delivery Driver</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- CTA Banner --}}
|
||||||
|
<section class="py-24 px-6 bg-[#bb5b3e] text-white text-center">
|
||||||
|
<div class="max-w-3xl mx-auto space-y-8">
|
||||||
|
<h2 class="text-4xl md:text-5xl font-black leading-tight">Ready to outsmart the pumps?</h2>
|
||||||
|
<p class="text-xl text-white/80">Sign up free today and never pay over the odds for fuel again.</p>
|
||||||
|
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
|
<a href="{{ route('register') }}" class="bg-white text-[#bb5b3e] px-10 py-4 rounded-xl text-lg font-black shadow-2xl hover:bg-gray-100 transition-all">Create Free Account</a>
|
||||||
|
<a href="{{ route('stations.search') }}" class="bg-transparent border-2 border-white/30 text-white px-10 py-4 rounded-xl text-lg font-bold hover:bg-white/10 transition-all">Search Prices Now</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{-- Footer --}}
|
||||||
|
<footer class="bg-[#faf6f3] border-t border-[#e5ded7] pt-16 pb-8 px-6">
|
||||||
|
<div class="max-w-7xl mx-auto grid grid-cols-2 md:grid-cols-4 gap-12 mb-12">
|
||||||
|
<div class="col-span-2 md:col-span-1 space-y-4">
|
||||||
|
<a href="{{ route('home') }}" class="flex items-center gap-2">
|
||||||
|
<div class="w-8 h-8 rounded bg-[#bb5b3e] flex items-center justify-center">
|
||||||
|
<iconify-icon icon="lucide:fuel" class="text-white"></iconify-icon>
|
||||||
|
</div>
|
||||||
|
<span class="text-xl font-black tracking-tighter text-[#bb5b3e]">FuelAlert</span>
|
||||||
|
</a>
|
||||||
|
<p class="text-sm text-[#89726c] leading-relaxed">
|
||||||
|
Helping UK drivers save money at the pump. Real-time data, smarter choices.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h5 class="font-black uppercase text-xs text-[#4a3f3b] tracking-widest">Product</h5>
|
||||||
|
<ul class="space-y-2 text-sm text-[#89726c]">
|
||||||
|
<li><a href="#pricing" class="hover:text-[#bb5b3e] transition-colors">Pricing</a></li>
|
||||||
|
<li><a href="#features" class="hover:text-[#bb5b3e] transition-colors">Features</a></li>
|
||||||
|
<li><a href="{{ route('stations.search') }}" class="hover:text-[#bb5b3e] transition-colors">Find Prices</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h5 class="font-black uppercase text-xs text-[#4a3f3b] tracking-widest">Account</h5>
|
||||||
|
<ul class="space-y-2 text-sm text-[#89726c]">
|
||||||
|
<li><a href="{{ route('register') }}" class="hover:text-[#bb5b3e] transition-colors">Sign Up Free</a></li>
|
||||||
|
<li><a href="{{ route('login') }}" class="hover:text-[#bb5b3e] transition-colors">Login</a></li>
|
||||||
|
@auth
|
||||||
|
<li><a href="{{ route('dashboard') }}" class="hover:text-[#bb5b3e] transition-colors">Dashboard</a></li>
|
||||||
|
@endauth
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="space-y-4">
|
||||||
|
<h5 class="font-black uppercase text-xs text-[#4a3f3b] tracking-widest">Legal</h5>
|
||||||
|
<ul class="space-y-2 text-sm text-[#89726c]">
|
||||||
|
<li><span class="cursor-default">Privacy Policy</span></li>
|
||||||
|
<li><span class="cursor-default">Terms of Service</span></li>
|
||||||
|
<li><span class="cursor-default">Cookie Settings</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="max-w-7xl mx-auto pt-8 border-t border-[#e5ded7] flex flex-col md:flex-row justify-between items-center gap-4 text-[10px] font-bold uppercase tracking-widest text-[#89726c]">
|
||||||
|
<p>© {{ date('Y') }} FuelAlert. All Rights Reserved.</p>
|
||||||
|
<p>Data sourced from the UK Fuel Finder transparency scheme.</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div>{{-- end desktop layout --}}
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -4,7 +4,11 @@ use App\Livewire\Public\FuelFinder;
|
|||||||
use App\Livewire\Public\StationSearch;
|
use App\Livewire\Public\StationSearch;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', FuelFinder::class)->name('home');
|
//Route::get('/', FuelFinder::class)->name('home');
|
||||||
|
|
||||||
|
Route::view('/', 'homepage')->name('home');
|
||||||
|
|
||||||
|
Route::get('/fuel-finder', FuelFinder::class)->name('fuel-finder');
|
||||||
|
|
||||||
Route::get('/stations', StationSearch::class)->name('stations.search');
|
Route::get('/stations', StationSearch::class)->name('stations.search');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user