import { Controller } from '@hotwired/stimulus'; import L from 'leaflet'; import 'leaflet/dist/leaflet.min.css'; L.Icon.Default.mergeOptions({ iconUrl: '/leaflet/marker-icon.png', iconRetinaUrl: '/leaflet/marker-icon-2x.png', shadowUrl: '/leaflet/marker-shadow.png', }); export default class extends Controller { connect() { this.map = L.map(this.element).setView([51.0543, 3.7174], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19, }).addTo(this.map); this.loadSubjects(); this.map.on('click', (e) => this.createSubject(e.latlng)); } loadSubjects() { fetch('/api/subjects') .then(r => r.json()) .then(data => { data.payload.subjects.forEach(s => { if (s.latitude && s.longitude) { this.addMarker(s.latitude, s.longitude, s.name); } }); }); } createSubject(latlng) { const name = prompt('Name of this place?'); if (!name) return; fetch('/api/subjects', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, latitude: latlng.lat, longitude: latlng.lng, }), }) .then(r => r.json()) .then(() => this.addMarker(latlng.lat, latlng.lng, name)); } addMarker(lat, lng, name) { L.marker([lat, lng]).addTo(this.map).bindPopup(name); } }