Wetter-Chip auf Karte + Bugfix private Routen zählen für km-Stats

- GET /api/weather?lat=&lon= (Open-Meteo, 30-min TTL-Cache)
- Zecken-Warnung regelbasiert: März–Okt + Temp > 7°C
- Karte: Wetterchip oben rechts nach GPS-Fix
- stats.py + achievements.py: is_public-Filter entfernt —
  private Routen zählen jetzt für eigene km/Achievements
- SW by-v320, APP_VER 308
This commit is contained in:
rene 2026-04-24 07:59:15 +02:00
parent 43d33c0fd1
commit 0461f936ce
9 changed files with 185 additions and 13 deletions

View file

@ -2723,6 +2723,42 @@ html.modal-open {
pointer-events: none;
}
/* Wetter-Chip — oben rechts auf der Karte */
.map-weather-chip {
position: absolute;
top: var(--space-3);
right: var(--space-3);
z-index: 1000;
background: rgba(255,255,255,0.92);
backdrop-filter: blur(4px);
border: 1px solid var(--c-border-light);
border-radius: var(--radius-full);
padding: 5px 12px;
font-size: 13px;
color: var(--c-text);
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
display: flex;
align-items: center;
gap: var(--space-2);
pointer-events: none;
user-select: none;
}
.map-weather-chip--hidden { display: none; }
.map-weather-chip__temp { font-weight: 700; }
.map-weather-chip__desc { color: var(--c-text-secondary); font-size: 12px; }
.map-weather-chip__zecken {
background: #FEF3C7;
color: #92400E;
border-radius: var(--radius-full);
padding: 1px 7px;
font-size: 11px;
font-weight: 600;
}
.map-weather-chip__zecken--hoch {
background: #FEE2E2;
color: #991B1B;
}
/* Giftköder-Marker — pulsierend, rot, sofort erkennbar */
.poison-marker {
position: relative;

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '307'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '308'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const App = (() => {

View file

@ -144,6 +144,7 @@ window.Page_map = (() => {
_userPos = pos;
if (_frankfurtTimer) { clearTimeout(_frankfurtTimer); _frankfurtTimer = null; }
_map?.flyTo([pos.lat, pos.lon], 14, { duration: 1.2 });
_loadWeather(pos.lat, pos.lon);
}).catch(() => {
const btn = document.getElementById('map-locate-btn');
if (btn) {
@ -195,6 +196,8 @@ window.Page_map = (() => {
<button class="map-fab" id="map-locate-btn" title="Meinen Standort"><svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#map-pin"></use></svg></button>
</div>
<div class="map-weather-chip map-weather-chip--hidden" id="map-weather-chip"></div>
<div class="map-statusbar" id="map-statusbar">
<span id="map-zoom-info"></span>
<span id="map-osm-status"></span>
@ -1512,6 +1515,26 @@ window.Page_map = (() => {
});
}
// ----------------------------------------------------------
// WETTER-CHIP
// ----------------------------------------------------------
async function _loadWeather(lat, lon) {
const chip = document.getElementById('map-weather-chip');
if (!chip) return;
try {
const w = await API.get(`/api/weather?lat=${lat}&lon=${lon}`);
const temp = w.temp_c != null ? `${Math.round(w.temp_c)}°` : '';
const icon = `<svg class="ph-icon" aria-hidden="true" style="width:16px;height:16px"><use href="/icons/phosphor.svg#${w.icon}"></use></svg>`;
let zeckenHtml = '';
if (w.zecken_warnung) {
const cls = w.zecken_warnung === 'hoch' ? 'map-weather-chip__zecken map-weather-chip__zecken--hoch' : 'map-weather-chip__zecken';
zeckenHtml = `<span class="${cls}" title="Zeckenrisiko ${w.zecken_warnung}">🦟 Zecken</span>`;
}
chip.innerHTML = `${icon}<span class="map-weather-chip__temp">${temp}</span><span class="map-weather-chip__desc">${w.desc}</span>${zeckenHtml}`;
chip.classList.remove('map-weather-chip--hidden');
} catch { /* still */ }
}
return { init, refresh, onDogChange, startRecording: _startRecording, stopRecording: _stopRecording, isRecording: () => _recActive };
})();

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache
============================================================ */
const CACHE_VERSION = 'by-v319';
const CACHE_VERSION = 'by-v320';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten