Compare commits
No commits in common. "ed8b91db4647564f21b376fea6390c1167dcc027" and "f873bc1c77c326f19a65e361bb891708f4ded13d" have entirely different histories.
ed8b91db46
...
f873bc1c77
6 changed files with 19 additions and 202 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,4 +2,3 @@
|
||||||
/result
|
/result
|
||||||
*.db
|
*.db
|
||||||
.direnv/
|
.direnv/
|
||||||
/prixdugaz
|
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -1,4 +1,4 @@
|
||||||
module github.com/Polensky/prixdugaz
|
module github.com/polen/prixdugaz
|
||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
|
|
|
||||||
118
static/map.js
118
static/map.js
|
|
@ -4,54 +4,20 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// ── URL param helpers ──────────────────────────────────────
|
let currentFuel = 'regular';
|
||||||
function getParams() {
|
let currentRegion = '';
|
||||||
return new URLSearchParams(window.location.search);
|
let clusterMode = 'avg'; // 'min' | 'avg' | 'max'
|
||||||
}
|
let showCostco = true;
|
||||||
|
|
||||||
function updateURL() {
|
|
||||||
const p = new URLSearchParams();
|
|
||||||
if (currentFuel !== 'regular') p.set('fuel', currentFuel);
|
|
||||||
if (currentRegion !== '') p.set('region', currentRegion);
|
|
||||||
if (clusterMode !== 'avg') p.set('cluster', clusterMode);
|
|
||||||
if (!showCostco) p.set('costco', '0');
|
|
||||||
const slider = document.getElementById('price-slider');
|
|
||||||
if (slider && parseFloat(slider.value) < parseFloat(slider.max)) {
|
|
||||||
p.set('price', slider.value);
|
|
||||||
}
|
|
||||||
if (map) {
|
|
||||||
const c = map.getCenter();
|
|
||||||
p.set('lat', c.lat.toFixed(5));
|
|
||||||
p.set('lng', c.lng.toFixed(5));
|
|
||||||
p.set('zoom', map.getZoom());
|
|
||||||
}
|
|
||||||
const qs = p.toString();
|
|
||||||
history.replaceState(null, '', qs ? '?' + qs : window.location.pathname);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read initial state from URL params (fall back to defaults).
|
|
||||||
const _p = getParams();
|
|
||||||
let currentFuel = ['regular','super','diesel'].includes(_p.get('fuel')) ? _p.get('fuel') : 'regular';
|
|
||||||
let currentRegion = _p.get('region') || '';
|
|
||||||
let clusterMode = ['min','avg','max'].includes(_p.get('cluster')) ? _p.get('cluster') : 'avg';
|
|
||||||
let showCostco = _p.get('costco') !== '0';
|
|
||||||
let _initPrice = _p.has('price') ? parseFloat(_p.get('price')) : null;
|
|
||||||
let _initLat = _p.has('lat') ? parseFloat(_p.get('lat')) : null;
|
|
||||||
let _initLng = _p.has('lng') ? parseFloat(_p.get('lng')) : null;
|
|
||||||
let _initZoom = _p.has('zoom') ? parseInt(_p.get('zoom'), 10) : null;
|
|
||||||
|
|
||||||
let allStations = window.__stations || [];
|
let allStations = window.__stations || [];
|
||||||
let allMarkers = [];
|
let allMarkers = [];
|
||||||
let visibleSet = new Set();
|
let visibleSet = new Set();
|
||||||
let minPrice = 0, maxPrice = 300;
|
let minPrice = 0, maxPrice = 300;
|
||||||
let sliderTimer = null;
|
let sliderTimer = null;
|
||||||
let mapMoveTimer = null;
|
|
||||||
const stationDeltas = window.__deltas || {};
|
const stationDeltas = window.__deltas || {};
|
||||||
|
|
||||||
// ── Map setup (deferred to init section below) ─────────────
|
// ── Map setup (deferred to init section below) ─────────────
|
||||||
let map;
|
let map;
|
||||||
let clusterGroup;
|
let clusterGroup;
|
||||||
let locateMarker = null;
|
|
||||||
|
|
||||||
// ── Colour helpers ─────────────────────────────────────────
|
// ── Colour helpers ─────────────────────────────────────────
|
||||||
function priceColor(price, min, max) {
|
function priceColor(price, min, max) {
|
||||||
|
|
@ -254,14 +220,13 @@
|
||||||
document.getElementById('region-select').addEventListener('change', function () {
|
document.getElementById('region-select').addEventListener('change', function () {
|
||||||
currentRegion = this.value;
|
currentRegion = this.value;
|
||||||
rebuildMarkers(true);
|
rebuildMarkers(true);
|
||||||
updateURL();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('price-slider').addEventListener('input', function () {
|
document.getElementById('price-slider').addEventListener('input', function () {
|
||||||
const val = parseFloat(this.value);
|
const val = parseFloat(this.value);
|
||||||
document.getElementById('slider-label').textContent = val.toFixed(1) + '¢/L';
|
document.getElementById('slider-label').textContent = val.toFixed(1) + '¢/L';
|
||||||
clearTimeout(sliderTimer);
|
clearTimeout(sliderTimer);
|
||||||
sliderTimer = setTimeout(() => { applyPriceFilter(val); updateURL(); }, 80);
|
sliderTimer = setTimeout(() => applyPriceFilter(val), 80);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll('.cluster-btn').forEach(btn => {
|
document.querySelectorAll('.cluster-btn').forEach(btn => {
|
||||||
|
|
@ -271,7 +236,6 @@
|
||||||
document.querySelectorAll('.cluster-btn').forEach(b =>
|
document.querySelectorAll('.cluster-btn').forEach(b =>
|
||||||
b.classList.toggle('active', b.dataset.mode === clusterMode));
|
b.classList.toggle('active', b.dataset.mode === clusterMode));
|
||||||
if (allStations.length) clusterGroup.refreshClusters();
|
if (allStations.length) clusterGroup.refreshClusters();
|
||||||
updateURL();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -282,39 +246,14 @@
|
||||||
document.querySelectorAll('.fuel-btn[data-fuel]').forEach(b =>
|
document.querySelectorAll('.fuel-btn[data-fuel]').forEach(b =>
|
||||||
b.classList.toggle('active', b.dataset.fuel === currentFuel));
|
b.classList.toggle('active', b.dataset.fuel === currentFuel));
|
||||||
rebuildMarkers();
|
rebuildMarkers();
|
||||||
updateURL();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('costco-toggle').addEventListener('change', function () {
|
document.getElementById('costco-toggle').addEventListener('change', function () {
|
||||||
showCostco = this.checked;
|
showCostco = this.checked;
|
||||||
rebuildMarkers();
|
rebuildMarkers();
|
||||||
updateURL();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── Locate-me button ───────────────────────────────────
|
|
||||||
var locateBtn = document.getElementById('locate-btn');
|
|
||||||
if (locateBtn) {
|
|
||||||
locateBtn.addEventListener('click', function () {
|
|
||||||
if (!navigator.geolocation) return;
|
|
||||||
navigator.geolocation.getCurrentPosition(function (pos) {
|
|
||||||
var latlng = [pos.coords.latitude, pos.coords.longitude];
|
|
||||||
map.setView(latlng, 14);
|
|
||||||
if (locateMarker) {
|
|
||||||
locateMarker.setLatLng(latlng);
|
|
||||||
} else {
|
|
||||||
var dotIcon = L.divIcon({
|
|
||||||
html: '<div class="locate-dot"><div class="locate-dot-pulse"></div><div class="locate-dot-inner"></div></div>',
|
|
||||||
className: '',
|
|
||||||
iconSize: [20, 20],
|
|
||||||
iconAnchor: [10, 10],
|
|
||||||
});
|
|
||||||
locateMarker = L.marker(latlng, { icon: dotIcon, pane: 'locatePane' }).addTo(map);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Mobile filter panel toggle ─────────────────────────
|
// ── Mobile filter panel toggle ─────────────────────────
|
||||||
var filterToggle = document.getElementById('filter-toggle');
|
var filterToggle = document.getElementById('filter-toggle');
|
||||||
var sliderPanel = document.getElementById('slider-panel');
|
var sliderPanel = document.getElementById('slider-panel');
|
||||||
|
|
@ -343,18 +282,10 @@
|
||||||
const loadingEl = document.getElementById('loading');
|
const loadingEl = document.getElementById('loading');
|
||||||
try {
|
try {
|
||||||
// Create map and cluster group now that the DOM is ready.
|
// Create map and cluster group now that the DOM is ready.
|
||||||
const initCenter = (_initLat !== null && _initLng !== null) ? [_initLat, _initLng] : [46.8, -71.2];
|
map = L.map('map', { zoomControl: false }).setView([46.8, -71.2], 7);
|
||||||
const initZoom = _initZoom !== null ? _initZoom : 7;
|
|
||||||
map = L.map('map', { zoomControl: false }).setView(initCenter, initZoom);
|
|
||||||
map.createPane('locatePane').style.zIndex = 650;
|
|
||||||
L.control.zoom({ position: 'topright' }).addTo(map);
|
L.control.zoom({ position: 'topright' }).addTo(map);
|
||||||
var lastUpdatedText = (document.getElementById('last-updated') || {}).textContent || '';
|
|
||||||
var lastUpdatedMobile = document.getElementById('last-updated-mobile');
|
|
||||||
if (lastUpdatedMobile && lastUpdatedText) {
|
|
||||||
lastUpdatedMobile.textContent = lastUpdatedText;
|
|
||||||
}
|
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> | Données: <a href="https://regieessencequebec.ca">Régie de l\'énergie du Québec</a>' + (lastUpdatedText ? ' | ' + lastUpdatedText : ''),
|
attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> | Données: <a href="https://regieessencequebec.ca">Régie de l\'énergie du Québec</a>',
|
||||||
maxZoom: 18,
|
maxZoom: 18,
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
|
|
||||||
|
|
@ -393,46 +324,11 @@
|
||||||
|
|
||||||
loadingEl.style.display = 'none';
|
loadingEl.style.display = 'none';
|
||||||
|
|
||||||
// Apply initial state from URL params to UI controls.
|
|
||||||
if (currentFuel !== 'regular') {
|
|
||||||
document.querySelectorAll('.fuel-btn[data-fuel]').forEach(b =>
|
|
||||||
b.classList.toggle('active', b.dataset.fuel === currentFuel));
|
|
||||||
}
|
|
||||||
if (clusterMode !== 'avg') {
|
|
||||||
document.querySelectorAll('.cluster-btn').forEach(b =>
|
|
||||||
b.classList.toggle('active', b.dataset.mode === clusterMode));
|
|
||||||
}
|
|
||||||
if (!showCostco) {
|
|
||||||
const ct = document.getElementById('costco-toggle');
|
|
||||||
if (ct) ct.checked = false;
|
|
||||||
}
|
|
||||||
if (currentRegion) {
|
|
||||||
const rs = document.getElementById('region-select');
|
|
||||||
if (rs) rs.value = currentRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildMarkers();
|
rebuildMarkers();
|
||||||
|
|
||||||
// Override slider value from URL after rebuildMarkers set it.
|
|
||||||
if (_initPrice !== null) {
|
|
||||||
const slider = document.getElementById('price-slider');
|
|
||||||
if (slider && _initPrice < parseFloat(slider.max)) {
|
|
||||||
slider.value = _initPrice;
|
|
||||||
document.getElementById('slider-label').textContent = _initPrice.toFixed(1) + '¢/L';
|
|
||||||
applyPriceFilter(_initPrice, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
map.addLayer(clusterGroup);
|
map.addLayer(clusterGroup);
|
||||||
|
|
||||||
bindControls();
|
bindControls();
|
||||||
|
|
||||||
// Update URL on map move/zoom.
|
|
||||||
map.on('moveend zoomend', function () {
|
|
||||||
clearTimeout(mapMoveTimer);
|
|
||||||
mapMoveTimer = setTimeout(updateURL, 200);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Expose for use after htmx page-swap back to the map page.
|
// Expose for use after htmx page-swap back to the map page.
|
||||||
window.__mapInvalidate = function () {
|
window.__mapInvalidate = function () {
|
||||||
setTimeout(() => map.invalidateSize(), 50);
|
setTimeout(() => map.invalidateSize(), 50);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Layout ─────────────────────────────────────────── */
|
/* ── Layout ─────────────────────────────────────────── */
|
||||||
html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
html, body { height: 100%; margin: 0; padding: 0; }
|
||||||
|
|
||||||
/* ── Top nav ─────────────────────────────────────────── */
|
/* ── Top nav ─────────────────────────────────────────── */
|
||||||
#topnav {
|
#topnav {
|
||||||
|
|
@ -47,17 +47,6 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
color: var(--primary-foreground);
|
color: var(--primary-foreground);
|
||||||
}
|
}
|
||||||
#topnav nav a svg { flex-shrink: 0; }
|
#topnav nav a svg { flex-shrink: 0; }
|
||||||
.github-link {
|
|
||||||
margin-left: auto;
|
|
||||||
display: flex; align-items: center;
|
|
||||||
color: var(--muted-foreground);
|
|
||||||
padding: 5px 6px; border-radius: 6px;
|
|
||||||
transition: background 0.12s, color 0.12s;
|
|
||||||
}
|
|
||||||
.github-link:hover {
|
|
||||||
background: var(--muted);
|
|
||||||
color: var(--foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── App shell ───────────────────────────────────────── */
|
/* ── App shell ───────────────────────────────────────── */
|
||||||
#app {
|
#app {
|
||||||
|
|
@ -70,7 +59,7 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Map page ────────────────────────────────────────── */
|
/* ── Map page ────────────────────────────────────────── */
|
||||||
#page-map { display: flex; flex-direction: column; flex: 1; position: relative; overflow: hidden; }
|
#page-map { display: flex; flex-direction: column; flex: 1; position: relative; }
|
||||||
#map { flex: 1; min-height: 0; }
|
#map { flex: 1; min-height: 0; }
|
||||||
|
|
||||||
/* Slider + fuel panel */
|
/* Slider + fuel panel */
|
||||||
|
|
@ -96,11 +85,6 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
}
|
}
|
||||||
#visible-count { margin-top: 6px; font-size: 11px; color: var(--muted-foreground); }
|
#visible-count { margin-top: 6px; font-size: 11px; color: var(--muted-foreground); }
|
||||||
|
|
||||||
/* Last-updated: only shown inside the mobile filter drawer */
|
|
||||||
#last-updated-mobile {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map overlay panels — sit above the Leaflet tiles */
|
/* Map overlay panels — sit above the Leaflet tiles */
|
||||||
.map-panel {
|
.map-panel {
|
||||||
background: var(--card);
|
background: var(--card);
|
||||||
|
|
@ -133,54 +117,15 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
font-size: 10px; color: var(--muted-foreground);
|
font-size: 10px; color: var(--muted-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#last-updated {
|
||||||
|
position: absolute; bottom: 24px; right: 8px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
z-index: 1000; font-size: 11px;
|
||||||
|
color: var(--muted-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
.pin-icon { filter: drop-shadow(0 1px 3px rgba(0,0,0,0.35)); }
|
.pin-icon { filter: drop-shadow(0 1px 3px rgba(0,0,0,0.35)); }
|
||||||
|
|
||||||
#locate-btn {
|
|
||||||
position: absolute; bottom: 34px; right: 8px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
padding: 0;
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 6px;
|
|
||||||
background: var(--card);
|
|
||||||
color: var(--card-foreground);
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
||||||
cursor: pointer;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
#locate-btn:hover { background: var(--muted); }
|
|
||||||
|
|
||||||
/* Locate-me blue dot + pulse ring */
|
|
||||||
.locate-dot {
|
|
||||||
position: relative;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
.locate-dot-inner {
|
|
||||||
position: absolute;
|
|
||||||
inset: 4px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #2563eb;
|
|
||||||
border: 2.5px solid #fff;
|
|
||||||
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.locate-dot-pulse {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #2563eb;
|
|
||||||
opacity: 0.35;
|
|
||||||
animation: locate-pulse 1.8s ease-out infinite;
|
|
||||||
}
|
|
||||||
@keyframes locate-pulse {
|
|
||||||
0% { transform: scale(0.6); opacity: 0.5; }
|
|
||||||
100% { transform: scale(2.2); opacity: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster-info-tip {
|
.cluster-info-tip {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
@ -320,9 +265,6 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
#filter-toggle { display: flex; }
|
#filter-toggle { display: flex; }
|
||||||
|
|
||||||
#filter-toggle,
|
|
||||||
#locate-btn { bottom: 24px; }
|
|
||||||
|
|
||||||
#slider-panel {
|
#slider-panel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: auto; left: 0; right: 0; bottom: 0;
|
top: auto; left: 0; right: 0; bottom: 0;
|
||||||
|
|
@ -375,15 +317,4 @@ html, body { height: 100%; margin: 0; padding: 0; overflow-x: hidden; }
|
||||||
.cluster-info-tip { display: none; }
|
.cluster-info-tip { display: none; }
|
||||||
.cluster-hint { display: block; }
|
.cluster-hint { display: block; }
|
||||||
.cluster-row { margin-bottom: 0; }
|
.cluster-row { margin-bottom: 0; }
|
||||||
|
|
||||||
/* Hide Leaflet attribution bar on mobile */
|
|
||||||
.leaflet-control-attribution { display: none; }
|
|
||||||
|
|
||||||
/* Show last-updated inside the filter drawer */
|
|
||||||
#last-updated-mobile {
|
|
||||||
display: block;
|
|
||||||
margin-top: 6px;
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--muted-foreground);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Prix du Gaz</title>
|
<title>Essence Québec</title>
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css" />
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css" />
|
||||||
|
|
@ -51,11 +51,6 @@
|
||||||
Statistiques
|
Statistiques
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
<a href="https://github.com/Polensky/prixdugaz" target="_blank" rel="noopener noreferrer" class="github-link" aria-label="GitHub">
|
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M12 2C6.477 2 2 6.477 2 12c0 4.418 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.009-.868-.013-1.703-2.782.605-3.369-1.342-3.369-1.342-.454-1.154-1.11-1.462-1.11-1.462-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836a9.59 9.59 0 0 1 2.504.337c1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.202 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.744 0 .267.18.579.688.481C19.138 20.163 22 16.418 22 12c0-5.523-4.477-10-10-10z"/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- ── Content area (htmx swap target) ── -->
|
<!-- ── Content area (htmx swap target) ── -->
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@
|
||||||
<span id="slider-max">-</span>
|
<span id="slider-max">-</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="visible-count"></div>
|
<div id="visible-count"></div>
|
||||||
<div id="last-updated-mobile"></div>
|
|
||||||
<div id="legend">
|
<div id="legend">
|
||||||
<div class="legend-header" id="legend-title">Régulier (¢/L)</div>
|
<div class="legend-header" id="legend-title">Régulier (¢/L)</div>
|
||||||
<div class="legend-gradient"></div>
|
<div class="legend-gradient"></div>
|
||||||
|
|
@ -67,10 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="filter-backdrop"></div>
|
<div id="filter-backdrop"></div>
|
||||||
<button id="locate-btn" aria-label="Ma position" title="Ma position">
|
<div id="last-updated" class="map-panel">{{.LastUpdated}}</div>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg>
|
|
||||||
</button>
|
|
||||||
<div id="last-updated" hidden>{{.LastUpdated}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue