feat(whereami): side-by-side map and weather layout

This commit is contained in:
Adriano Caloiaro 2026-04-09 23:03:50 -06:00
parent 3e7c61af44
commit 6dd249dc17
No known key found for this signature in database

View file

@ -2,19 +2,39 @@
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script>
<style> <style>
#map { height: 480px; }
#location-name { min-height: 1.5em; } #location-name { min-height: 1.5em; }
#weather { margin-top: 1.5rem; } .container { max-width: 1200px; width: 95%; }
#weather table { border-collapse: collapse; } #page-grid {
#weather td { padding: 0.2rem 0.8rem 0.2rem 0; } display: grid;
#weather td:first-child { color: #888; white-space: nowrap; } grid-template-columns: 3fr 2fr;
gap: 1rem;
align-items: start;
}
@media (max-width: 700px) {
#page-grid { grid-template-columns: 1fr; }
}
#map { height: 520px; }
#weather-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.4rem 1rem;
}
.wx-card {
border-left: 2px solid #ddd;
padding: 0.2rem 0 0.2rem 0.5rem;
}
.wx-label { font-size: 0.72em; color: #888; margin: 0; line-height: 1.2; }
.wx-value { font-size: 1.05em; margin: 0; line-height: 1.3; }
#weather-updated { font-size: 0.75em; color: #888; margin-bottom: 0.6rem; }
</style> </style>
<div class="container" role="main"> <div class="container" role="main">
<h2 id="location-name">Fetching location&hellip;</h2> <h2 id="location-name">Fetching location&hellip;</h2>
<div id="map"></div>
<div id="weather"></div> <div id="page-grid">
<div id="map"></div>
<div id="weather"></div>
</div>
<script> <script>
var map = L.map('map').setView([0, 0], 2); var map = L.map('map').setView([0, 0], 2);
@ -52,29 +72,35 @@
fetch('https://jellybee.bison-lizard.ts.net/weather') fetch('https://jellybee.bison-lizard.ts.net/weather')
.then(function(r) { if (!r.ok) throw new Error(r.status); return r.json(); }) .then(function(r) { if (!r.ok) throw new Error(r.status); return r.json(); })
.then(function(w) { .then(function(w) {
var rows = []; function fmt1(v) { return v !== undefined && v !== null ? Math.round(v * 10) / 10 : null; }
function row(label, val, unit) { function fmt0(v) { return v !== undefined && v !== null ? Math.round(v) : null; }
if (val === undefined || val === null) return; var cards = [
rows.push('<tr><td>' + label + '</td><td>' + val + (unit ? ' ' + unit : '') + '</td></tr>'); { label: 'Temperature', value: fmt1(w.tempf), unit: '°F' },
} { label: 'Feels like', value: fmt1(w.feelsLike), unit: '°F' },
row('Temperature', w.tempf !== undefined ? Math.round(w.tempf * 10) / 10 : undefined, '°F'); { label: 'Humidity', value: fmt0(w.humidity), unit: '%' },
row('Feels like', w.feelsLike !== undefined ? Math.round(w.feelsLike * 10) / 10 : undefined, '°F'); { label: 'Dew point', value: fmt1(w.dewPoint), unit: '°F' },
row('Humidity', w.humidity !== undefined ? Math.round(w.humidity) : undefined, '%'); { label: 'Wind speed', value: fmt1(w.windspeedmph), unit: 'mph' },
row('Dew point', w.dewPoint !== undefined ? Math.round(w.dewPoint * 10) / 10 : undefined, '°F'); { label: 'Wind gust', value: fmt1(w.windgustmph), unit: 'mph' },
row('Wind', w.windspeedmph !== undefined ? Math.round(w.windspeedmph * 10) / 10 : undefined, 'mph'); { label: 'Pressure', value: fmt1(w.baromrelin), unit: 'inHg' },
row('Wind gust', w.windgustmph !== undefined ? Math.round(w.windgustmph * 10) / 10 : undefined, 'mph'); { label: 'UV index', value: fmt0(w.uv), unit: '' },
row('UV index', w.uv !== undefined ? Math.round(w.uv) : undefined, ''); { label: 'Solar', value: fmt0(w.solarradiation), unit: 'W/m²' },
row('Solar radiation', w.solarradiation !== undefined ? Math.round(w.solarradiation) : undefined, 'W/m²'); { label: 'Rain (hourly)', value: w.hourlyrainin, unit: 'in' },
row('Rain (hourly)', w.hourlyrainin, 'in'); { label: 'Rain (daily)', value: w.dailyrainin, unit: 'in' },
row('Rain (daily)', w.dailyrainin, 'in'); { label: 'Indoor temp', value: fmt1(w.tempinf), unit: '°F' },
row('Pressure (rel)', w.baromrelin, 'inHg'); { label: 'Indoor humidity', value: fmt0(w.humidityin), unit: '%' },
row('Indoor temp', w.tempinf !== undefined ? Math.round(w.tempinf * 10) / 10 : undefined, '°F'); ].filter(function(c) { return c.value !== null && c.value !== undefined; });
row('Indoor humidity', w.humidityin !== undefined ? Math.round(w.humidityin) : undefined, '%');
if (rows.length === 0) return; if (cards.length === 0) return;
var updated = w.lastUpdated ? new Date(w.lastUpdated).toLocaleTimeString() : ''; var updated = w.lastUpdated ? new Date(w.lastUpdated).toLocaleTimeString() : '';
document.getElementById('weather').innerHTML = var html = '<h3 style="margin-bottom:0.3rem">Local Weather</h3>';
'<h3>Local Weather' + (updated ? ' <small style="font-weight:normal;font-size:0.7em;color:#888">updated ' + updated + '</small>' : '') + '</h3>' + if (updated) html += '<div id="weather-updated">updated ' + updated + '</div>';
'<table>' + rows.join('') + '</table>'; html += '<div id="weather-grid">';
cards.forEach(function(c) {
html += '<div class="wx-card"><p class="wx-label">' + c.label + '</p><p class="wx-value">' + c.value + (c.unit ? ' ' + c.unit : '') + '</p></div>';
});
html += '</div>';
document.getElementById('weather').innerHTML = html;
}) })
.catch(function() {}); .catch(function() {});
</script> </script>