import Component from '@glimmer/component'; import { service } from '@ember/service'; import { action } from '@ember/object'; import { on } from '@ember/modifier'; import { fn } from '@ember/helper'; import or from 'ember-truth-helpers/helpers/or'; import PlaceDetails from './place-details'; export default class PlacesSidebar extends Component { @service storage; @action selectPlace(place) { if (this.args.onSelect) { this.args.onSelect(place); } } @action clearSelection() { // Going "back" clears the specific selection but keeps the sidebar open (showing list) if (this.args.onSelect) { this.args.onSelect(null); } // Fallback logic: if no list available, close sidebar if (!this.args.places || this.args.places.length === 0) { if (this.args.onClose) { this.args.onClose(); } } } get geoLink() { if (!this.args.selectedPlace) return '#'; const p = this.args.selectedPlace; // geo:lat,lon?q=lat,lon(Label) const label = encodeURIComponent( p.title || p.tags?.name || p.tags?.['name:en'] || 'Location' ); return `geo:${p.lat},${p.lon}?q=${p.lat},${p.lon}(${label})`; } get visibleGeoLink() { if (!this.args.selectedPlace) return ''; const p = this.args.selectedPlace; return `geo:${p.lat},${p.lon}`; } @action async toggleSave(place) { if (!place) return; if (place.createdAt) { // It's a saved bookmark -> Delete it if (confirm(`Delete "${place.title}"?`)) { try { if (place.id && place.geohash) { await this.storage.places.remove(place.id, place.geohash); console.log('Place deleted:', place.title); // Notify parent to refresh map bookmarks if (this.args.onBookmarkChange) { this.args.onBookmarkChange(); } // Update selection to the new saved place object // This updates the local UI state immediately without a route refresh if (this.args.onUpdate) { // When deleting, we revert to a "fresh" object or just close. // Since we close the sidebar below, we might not strictly need to update local state, // but it's good practice. // Reconstruct the "original" place without ID/Geohash/CreatedAt const freshPlace = { ...place, id: undefined, geohash: undefined, createdAt: undefined }; this.args.onUpdate(freshPlace); } // Also fire onSelect if it exists (for list view) if (this.args.onSelect) { // Similar logic for select if needed, but we usually close. this.args.onSelect(null); } // Close sidebar after delete if (this.args.onClose) { this.args.onClose(); } } else { alert('Cannot delete: Missing ID or Geohash'); } } catch (e) { console.error('Failed to delete:', e); alert('Failed to delete: ' + e.message); } } } else { // It's a fresh POI -> Save it const placeData = { title: place.osmTags.name || place.osmTags['name:en'] || 'Untitled Place', lat: place.lat, lon: place.lon, tags: [], url: place.osmTags.website, osmId: String(place.osmId || place.id), // Ensure we grab osmId if available, or fallback to id osmType: place.osmType, osmTags: place.osmTags, }; try { const savedPlace = await this.storage.places.store(placeData); console.log('Place saved:', placeData.title); // Notify parent to refresh map bookmarks if (this.args.onBookmarkChange) { this.args.onBookmarkChange(); } // Update selection to the new saved place object if (this.args.onUpdate) { this.args.onUpdate(savedPlace); } // Update selection to the new saved place object if (this.args.onSelect) { this.args.onSelect(savedPlace); } } catch (error) { console.error('Failed to save place:', error); alert('Failed to save place: ' + error.message); } } } }