chore: remove Livewire public components and homepage, prepare for Vue
This commit is contained in:
BIN
.claude/.DS_Store
vendored
Normal file
BIN
.claude/.DS_Store
vendored
Normal file
Binary file not shown.
2087
docs/superpowers/plans/2026-04-10-vue-frontend-setup.md
Normal file
2087
docs/superpowers/plans/2026-04-10-vue-frontend-setup.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,203 +0,0 @@
|
|||||||
import L from 'leaflet';
|
|
||||||
import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png';
|
|
||||||
import markerIcon from 'leaflet/dist/images/marker-icon.png';
|
|
||||||
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
|
|
||||||
|
|
||||||
delete L.Icon.Default.prototype._getIconUrl;
|
|
||||||
L.Icon.Default.mergeOptions({
|
|
||||||
iconUrl: markerIcon,
|
|
||||||
iconRetinaUrl: markerIcon2x,
|
|
||||||
shadowUrl: markerShadow,
|
|
||||||
});
|
|
||||||
|
|
||||||
function escHtml(str) {
|
|
||||||
return String(str ?? '')
|
|
||||||
.replace(/&/g, '&')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
.replace(/"/g, '"');
|
|
||||||
}
|
|
||||||
|
|
||||||
const CLASSIFICATION_COLOURS = {
|
|
||||||
current: '#22c55e',
|
|
||||||
recent: '#64748b',
|
|
||||||
stale: '#f59e0b',
|
|
||||||
outdated: '#ef4444',
|
|
||||||
};
|
|
||||||
|
|
||||||
const UK_CENTRE = [54.0, -2.0];
|
|
||||||
const UK_ZOOM = 7;
|
|
||||||
|
|
||||||
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 {
|
|
||||||
results,
|
|
||||||
meta,
|
|
||||||
radius,
|
|
||||||
_map: null,
|
|
||||||
_markers: [],
|
|
||||||
_userMarker: null,
|
|
||||||
|
|
||||||
init() {
|
|
||||||
injectUserMarkerStyles();
|
|
||||||
this._map = L.map(this.$el, { zoomControl: true }).setView(UK_CENTRE, UK_ZOOM);
|
|
||||||
|
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
||||||
maxZoom: 19,
|
|
||||||
}).addTo(this._map);
|
|
||||||
|
|
||||||
window.addEventListener('map-update', (e) => {
|
|
||||||
this.results = e.detail.results;
|
|
||||||
this.meta = e.detail.meta;
|
|
||||||
this.radius = e.detail.radius;
|
|
||||||
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() {
|
|
||||||
this._markers.forEach((m) => m.remove());
|
|
||||||
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() {
|
|
||||||
if (this._map) {
|
|
||||||
this._map.remove();
|
|
||||||
this._map = null;
|
|
||||||
this._markers = [];
|
|
||||||
this._userMarker = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_plotMarkers() {
|
|
||||||
if (!this._map) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._clearMarkers();
|
|
||||||
|
|
||||||
if (!this.results || this.results.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.results.forEach((station) => {
|
|
||||||
const colour = escHtml(CLASSIFICATION_COLOURS[station.price_classification] ?? '#64748b');
|
|
||||||
const miles = (station.distance_km * 0.621371).toFixed(1);
|
|
||||||
const supermarketTag = station.is_supermarket
|
|
||||||
? '<span style="display:inline-block;background:#84cc16;color:#fff;font-size:10px;padding:1px 5px;border-radius:3px;margin-left:4px;">Supermarket</span>'
|
|
||||||
: '';
|
|
||||||
|
|
||||||
const popup = `
|
|
||||||
<div style="min-width:160px">
|
|
||||||
<strong style="font-size:13px">${escHtml(station.name)}</strong>${supermarketTag}<br>
|
|
||||||
<span style="font-size:20px;font-weight:700;color:${colour}">${Number(station.price).toFixed(1)}p</span><br>
|
|
||||||
<span style="font-size:12px;color:#6b7280">${escHtml(miles)} miles away</span><br>
|
|
||||||
<span style="font-size:11px;color:#9ca3af">${escHtml(station.address)}, ${escHtml(station.postcode)}</span>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const marker = L.circleMarker([station.lat, station.lng], {
|
|
||||||
radius: 9,
|
|
||||||
fillColor: colour,
|
|
||||||
color: '#ffffff',
|
|
||||||
weight: 2,
|
|
||||||
opacity: 1,
|
|
||||||
fillOpacity: 0.85,
|
|
||||||
}).bindPopup(popup);
|
|
||||||
|
|
||||||
marker.addTo(this._map);
|
|
||||||
this._markers.push(marker);
|
|
||||||
});
|
|
||||||
|
|
||||||
const map = this._map;
|
|
||||||
const lat = this.meta?.lat;
|
|
||||||
const lng = this.meta?.lng;
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
@php
|
@php
|
||||||
$cardClass = match(true) {
|
$cardClass = match(true) {
|
||||||
$dark => 'bg-zinc-800 border border-zinc-800 text-white',
|
$dark => 'bg-primary border border-primary text-white',
|
||||||
$featured => 'bg-white border-2 border-primary',
|
$featured => 'bg-white border-2 border-primary',
|
||||||
default => 'bg-white border border-zinc-300',
|
default => 'bg-white border border-zinc-300',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,369 +0,0 @@
|
|||||||
<x-layouts::public title="FuelAlert — Fill up now or wait?">
|
|
||||||
<div class="min-h-screen bg-zinc-100">
|
|
||||||
|
|
||||||
{{-- Navigation --}}
|
|
||||||
<nav class="fixed top-0 w-full z-50 bg-zinc-50 border-b border-zinc-300 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-primary 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="font-display text-2xl md:text-3xl font-black tracking-tighter text-primary">FuelAlert</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="hidden md:flex items-center gap-10">
|
|
||||||
<a href="#how-it-works" class="text-sm font-semibold text-zinc-500 hover:text-primary transition-colors">How it Works</a>
|
|
||||||
<a href="#features" class="text-sm font-semibold text-zinc-500 hover:text-primary transition-colors">Features</a>
|
|
||||||
<a href="#pricing" class="text-sm font-semibold text-zinc-500 hover:text-primary transition-colors">Pricing</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
@auth
|
|
||||||
<a href="{{ route('dashboard') }}" class="text-sm font-bold text-zinc-500 hover:text-zinc-800 transition-colors">Dashboard</a>
|
|
||||||
@else
|
|
||||||
<a href="{{ route('login') }}" class="text-sm font-bold text-zinc-500 hover:text-zinc-800 transition-colors">Login</a>
|
|
||||||
<a href="{{ route('register') }}" class="bg-primary text-white px-6 py-2.5 rounded-full text-sm font-bold shadow-lg hover:bg-primary-dark transition-all 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-primary/10 text-primary rounded-full text-[10px] md:text-xs font-bold uppercase tracking-wider">
|
|
||||||
<iconify-icon icon="lucide:sparkles"></iconify-icon>
|
|
||||||
Save up to £250/year on fuel
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1 class="font-display text-3xl md:text-5xl lg:text-7xl font-black text-zinc-800 leading-[1.1] tracking-tighter">
|
|
||||||
Stop Overpaying <br> <span class="text-primary">for Fuel.</span>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p class="text-base md:text-xl text-zinc-500 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>
|
|
||||||
|
|
||||||
{{-- Search Section --}}
|
|
||||||
<div 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-zinc-500 text-xl"></iconify-icon>
|
|
||||||
<input type="text" placeholder="Enter Postcode"
|
|
||||||
class="w-full h-14 pl-12 pr-4 bg-white border border-zinc-300 rounded-xl text-lg shadow-inner focus:outline-none focus:ring-2 focus:ring-primary">
|
|
||||||
</div>
|
|
||||||
<button class="h-14 px-8 bg-primary text-white rounded-xl font-bold text-lg shadow-xl hover:bg-primary-dark transition-all">
|
|
||||||
Find Prices
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{{-- Search Section --}}
|
|
||||||
|
|
||||||
<div class="flex items-center gap-4 pt-4">
|
|
||||||
<div class="flex -space-x-2">
|
|
||||||
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=1" alt="" class="w-8 h-8 rounded-full border-2 border-white">
|
|
||||||
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=2" alt="" class="w-8 h-8 rounded-full border-2 border-white">
|
|
||||||
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=3" alt="" class="w-8 h-8 rounded-full border-2 border-white">
|
|
||||||
</div>
|
|
||||||
<span class="text-sm text-zinc-500 font-medium italic">"Saved me £12 on my first tank!"</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{-- Hero card mockup --}}
|
|
||||||
<div class="relative hidden lg:block">
|
|
||||||
<div class="absolute -inset-4 bg-primary/5 rounded-[2.5rem] blur-2xl"></div>
|
|
||||||
<div class="relative glass-card p-6 rounded-4xl shadow-2xl space-y-4 max-w-md mx-auto rotate-2">
|
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<div class="w-8 h-8 rounded bg-primary flex items-center justify-center">
|
|
||||||
<iconify-icon icon="lucide:fuel" class="text-white"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<span class="font-display font-black text-primary">FuelAlert</span>
|
|
||||||
</div>
|
|
||||||
<span class="text-xs font-bold text-zinc-500">SW1A 1AA</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="bg-zinc-50 p-4 rounded-xl border border-zinc-300 shadow-sm">
|
|
||||||
<p class="text-[10px] font-bold uppercase tracking-widest text-zinc-500 mb-1">Recommendation</p>
|
|
||||||
<h3 class="font-display text-2xl font-black text-mauve">Fill up now</h3>
|
|
||||||
<div class="mt-2 h-1.5 w-full bg-zinc-200 rounded-full overflow-hidden">
|
|
||||||
<div class="h-full bg-mauve 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-zinc-200">
|
|
||||||
<span class="font-bold text-sm">Tesco Superstore</span>
|
|
||||||
<span class="font-black text-status-good">142.9p</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between items-center p-3 bg-white rounded-lg border border-zinc-200">
|
|
||||||
<span class="font-bold text-sm">Shell V-Power</span>
|
|
||||||
<span class="font-black text-zinc-500">148.9p</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- How It Works --}}
|
|
||||||
<section id="how-it-works" class="py-24 px-6 bg-zinc-50">
|
|
||||||
<div class="max-w-7xl mx-auto">
|
|
||||||
<div class="text-center mb-16 space-y-4">
|
|
||||||
<h2 class="font-display text-4xl md:text-5xl font-black text-zinc-800">Smart Savings in 3 Steps</h2>
|
|
||||||
<p class="text-zinc-500 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-primary/10 text-primary rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
|
||||||
<iconify-icon icon="lucide:search"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<h3 class="font-display text-2xl font-bold">1. Search</h3>
|
|
||||||
<p class="text-zinc-500">Enter your postcode or location 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-primary/10 text-primary rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
|
||||||
<iconify-icon icon="lucide:trending-up"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<h3 class="font-display text-2xl font-bold">2. Get Advice</h3>
|
|
||||||
<p class="text-zinc-500">Our AI 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-primary/10 text-primary rounded-2xl flex items-center justify-center mx-auto text-3xl">
|
|
||||||
<iconify-icon icon="lucide:wallet"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<h3 class="font-display text-2xl font-bold">3. Fill Up Smart</h3>
|
|
||||||
<p class="text-zinc-500">Navigate to the cheapest station and fill up with confidence knowing you've secured the best price.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- Features --}}
|
|
||||||
<section id="features" class="py-24 px-6">
|
|
||||||
<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 grid grid-cols-2 gap-6">
|
|
||||||
<div class="p-6 bg-zinc-50 border border-zinc-300 rounded-2xl space-y-3">
|
|
||||||
<iconify-icon icon="lucide:zap" class="text-3xl text-primary"></iconify-icon>
|
|
||||||
<h4 class="font-bold text-lg">Real-Time Prices</h4>
|
|
||||||
<p class="text-sm text-zinc-500">Verified daily prices from thousands of UK forecourts.</p>
|
|
||||||
</div>
|
|
||||||
<div class="p-6 bg-zinc-50 border border-zinc-300 rounded-2xl space-y-3">
|
|
||||||
<iconify-icon icon="lucide:calendar" class="text-3xl text-primary"></iconify-icon>
|
|
||||||
<h4 class="font-bold text-lg">Timing Predictions</h4>
|
|
||||||
<p class="text-sm text-zinc-500">Proprietary 14-day forecasts for petrol and diesel trends.</p>
|
|
||||||
</div>
|
|
||||||
<div class="p-6 bg-zinc-50 border border-zinc-300 rounded-2xl space-y-3">
|
|
||||||
<iconify-icon icon="lucide:shopping-bag" class="text-3xl text-primary"></iconify-icon>
|
|
||||||
<h4 class="font-bold text-lg">Supermarket Anchors</h4>
|
|
||||||
<p class="text-sm text-zinc-500">Track local supermarkets to find the absolute lowest base price.</p>
|
|
||||||
</div>
|
|
||||||
<div class="p-6 bg-zinc-50 border border-zinc-300 rounded-2xl space-y-3">
|
|
||||||
<iconify-icon icon="lucide:bell-ring" class="text-3xl text-primary"></iconify-icon>
|
|
||||||
<h4 class="font-bold text-lg">Smart Price Alerts</h4>
|
|
||||||
<p class="text-sm text-zinc-500">Get notified when local prices drop below your set target.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="order-1 lg:order-2 space-y-8">
|
|
||||||
<h2 class="font-display text-4xl md:text-5xl font-black text-zinc-800">The ultimate fuel companion.</h2>
|
|
||||||
<p class="text-lg text-zinc-500">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">
|
|
||||||
<iconify-icon icon="lucide:check-circle-2" class="text-primary"></iconify-icon>
|
|
||||||
Coverage for 98% of UK Forecourts
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center gap-3 font-bold">
|
|
||||||
<iconify-icon icon="lucide:check-circle-2" class="text-primary"></iconify-icon>
|
|
||||||
Hyper-local Map Visualisation
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center gap-3 font-bold">
|
|
||||||
<iconify-icon icon="lucide:check-circle-2" class="text-primary"></iconify-icon>
|
|
||||||
Historic Price Benchmarking
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<a href="{{ route('register') }}" class="inline-flex items-center gap-2 text-primary font-black text-lg group">
|
|
||||||
Explore all features
|
|
||||||
<iconify-icon icon="lucide:arrow-right" class="transition-transform group-hover:translate-x-1"></iconify-icon>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- Pricing --}}
|
|
||||||
<section id="pricing" class="py-24 px-6 bg-zinc-50">
|
|
||||||
<div class="max-w-7xl mx-auto">
|
|
||||||
<div class="text-center mb-16">
|
|
||||||
<h2 class="font-display text-4xl md:text-5xl font-black text-zinc-800 mb-4">Pricing for every driver</h2>
|
|
||||||
<p class="text-zinc-500 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">
|
|
||||||
|
|
||||||
<x-pricing-card
|
|
||||||
name="Free"
|
|
||||||
price="£0"
|
|
||||||
button-text="Get Started"
|
|
||||||
:perks="[
|
|
||||||
['text' => 'Basic Search', 'included' => true],
|
|
||||||
['text' => 'Daily Updates', 'included' => true],
|
|
||||||
['text' => 'No Alerts', 'included' => false],
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<x-pricing-card
|
|
||||||
name="Basic"
|
|
||||||
price="£0.99"
|
|
||||||
button-text="Select Basic"
|
|
||||||
:perks="[
|
|
||||||
['text' => 'Ad-free Experience', 'included' => true],
|
|
||||||
['text' => '14-day Trend Data', 'included' => true],
|
|
||||||
['text' => '3 Daily Price Alerts','included' => true],
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<x-pricing-card
|
|
||||||
name="Plus"
|
|
||||||
price="£2.49"
|
|
||||||
button-text="Join Plus"
|
|
||||||
:featured="true"
|
|
||||||
:perks="[
|
|
||||||
['text' => 'Supermarket Anchor', 'included' => true],
|
|
||||||
['text' => 'Priority Price Alerts', 'included' => true],
|
|
||||||
['text' => 'Multi-location Tracking','included' => true],
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<x-pricing-card
|
|
||||||
name="Pro"
|
|
||||||
price="£3.99"
|
|
||||||
button-text="Go Pro"
|
|
||||||
:dark="true"
|
|
||||||
:perks="[
|
|
||||||
['text' => 'AI Price Predictions', 'included' => true],
|
|
||||||
['text' => 'Multi-Vehicle Fleet', 'included' => true],
|
|
||||||
['text' => 'Exportable Price History','included' => true],
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- Social Proof --}}
|
|
||||||
<section class="py-24 px-6">
|
|
||||||
<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="font-display text-4xl font-black text-zinc-800 mb-4">Loved by commuters.</h2>
|
|
||||||
<div class="flex items-center gap-1 text-status-warn 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-zinc-500">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-zinc-50 border border-zinc-300 rounded-2xl shadow-sm italic text-zinc-800">
|
|
||||||
"I used to just go to the station on my way home. Now I check FuelAlert and realise there's a station 2 miles away that's 5p cheaper! Over a month, it adds up to a free tank per year."
|
|
||||||
<div class="mt-4 flex items-center gap-3 not-italic">
|
|
||||||
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=John" alt="James R." class="w-10 h-10 rounded-full">
|
|
||||||
<div>
|
|
||||||
<p class="font-bold text-sm">James R.</p>
|
|
||||||
<p class="text-[10px] text-zinc-500 uppercase font-bold tracking-widest">Daily Commuter</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="p-6 bg-zinc-50 border border-zinc-300 rounded-2xl shadow-sm italic text-zinc-800">
|
|
||||||
"The predictions are eerily accurate. I was going to fill up Friday, but FuelAlert said 'Hold on' for Monday. Sure enough, prices dropped at my local Tesco by 3p. Brilliant."
|
|
||||||
<div class="mt-4 flex items-center gap-3 not-italic">
|
|
||||||
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=Sarah" alt="Sarah M." class="w-10 h-10 rounded-full">
|
|
||||||
<div>
|
|
||||||
<p class="font-bold text-sm">Sarah M.</p>
|
|
||||||
<p class="text-[10px] text-zinc-500 uppercase font-bold tracking-widest">Delivery Driver</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- CTA Banner --}}
|
|
||||||
<section class="py-24 px-6 bg-primary text-white text-center">
|
|
||||||
<div class="max-w-3xl mx-auto space-y-8">
|
|
||||||
<h2 class="font-display text-4xl md:text-5xl font-black leading-tight">Ready to outsmart the pumps?</h2>
|
|
||||||
<p class="text-xl text-white/80">Sign up for 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-primary px-10 py-4 rounded-xl text-lg font-black shadow-2xl hover:bg-zinc-100 transition-all">Create Free Account</a>
|
|
||||||
<a href="#" class="border-2 border-white/30 text-white px-10 py-4 rounded-xl text-lg font-bold hover:bg-white/10 transition-all">Watch Demo Video</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{{-- Footer --}}
|
|
||||||
<footer class="bg-zinc-50 border-t border-zinc-300 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-primary flex items-center justify-center">
|
|
||||||
<iconify-icon icon="lucide:fuel" class="text-white"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<span class="font-display text-xl font-black tracking-tighter text-primary">FuelAlert</span>
|
|
||||||
</a>
|
|
||||||
<p class="text-sm text-zinc-500 leading-relaxed">Helping UK drivers save money at the pump since 2021. Real-time data, smarter choices.</p>
|
|
||||||
<div class="flex gap-4">
|
|
||||||
<iconify-icon icon="mdi:twitter" class="text-2xl text-zinc-500 hover:text-primary cursor-pointer transition-colors"></iconify-icon>
|
|
||||||
<iconify-icon icon="mdi:facebook" class="text-2xl text-zinc-500 hover:text-primary cursor-pointer transition-colors"></iconify-icon>
|
|
||||||
<iconify-icon icon="mdi:instagram" class="text-2xl text-zinc-500 hover:text-primary cursor-pointer transition-colors"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-4">
|
|
||||||
<h5 class="font-black uppercase text-xs text-zinc-800 tracking-widest">Product</h5>
|
|
||||||
<ul class="space-y-2 text-sm text-zinc-500">
|
|
||||||
<li><a href="#pricing" class="hover:text-primary transition-colors">Pricing</a></li>
|
|
||||||
<li><a href="#features" class="hover:text-primary transition-colors">Features</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">FuelAlert Pro</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Enterprise API</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-4">
|
|
||||||
<h5 class="font-black uppercase text-xs text-zinc-800 tracking-widest">Resources</h5>
|
|
||||||
<ul class="space-y-2 text-sm text-zinc-500">
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Market Insights</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">How We Track</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Help Centre</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Driver Safety</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="space-y-4">
|
|
||||||
<h5 class="font-black uppercase text-xs text-zinc-800 tracking-widest">Legal</h5>
|
|
||||||
<ul class="space-y-2 text-sm text-zinc-500">
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Privacy Policy</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Terms of Service</a></li>
|
|
||||||
<li><a href="#" class="hover:text-primary transition-colors">Cookie Settings</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="max-w-7xl mx-auto pt-8 border-t border-zinc-300 flex flex-col md:flex-row justify-between items-center gap-4 text-[10px] font-bold uppercase tracking-widest text-zinc-500">
|
|
||||||
<p>© {{ date('Y') }} FuelAlert UK Limited. All Rights Reserved.</p>
|
|
||||||
<p>Data provided by official UK retail price transparency schemes.</p>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</x-layouts::public>
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
<div class="flex h-dvh flex-col bg-surface-page">
|
|
||||||
|
|
||||||
{{-- HEADER --}}
|
|
||||||
<header class="shrink-0 z-50 bg-surface border-b border-border shadow-sm
|
|
||||||
flex items-center justify-between px-5 pb-4 md:px-8"
|
|
||||||
style="padding-top: max(1rem, env(safe-area-inset-top))">
|
|
||||||
|
|
||||||
<a href="{{ route('home') }}" class="flex items-center gap-2.5">
|
|
||||||
<div class="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary shadow-md md:h-10 md:w-10">
|
|
||||||
<iconify-icon icon="lucide:fuel" class="text-lg text-white md:text-xl"></iconify-icon>
|
|
||||||
</div>
|
|
||||||
<span class="text-xl font-black tracking-tighter text-primary md:text-2xl">FuelAlert</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<nav class="hidden items-center gap-8 md:flex">
|
|
||||||
<a href="#" class="text-sm font-semibold text-text-muted transition-colors hover:text-primary">Prices</a>
|
|
||||||
<a href="#" class="text-sm font-semibold text-text-muted transition-colors hover:text-primary">Alerts</a>
|
|
||||||
<a href="#" class="text-sm font-semibold text-text-muted transition-colors hover:text-primary">Trends</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
@auth
|
|
||||||
<a href="{{ route('dashboard') }}"
|
|
||||||
class="flex h-9 w-9 items-center justify-center rounded-full border border-border bg-surface-subtle">
|
|
||||||
<iconify-icon icon="lucide:user" class="text-base text-text-muted"></iconify-icon>
|
|
||||||
</a>
|
|
||||||
@else
|
|
||||||
<a href="{{ route('login') }}"
|
|
||||||
class="flex h-9 w-9 items-center justify-center rounded-full border border-border bg-surface-subtle">
|
|
||||||
<iconify-icon icon="lucide:user" class="text-base text-text-muted"></iconify-icon>
|
|
||||||
</a>
|
|
||||||
@endauth
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{{-- MAIN --}}
|
|
||||||
<main class="flex-1 overflow-y-auto" style="-ms-overflow-style:none;scrollbar-width:none;">
|
|
||||||
<div class="md:mx-auto md:max-w-3xl">
|
|
||||||
|
|
||||||
<livewire:public.fuel.search />
|
|
||||||
<livewire:public.fuel.recommendation />
|
|
||||||
<livewire:public.fuel.map />
|
|
||||||
<livewire:public.fuel.station-list />
|
|
||||||
|
|
||||||
<section class="px-5 pb-8">
|
|
||||||
<x-fuel.forecast />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
{{-- BOTTOM TAB BAR --}}
|
|
||||||
@php
|
|
||||||
$tabs = [
|
|
||||||
['label' => 'Prices', 'icon' => 'lucide:fuel', 'route' => 'home'],
|
|
||||||
['label' => 'Alerts', 'icon' => 'lucide:bell', 'route' => null],
|
|
||||||
['label' => 'Forecourts', 'icon' => 'lucide:map-pin', 'route' => null],
|
|
||||||
['label' => 'Trends', 'icon' => 'lucide:trending-up', 'route' => null],
|
|
||||||
];
|
|
||||||
@endphp
|
|
||||||
<nav class="shrink-0 border-t border-border bg-surface md:hidden"
|
|
||||||
style="padding-bottom: max(0.5rem, env(safe-area-inset-bottom))">
|
|
||||||
<div class="flex pt-3">
|
|
||||||
@foreach ($tabs as $tab)
|
|
||||||
@php $active = $tab['route'] && request()->routeIs($tab['route']); @endphp
|
|
||||||
<div class="flex flex-1 flex-col items-center gap-1">
|
|
||||||
<iconify-icon
|
|
||||||
icon="{{ $tab['icon'] }}"
|
|
||||||
class="text-xl {{ $active ? 'text-primary' : 'text-text-muted' }}"
|
|
||||||
></iconify-icon>
|
|
||||||
<span class="text-[10px] font-bold uppercase tracking-wide {{ $active ? 'text-primary' : 'text-text-muted' }}">
|
|
||||||
{{ $tab['label'] }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<div class="mb-4" wire:ignore>
|
|
||||||
<x-fuel.station-map />
|
|
||||||
</div>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<div>
|
|
||||||
@if ($prediction)
|
|
||||||
<div class="px-5 pb-5">
|
|
||||||
<x-fuel.recommendation :prediction="$prediction" />
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
<div class="space-y-3 px-5 pb-4 pt-5">
|
|
||||||
<form wire:submit="findStations">
|
|
||||||
|
|
||||||
<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
|
|
||||||
icon="lucide:map-pin"
|
|
||||||
class="pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-xl text-text-muted"
|
|
||||||
></iconify-icon>
|
|
||||||
<input
|
|
||||||
wire:model="search"
|
|
||||||
x-model="query"
|
|
||||||
x-ref="searchInput"
|
|
||||||
type="text"
|
|
||||||
name="search"
|
|
||||||
@focus="_usedIpFallback = false"
|
|
||||||
placeholder="Postcode, town or city"
|
|
||||||
class="h-14 w-full rounded-xl border border-border bg-surface pl-12 pr-36 text-base font-semibold text-text-base focus:border-transparent focus:outline-none focus:ring-2 focus:ring-primary"
|
|
||||||
/>
|
|
||||||
<div class="absolute inset-y-0 right-0 flex items-center gap-2 pr-3">
|
|
||||||
<button
|
|
||||||
x-show="query.length > 0"
|
|
||||||
x-cloak
|
|
||||||
type="button"
|
|
||||||
@click="query = ''; $wire.set('search', ''); _usedIpFallback = false"
|
|
||||||
class="text-text-muted hover:text-text-base"
|
|
||||||
>
|
|
||||||
<iconify-icon icon="lucide:x" class="text-base"></iconify-icon>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="locateUser()"
|
|
||||||
:disabled="locatingUser"
|
|
||||||
class="flex items-center gap-1.5 rounded-full bg-surface-subtle px-3 py-1.5 text-sm font-semibold text-text-base 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="animate-spin text-sm"></iconify-icon>
|
|
||||||
<span x-text="locatingUser ? 'Finding...' : 'Near me'">Near me</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
wire:loading.attr="disabled"
|
|
||||||
class="text-text-muted 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="animate-spin text-xl"></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 left-0 right-0 top-full 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>
|
|
||||||
|
|
||||||
@error('search')
|
|
||||||
<p class="mb-2 text-sm text-red-600">{{ $message }}</p>
|
|
||||||
@enderror
|
|
||||||
|
|
||||||
<div class="flex gap-2 overflow-x-auto pb-1" style="-ms-overflow-style:none;scrollbar-width:none;">
|
|
||||||
<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 class="shrink-0"><x-fuel.radius-select wire:model.live="radius" /></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
@if ($apiError)
|
|
||||||
<div class="rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
|
|
||||||
{{ $apiError }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<div>
|
|
||||||
@if ($hasSearched)
|
|
||||||
<div class="px-5 pb-5">
|
|
||||||
@if (! empty($meta))
|
|
||||||
<div class="mb-3 flex items-center justify-between">
|
|
||||||
<h3 class="text-base font-bold text-text-base">Stations Nearby</h3>
|
|
||||||
<span class="text-[10px] font-bold uppercase tracking-widest text-text-muted">
|
|
||||||
{{ $meta['count'] ?? 0 }} {{ str('Result')->plural($meta['count'] ?? 0) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@forelse ($results as $station)
|
|
||||||
<div class="mb-2">
|
|
||||||
<x-fuel.station-card :station="$station" />
|
|
||||||
</div>
|
|
||||||
@empty
|
|
||||||
<p class="text-sm text-text-muted">
|
|
||||||
No stations found within {{ $radius }} {{ str('mile')->plural($radius) }}.
|
|
||||||
</p>
|
|
||||||
@endforelse
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@@ -1,15 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
//use App\Livewire\Public\FuelFinder;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
Route::middleware(['auth', 'verified'])->group(function (): void {
|
||||||
//Route::get('/fuel-finder', FuelFinder::class)->name('fuel-finder');
|
Route::view('dashboard', 'dashboard')->name('dashboard');
|
||||||
|
|
||||||
Route::view('/', 'homepage')->name('home');
|
|
||||||
|
|
||||||
Route::middleware(['auth', 'verified'])->group(function () {
|
|
||||||
Route::view('dashboard', 'dashboard')->name('dashboard');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
require __DIR__.'/settings.php';
|
require __DIR__.'/settings.php';
|
||||||
|
|||||||
Reference in New Issue
Block a user