Feature: Gassirunden-Chip auf Welcome öffnet direkt ORS-Vorschlag im Routen-Tab — SW by-v479, APP_VER 456

This commit is contained in:
rene 2026-04-29 08:18:16 +02:00
parent 369eae5e5a
commit ca8bb495b0
4 changed files with 61 additions and 76 deletions

View file

@ -74,17 +74,32 @@ window.Page_routes = (() => {
// _esc und _emptyState ersetzt durch UI.escape() / UI.emptyState()
async function init(container, appState) {
async function init(container, appState, params = {}) {
_container = container;
_appState = appState;
// Vorberechneter Vorschlag vom Welcome-Chip → direkt in Suggest-Tab anzeigen
if (params._suggestResult) {
_suggestResult = params._suggestResult;
_suggestKm = params._suggestKm || _suggestKm;
_suggestSeed = params._suggestSeed || _suggestSeed;
_browseMode = 'suggest';
}
_render();
UI.loadLeaflet(); // fire & forget — bereit wenn Cards gerendert werden
try { _userPos = await API.getLocation(); } catch {}
await _loadData();
// Vorschlag sofort rendern (Leaflet war noch nicht bereit bei _render)
if (params._suggestResult) {
_renderSuggestTab();
_showSuggestResult(params._suggestResult);
}
// Deep-Link: /#routes?id=123 → direkt Route-Detail öffnen
const params = new URLSearchParams((location.hash.split('?')[1] || ''));
const deepId = params.get('id');
const urlParams = new URLSearchParams((location.hash.split('?')[1] || ''));
const deepId = urlParams.get('id');
if (deepId) {
_openDetail(parseInt(deepId, 10));
}
@ -486,19 +501,22 @@ window.Page_routes = (() => {
}
if (calcBtn) calcBtn.disabled = false;
// Ergebnis rendern
const distStr = result.distanz_km ? result.distanz_km.toFixed(2) + ' km' : '';
const durStr = result.dauer_min
_showSuggestResult(result);
}
function _showSuggestResult(result) {
_suggestResult = result;
const res = document.getElementById('rks-result');
if (!res) return;
const distStr = result.distanz_km ? result.distanz_km.toFixed(2) + ' km' : '';
const durStr = result.dauer_min
? (result.dauer_min < 60 ? result.dauer_min + ' min' : Math.floor(result.dauer_min/60) + 'h ' + (result.dauer_min%60||'') + 'min').trim()
: '';
const diffLabel = { leicht: 'Leicht', mittel: 'Mittel', anspruchsvoll: 'Schwer' }[result.schwierigkeit] || '';
if (!res) return;
res.innerHTML = `
<!-- Karte -->
<div id="rks-map" style="height:250px;background:var(--c-surface);margin-bottom:var(--space-3)"></div>
<!-- Info-Zeile -->
<div style="display:flex;gap:var(--space-3);align-items:center;flex-wrap:wrap;margin-bottom:var(--space-4)">
<span style="${_pillStyle('rgba(107,114,128,0.10)','#9ca3af','rgba(107,114,128,0.30)')}">
${UI.icon('map-trifold')} ${UI.escape(distStr)}
@ -513,8 +531,6 @@ window.Page_routes = (() => {
<span style="font-size:0.85rem;color:var(--c-text-secondary);flex:1;min-width:0;
overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${UI.escape(result.name || '')}</span>
</div>
<!-- Aktions-Buttons -->
<div style="display:flex;gap:var(--space-3)">
<button id="rks-nav-btn" style="${_btnStyle(false)}flex:1">
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#navigation-arrow"></use></svg>
@ -524,63 +540,42 @@ window.Page_routes = (() => {
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#floppy-disk"></use></svg>
Route speichern
</button>
</div>
`;
</div>`;
// Leaflet-Karte mit dem berechneten Track
const _initMap = () => {
const mapEl = document.getElementById('rks-map');
if (!mapEl || !window.L) return;
if (_suggestMap) { _suggestMap.remove(); _suggestMap = null; }
const track = result.gps_track || [];
if (track.length < 2) { mapEl.innerHTML = '<div style="height:100%;display:flex;align-items:center;justify-content:center;color:var(--c-text-muted)">Kein Track vorhanden</div>'; return; }
const lls = track.map(p => [p.lat, p.lon]);
if (track.length < 2) return;
const lls = track.map(p => [p.lat, p.lon]);
_suggestMap = L.map(mapEl, { zoomControl: false, attributionControl: false,
dragging: true, touchZoom: true, scrollWheelZoom: false });
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19 }).addTo(_suggestMap);
const poly = L.polyline(lls, { color: '#C4843A', weight: 4, opacity: 0.9 }).addTo(_suggestMap);
L.circleMarker(lls[0], { radius:7, color:'#22C55E', fillColor:'#22C55E', fillOpacity:1, weight:2 }).addTo(_suggestMap);
L.circleMarker(lls.at(-1), { radius:7, color:'#EF4444', fillColor:'#EF4444', fillOpacity:1, weight:2 }).addTo(_suggestMap);
L.circleMarker(lls[0], { radius:7, color:'#22C55E', fillColor:'#22C55E', fillOpacity:1, weight:2 }).addTo(_suggestMap);
L.circleMarker(lls.at(-1), { radius:7, color:'#EF4444', fillColor:'#EF4444', fillOpacity:1, weight:2 }).addTo(_suggestMap);
_addRouteArrows(_suggestMap, track, '#3b82f6');
_suggestMap.fitBounds(poly.getBounds(), { padding: [16, 16] });
setTimeout(() => _suggestMap?.invalidateSize(), 120);
};
if (window.L) {
_initMap();
} else {
if (window.L) { _initMap(); } else {
let tries = 0;
const poll = setInterval(() => {
if (window.L || ++tries > 40) { clearInterval(poll); if (window.L) _initMap(); }
}, 100);
}
// Navigation starten
document.getElementById('rks-nav-btn')?.addEventListener('click', () => {
if (!_suggestResult) return;
const route = {
id: 'suggest-' + Date.now(),
name: _suggestResult.name,
gps_track: _suggestResult.gps_track,
distanz_km: _suggestResult.distanz_km,
};
_openNavOverlay(route);
_openNavOverlay({ id: 'suggest-' + Date.now(), name: result.name,
gps_track: result.gps_track, distanz_km: result.distanz_km });
});
// Route speichern
document.getElementById('rks-save-btn')?.addEventListener('click', async () => {
const btn = document.getElementById('rks-save-btn');
if (!btn || !_suggestResult) return;
if (!btn) return;
await UI.asyncButton(btn, async () => {
await API.post('/routes', {
name: _suggestResult.name,
gps_track: _suggestResult.gps_track,
distanz_km: _suggestResult.distanz_km,
dauer_min: _suggestResult.dauer_min,
schwierigkeit: _suggestResult.schwierigkeit,
});
await API.post('/routes', { name: result.name, gps_track: result.gps_track,
distanz_km: result.distanz_km, dauer_min: result.dauer_min, schwierigkeit: result.schwierigkeit });
UI.toast.success('Route gespeichert!');
await _loadData();
_setBrowseMode('mine');