UX: Nearby-POIs einklappbar + klickbar + nur relevante Typen
- NEARBY_TYPES: Bänke/Wasserstellen entfernt → nur Restaurant, Tierarzt, Zoobedarf - Gruppen einklappbar (Chevron dreht sich) - POI-Namen anklickbar → öffnet Apple Maps/Google Maps am POI-Standort - CSS: Card-Stil für Gruppen, gute Touch-Targets
This commit is contained in:
parent
9a56978f81
commit
3144e100f3
3 changed files with 95 additions and 29 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '226'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '227'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
|
||||
const App = (() => {
|
||||
|
||||
|
|
|
|||
|
|
@ -34,12 +34,11 @@ window.Page_routes = (() => {
|
|||
const TERRAIN_LABEL = { wald: '🌲 Wald', asphalt: '🛣️ Asphalt', wiese: '🌿 Wiese', mix: '🔀 Mix' };
|
||||
const HUNDE_LABEL = { eingeschränkt: '🐾', gut: '🐾🐾', sehr_gut: '🐾🐾🐾', premium: '🐾🐾🐾🐾' };
|
||||
|
||||
// POI-Typen die entlang einer Route gezeigt werden
|
||||
// POI-Typen entlang der Route — nur relevante/interessante Orte
|
||||
const NEARBY_TYPES = [
|
||||
{ type: 'restaurant', icon: '🍽️', label: 'Restaurant/Café' },
|
||||
{ type: 'parkplatz', icon: '🅿️', label: 'Parkplatz' },
|
||||
{ type: 'drinking_water', icon: '💧', label: 'Wasserstelle' },
|
||||
{ type: 'bank', icon: '🪑', label: 'Bank' },
|
||||
{ type: 'restaurant', icon: '🍽️', label: 'Restaurant/Café' },
|
||||
{ type: 'tierarzt', icon: '🏥', label: 'Tierarzt' },
|
||||
{ type: 'shop', icon: '🐾', label: 'Zoobedarf' },
|
||||
];
|
||||
|
||||
// _esc und _emptyState ersetzt durch UI.escape() / UI.emptyState()
|
||||
|
|
@ -936,7 +935,6 @@ window.Page_routes = (() => {
|
|||
if (!el) return;
|
||||
if (!pois.length) { el.innerHTML = ''; return; }
|
||||
|
||||
// Gruppieren nach Typ
|
||||
const byType = {};
|
||||
pois.forEach(p => {
|
||||
const key = p._label;
|
||||
|
|
@ -944,22 +942,64 @@ window.Page_routes = (() => {
|
|||
byType[key].items.push(p);
|
||||
});
|
||||
|
||||
let gIdx = 0;
|
||||
el.innerHTML = `
|
||||
<div class="rk-nearby-title">${UI.icon('map-pin')} Entlang der Route</div>
|
||||
${Object.values(byType).map(group => `
|
||||
<div class="rk-nearby-group">
|
||||
<div class="rk-nearby-group-label">${group.icon} ${UI.escape(group.label)} (${group.items.length})</div>
|
||||
${group.items.slice(0, 5).map(p => `
|
||||
<div class="rk-nearby-item">
|
||||
<span class="rk-nearby-name">${UI.escape(p.name || group.label)}</span>
|
||||
${p.opening_hours ? `<span class="rk-nearby-detail">${UI.icon('clock')} ${UI.escape(p.opening_hours)}</span>` : ''}
|
||||
${p.phone ? `<a href="tel:${UI.escape(p.phone)}" class="rk-nearby-detail rk-nearby-phone">${UI.icon('phone')} ${UI.escape(p.phone)}</a>` : ''}
|
||||
${Object.values(byType).map(group => {
|
||||
const id = `rk-ng-${gIdx++}`;
|
||||
return `
|
||||
<div class="rk-nearby-group">
|
||||
<button class="rk-nearby-group-header" data-target="${id}" type="button">
|
||||
<span>${group.icon} ${UI.escape(group.label)} (${group.items.length})</span>
|
||||
<svg class="ph-icon rk-nearby-chevron" aria-hidden="true" style="transition:transform 0.2s">
|
||||
<use href="/icons/phosphor.svg#caret-down"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<div id="${id}" class="rk-nearby-items">
|
||||
${group.items.map(p => `
|
||||
<button class="rk-nearby-item rk-nearby-item--link" type="button"
|
||||
data-lat="${p.lat}" data-lon="${p.lon}"
|
||||
data-name="${UI.escape(p.name || group.label)}">
|
||||
<div>
|
||||
<span class="rk-nearby-name">${UI.escape(p.name || group.label)}</span>
|
||||
${p.opening_hours ? `<span class="rk-nearby-detail">${UI.icon('clock')} ${UI.escape(p.opening_hours)}</span>` : ''}
|
||||
${p.phone ? `<span class="rk-nearby-detail">${UI.icon('phone')} ${UI.escape(p.phone)}</span>` : ''}
|
||||
</div>
|
||||
<svg class="ph-icon" style="width:14px;height:14px;color:var(--c-text-muted);flex-shrink:0" aria-hidden="true">
|
||||
<use href="/icons/phosphor.svg#map-pin"></use>
|
||||
</svg>
|
||||
</button>
|
||||
`).join('')}
|
||||
</div>
|
||||
`).join('')}
|
||||
${group.items.length > 5 ? `<div style="font-size:var(--text-xs);color:var(--c-text-muted);padding:2px 0">+${group.items.length-5} weitere</div>` : ''}
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>`;
|
||||
}).join('')}
|
||||
`;
|
||||
|
||||
// Einklapp-Logik
|
||||
el.querySelectorAll('.rk-nearby-group-header').forEach(btn => {
|
||||
const target = document.getElementById(btn.dataset.target);
|
||||
const chevron = btn.querySelector('.rk-nearby-chevron');
|
||||
let open = true;
|
||||
btn.addEventListener('click', () => {
|
||||
open = !open;
|
||||
target.style.display = open ? '' : 'none';
|
||||
chevron.style.transform = open ? '' : 'rotate(-90deg)';
|
||||
});
|
||||
});
|
||||
|
||||
// POI auf Karte zeigen
|
||||
el.querySelectorAll('.rk-nearby-item--link').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
const lat = parseFloat(btn.dataset.lat);
|
||||
const lon = parseFloat(btn.dataset.lon);
|
||||
const name = btn.dataset.name;
|
||||
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
|
||||
const url = isIOS
|
||||
? `maps://maps.apple.com/?q=${encodeURIComponent(name)}&ll=${lat},${lon}`
|
||||
: `https://www.google.com/maps/search/?api=1&query=${lat},${lon}`;
|
||||
window.open(url, '_blank');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue