689 lines
26 KiB
JavaScript
689 lines
26 KiB
JavaScript
// UI interaction handlers
|
||
import { showStatus, parseGeoLocation } from './utils.js';
|
||
import { map, toggleStartLocationVisibility } from './map-manager.js';
|
||
import { loadLocations, handleAddLocation, handleEditLocation, handleDeleteLocation, openEditForm, closeEditForm, closeAddModal, openAddModal } from './location-manager.js';
|
||
|
||
export let userLocationMarker = null;
|
||
export let isAddingLocation = false;
|
||
export let isAddressConfirmed = false;
|
||
export let isEditAddressConfirmed = false;
|
||
|
||
// Add this after the existing imports
|
||
let isMoveMode = false;
|
||
|
||
// Export function to get current confirmation states
|
||
export function getAddressConfirmationState() {
|
||
return {
|
||
isAddressConfirmed,
|
||
isEditAddressConfirmed
|
||
};
|
||
}
|
||
|
||
// Add logout function
|
||
async function logout() {
|
||
try {
|
||
const response = await fetch('/api/auth/logout', {
|
||
method: 'POST',
|
||
credentials: 'include'
|
||
});
|
||
|
||
if (response.ok) {
|
||
// Clear any local storage or session storage
|
||
localStorage.clear();
|
||
sessionStorage.clear();
|
||
|
||
// Redirect to login page
|
||
window.location.href = '/login.html';
|
||
} else {
|
||
throw new Error('Logout failed');
|
||
}
|
||
} catch (error) {
|
||
console.error('Logout error:', error);
|
||
showStatus('Logout failed, redirecting anyway...', 'warning');
|
||
// Force redirect even if logout request fails
|
||
setTimeout(() => {
|
||
window.location.href = '/login.html';
|
||
}, 1000);
|
||
}
|
||
}
|
||
|
||
// Add logout handler function
|
||
function handleLogout(e) {
|
||
e.preventDefault();
|
||
if (confirm('Are you sure you want to logout?')) {
|
||
logout();
|
||
}
|
||
}
|
||
|
||
export function getUserLocation() {
|
||
if (!navigator.geolocation) {
|
||
showStatus('Geolocation is not supported by your browser', 'error');
|
||
return;
|
||
}
|
||
|
||
showStatus('Getting your location...', 'info');
|
||
|
||
navigator.geolocation.getCurrentPosition(
|
||
(position) => {
|
||
const lat = position.coords.latitude;
|
||
const lng = position.coords.longitude;
|
||
|
||
// Center map on user location
|
||
map.setView([lat, lng], 19);
|
||
|
||
// Add or update user location marker
|
||
if (userLocationMarker) {
|
||
userLocationMarker.setLatLng([lat, lng]);
|
||
} else {
|
||
userLocationMarker = L.circleMarker([lat, lng], {
|
||
radius: 10,
|
||
fillColor: '#2196F3',
|
||
color: '#fff',
|
||
weight: 3,
|
||
opacity: 1,
|
||
fillOpacity: 0.8
|
||
}).addTo(map);
|
||
|
||
userLocationMarker.bindPopup('<strong>Your Location</strong>');
|
||
}
|
||
|
||
showStatus('Location found!', 'success');
|
||
},
|
||
(error) => {
|
||
let message = 'Unable to get your location';
|
||
switch(error.code) {
|
||
case error.PERMISSION_DENIED:
|
||
message = 'Location permission denied';
|
||
break;
|
||
case error.POSITION_UNAVAILABLE:
|
||
message = 'Location information unavailable';
|
||
break;
|
||
case error.TIMEOUT:
|
||
message = 'Location request timed out';
|
||
break;
|
||
}
|
||
showStatus(message, 'error');
|
||
},
|
||
{
|
||
enableHighAccuracy: true,
|
||
timeout: 10000,
|
||
maximumAge: 0
|
||
}
|
||
);
|
||
}
|
||
|
||
export function toggleAddLocationMode() {
|
||
isAddingLocation = !isAddingLocation;
|
||
|
||
const crosshair = document.getElementById('crosshair');
|
||
const addBtn = document.getElementById('add-location-btn');
|
||
const mobileAddBtn = document.getElementById('mobile-add-location-btn');
|
||
|
||
if (isAddingLocation) {
|
||
crosshair.classList.remove('hidden');
|
||
|
||
// Update desktop button
|
||
if (addBtn) {
|
||
addBtn.classList.add('active');
|
||
addBtn.innerHTML = '<span class="btn-icon">✕</span><span class="btn-text">Cancel</span>';
|
||
}
|
||
|
||
// Update mobile button
|
||
if (mobileAddBtn) {
|
||
mobileAddBtn.classList.add('active');
|
||
mobileAddBtn.innerHTML = '✕';
|
||
mobileAddBtn.title = 'Cancel';
|
||
}
|
||
|
||
map.on('click', handleMapClick);
|
||
} else {
|
||
crosshair.classList.add('hidden');
|
||
|
||
// Update desktop button
|
||
if (addBtn) {
|
||
addBtn.classList.remove('active');
|
||
addBtn.innerHTML = '<span class="btn-icon">➕</span><span class="btn-text">Add Location Here</span>';
|
||
}
|
||
|
||
// Update mobile button
|
||
if (mobileAddBtn) {
|
||
mobileAddBtn.classList.remove('active');
|
||
mobileAddBtn.innerHTML = '➕';
|
||
mobileAddBtn.title = 'Add Location';
|
||
}
|
||
|
||
map.off('click', handleMapClick);
|
||
}
|
||
}
|
||
|
||
function handleMapClick(e) {
|
||
if (!isAddingLocation) return;
|
||
|
||
const { lat, lng } = e.latlng;
|
||
openAddModal(lat, lng);
|
||
toggleAddLocationMode();
|
||
}
|
||
|
||
export function toggleFullscreen() {
|
||
const app = document.getElementById('app');
|
||
const btn = document.getElementById('fullscreen-btn');
|
||
const mobileBtn = document.getElementById('mobile-fullscreen-btn');
|
||
|
||
if (!document.fullscreenElement) {
|
||
app.requestFullscreen().then(() => {
|
||
app.classList.add('fullscreen');
|
||
|
||
// Update desktop button
|
||
if (btn) {
|
||
btn.innerHTML = '<span class="btn-icon">◱</span><span class="btn-text">Exit Fullscreen</span>';
|
||
}
|
||
|
||
// Update mobile button
|
||
if (mobileBtn) {
|
||
mobileBtn.innerHTML = '◱';
|
||
mobileBtn.title = 'Exit Fullscreen';
|
||
}
|
||
}).catch(err => {
|
||
console.error('Error entering fullscreen:', err);
|
||
showStatus('Unable to enter fullscreen', 'error');
|
||
});
|
||
} else {
|
||
document.exitFullscreen().then(() => {
|
||
app.classList.remove('fullscreen');
|
||
|
||
// Update desktop button
|
||
if (btn) {
|
||
btn.innerHTML = '<span class="btn-icon">⛶</span><span class="btn-text">Fullscreen</span>';
|
||
}
|
||
|
||
// Update mobile button
|
||
if (mobileBtn) {
|
||
mobileBtn.innerHTML = '⛶';
|
||
mobileBtn.title = 'Fullscreen';
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
export async function confirmAddress(mode) {
|
||
let latInput, lngInput, addressInput, saveButton;
|
||
|
||
if (mode === 'add') {
|
||
latInput = document.getElementById('location-lat');
|
||
lngInput = document.getElementById('location-lng');
|
||
addressInput = document.getElementById('location-address');
|
||
saveButton = document.getElementById('save-location-btn');
|
||
} else if (mode === 'edit') {
|
||
latInput = document.getElementById('edit-location-lat');
|
||
lngInput = document.getElementById('edit-location-lng');
|
||
addressInput = document.getElementById('edit-location-address');
|
||
saveButton = document.getElementById('save-edit-location-btn'); // We'll need to add this ID to edit form
|
||
} else {
|
||
console.error('Invalid confirm mode:', mode);
|
||
return;
|
||
}
|
||
|
||
if (!latInput || !lngInput || !addressInput) {
|
||
showStatus('Form elements not found', 'error');
|
||
return;
|
||
}
|
||
|
||
const lat = parseFloat(latInput.value);
|
||
const lng = parseFloat(lngInput.value);
|
||
|
||
if (isNaN(lat) || isNaN(lng)) {
|
||
showStatus('Please enter valid coordinates first', 'warning');
|
||
return;
|
||
}
|
||
|
||
// Get the confirm button
|
||
const button = mode === 'add' ?
|
||
document.getElementById('confirm-address-add-btn') :
|
||
document.getElementById('confirm-address-edit-btn');
|
||
|
||
const originalText = button ? button.textContent : '';
|
||
|
||
// Check if already confirmed
|
||
const currentlyConfirmed = mode === 'add' ? isAddressConfirmed : isEditAddressConfirmed;
|
||
|
||
// If already confirmed, just enable save
|
||
if (currentlyConfirmed) {
|
||
if (mode === 'add') {
|
||
isAddressConfirmed = false;
|
||
} else {
|
||
isEditAddressConfirmed = false;
|
||
}
|
||
|
||
// Reset button and disable save
|
||
if (button) {
|
||
button.textContent = '📍 Confirm Address';
|
||
button.classList.remove('btn-success');
|
||
button.classList.add('btn-secondary');
|
||
}
|
||
if (saveButton) {
|
||
saveButton.disabled = true;
|
||
}
|
||
showStatus('Please confirm address again to enable saving', 'info');
|
||
return;
|
||
}
|
||
|
||
if (button) {
|
||
button.disabled = true;
|
||
button.textContent = 'Looking up...';
|
||
}
|
||
|
||
try {
|
||
console.log(`Looking up address for: ${lat}, ${lng}`);
|
||
const response = await fetch(`/api/geocode/reverse?lat=${lat}&lng=${lng}`);
|
||
|
||
if (!response.ok) {
|
||
const errorText = await response.text();
|
||
throw new Error(`Geocoding failed: ${response.status} ${errorText}`);
|
||
}
|
||
|
||
const data = await response.json();
|
||
|
||
if (data.success && data.data) {
|
||
// Use the formatted address or full address
|
||
const address = data.data.formattedAddress || data.data.fullAddress;
|
||
if (address) {
|
||
addressInput.value = address;
|
||
|
||
// Mark as confirmed
|
||
if (mode === 'add') {
|
||
isAddressConfirmed = true;
|
||
} else {
|
||
isEditAddressConfirmed = true;
|
||
}
|
||
|
||
// Update button to show confirmed state
|
||
if (button) {
|
||
button.textContent = '✅ Address Confirmed';
|
||
button.classList.remove('btn-secondary');
|
||
button.classList.add('btn-success');
|
||
}
|
||
|
||
// Enable save button
|
||
if (saveButton) {
|
||
saveButton.disabled = false;
|
||
}
|
||
|
||
showStatus('Address confirmed! You can now save the location.', 'success');
|
||
} else {
|
||
showStatus('No address found for these coordinates', 'warning');
|
||
}
|
||
} else {
|
||
showStatus('Address lookup failed', 'warning');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('Address lookup error:', error);
|
||
showStatus(`Address lookup failed: ${error.message}`, 'error');
|
||
} finally {
|
||
// Restore button state if not confirmed
|
||
const finallyConfirmed = mode === 'add' ? isAddressConfirmed : isEditAddressConfirmed;
|
||
if (button && !finallyConfirmed) {
|
||
button.disabled = false;
|
||
button.textContent = originalText;
|
||
}
|
||
}
|
||
}
|
||
|
||
export function resetAddressConfirmation(mode) {
|
||
if (mode === 'add') {
|
||
isAddressConfirmed = false;
|
||
const button = document.getElementById('confirm-address-add-btn');
|
||
const saveButton = document.getElementById('save-location-btn');
|
||
|
||
if (button) {
|
||
button.textContent = '📍 Confirm Address';
|
||
button.classList.remove('btn-success');
|
||
button.classList.add('btn-secondary');
|
||
button.disabled = false;
|
||
}
|
||
if (saveButton) {
|
||
saveButton.disabled = true;
|
||
}
|
||
} else if (mode === 'edit') {
|
||
isEditAddressConfirmed = false;
|
||
const button = document.getElementById('confirm-address-edit-btn');
|
||
const saveButton = document.getElementById('save-edit-location-btn');
|
||
|
||
if (button) {
|
||
button.textContent = '📍 Confirm Address';
|
||
button.classList.remove('btn-success');
|
||
button.classList.add('btn-secondary');
|
||
button.disabled = false;
|
||
}
|
||
if (saveButton) {
|
||
saveButton.disabled = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
export function setupGeoLocationSync() {
|
||
// For add form
|
||
const addLatInput = document.getElementById('location-lat');
|
||
const addLngInput = document.getElementById('location-lng');
|
||
const addGeoInput = document.getElementById('geo-location');
|
||
|
||
if (addLatInput && addLngInput && addGeoInput) {
|
||
[addLatInput, addLngInput].forEach(input => {
|
||
input.addEventListener('input', () => {
|
||
const lat = addLatInput.value;
|
||
const lng = addLngInput.value;
|
||
if (lat && lng) {
|
||
addGeoInput.value = `${lat};${lng}`;
|
||
}
|
||
// Reset address confirmation when coordinates change
|
||
resetAddressConfirmation('add');
|
||
});
|
||
});
|
||
|
||
addGeoInput.addEventListener('input', () => {
|
||
const coords = parseGeoLocation(addGeoInput.value);
|
||
if (coords) {
|
||
addLatInput.value = coords.lat;
|
||
addLngInput.value = coords.lng;
|
||
}
|
||
// Reset address confirmation when geo-location changes
|
||
resetAddressConfirmation('add');
|
||
});
|
||
}
|
||
|
||
// For edit form
|
||
const editLatInput = document.getElementById('edit-location-lat');
|
||
const editLngInput = document.getElementById('edit-location-lng');
|
||
const editGeoInput = document.getElementById('edit-geo-location');
|
||
|
||
if (editLatInput && editLngInput && editGeoInput) {
|
||
[editLatInput, editLngInput].forEach(input => {
|
||
input.addEventListener('input', () => {
|
||
const lat = editLatInput.value;
|
||
const lng = editLngInput.value;
|
||
if (lat && lng) {
|
||
editGeoInput.value = `${lat};${lng}`;
|
||
}
|
||
// Reset address confirmation when coordinates change
|
||
resetAddressConfirmation('edit');
|
||
});
|
||
});
|
||
|
||
editGeoInput.addEventListener('input', () => {
|
||
const coords = parseGeoLocation(editGeoInput.value);
|
||
if (coords) {
|
||
editLatInput.value = coords.lat;
|
||
editLngInput.value = coords.lng;
|
||
}
|
||
// Reset address confirmation when geo-location changes
|
||
resetAddressConfirmation('edit');
|
||
});
|
||
}
|
||
}
|
||
|
||
export function setupEventListeners() {
|
||
// Desktop controls
|
||
document.getElementById('refresh-btn')?.addEventListener('click', () => {
|
||
loadLocations();
|
||
showStatus('Locations refreshed', 'success');
|
||
});
|
||
|
||
document.getElementById('geolocate-btn')?.addEventListener('click', getUserLocation);
|
||
document.getElementById('toggle-start-location-btn')?.addEventListener('click', toggleStartLocationVisibility);
|
||
document.getElementById('add-location-btn')?.addEventListener('click', toggleAddLocationMode);
|
||
document.getElementById('fullscreen-btn')?.addEventListener('click', toggleFullscreen);
|
||
|
||
// Add logout button event listeners
|
||
document.getElementById('logout-btn')?.addEventListener('click', handleLogout);
|
||
document.getElementById('mobile-logout-btn')?.addEventListener('click', handleLogout);
|
||
|
||
// Mobile controls
|
||
document.getElementById('mobile-refresh-btn')?.addEventListener('click', () => {
|
||
loadLocations();
|
||
showStatus('Locations refreshed', 'success');
|
||
});
|
||
|
||
document.getElementById('mobile-geolocate-btn')?.addEventListener('click', getUserLocation);
|
||
document.getElementById('mobile-toggle-start-location-btn')?.addEventListener('click', toggleStartLocationVisibility);
|
||
document.getElementById('mobile-add-location-btn')?.addEventListener('click', toggleAddLocationMode);
|
||
document.getElementById('mobile-fullscreen-btn')?.addEventListener('click', toggleFullscreen);
|
||
|
||
// Mobile dropdown toggle
|
||
document.getElementById('mobile-dropdown-toggle')?.addEventListener('click', (e) => {
|
||
e.stopPropagation();
|
||
const dropdown = document.getElementById('mobile-dropdown');
|
||
dropdown.classList.toggle('active');
|
||
});
|
||
|
||
// Close mobile dropdown when clicking outside
|
||
document.addEventListener('click', (e) => {
|
||
const dropdown = document.getElementById('mobile-dropdown');
|
||
if (!dropdown.contains(e.target)) {
|
||
dropdown.classList.remove('active');
|
||
}
|
||
});
|
||
|
||
// Modal controls
|
||
document.getElementById('close-modal-btn')?.addEventListener('click', closeAddModal);
|
||
document.getElementById('cancel-modal-btn')?.addEventListener('click', closeAddModal);
|
||
|
||
// Edit footer controls
|
||
document.getElementById('close-edit-footer-btn')?.addEventListener('click', closeEditForm);
|
||
|
||
// Forms
|
||
document.getElementById('location-form')?.addEventListener('submit', handleAddLocation);
|
||
document.getElementById('edit-location-form')?.addEventListener('submit', handleEditLocation);
|
||
|
||
// Delete button
|
||
document.getElementById('delete-location-btn')?.addEventListener('click', handleDeleteLocation);
|
||
|
||
// Address confirm buttons
|
||
document.getElementById('confirm-address-add-btn')?.addEventListener('click', () => {
|
||
confirmAddress('add');
|
||
});
|
||
|
||
document.getElementById('confirm-address-edit-btn')?.addEventListener('click', () => {
|
||
confirmAddress('edit');
|
||
});
|
||
|
||
// Auto address lookup event listener
|
||
document.addEventListener('autoAddressLookup', (e) => {
|
||
const { mode } = e.detail;
|
||
if (mode === 'add') {
|
||
// Add a small delay to ensure the form is fully rendered
|
||
setTimeout(() => {
|
||
confirmAddress('add');
|
||
}, 200);
|
||
}
|
||
});
|
||
|
||
// Geo-location field sync
|
||
setupGeoLocationSync();
|
||
|
||
// Add event delegation for popup edit buttons
|
||
document.addEventListener('click', (e) => {
|
||
if (e.target.classList.contains('edit-location-popup-btn')) {
|
||
e.preventDefault();
|
||
try {
|
||
const locationData = JSON.parse(e.target.getAttribute('data-location'));
|
||
openEditForm(locationData);
|
||
} catch (error) {
|
||
console.error('Error parsing location data:', error);
|
||
showStatus('Error opening edit form', 'error');
|
||
}
|
||
}
|
||
|
||
// Add handler for move button
|
||
if (e.target.classList.contains('move-location-popup-btn')) {
|
||
e.preventDefault();
|
||
try {
|
||
const locationData = JSON.parse(e.target.getAttribute('data-location'));
|
||
// Find the marker that corresponds to this location
|
||
import('./location-manager.js').then(({ markers, startMovingMarker }) => {
|
||
const marker = markers.find(m => {
|
||
const markerData = m._locationData;
|
||
const locationId = locationData.Id || locationData.id || locationData.ID || locationData._id;
|
||
const markerId = markerData?.Id || markerData?.id || markerData?.ID || markerData?._id;
|
||
return markerId === locationId;
|
||
});
|
||
|
||
if (marker) {
|
||
startMovingMarker(locationData, marker);
|
||
} else {
|
||
console.error('Could not find marker for location:', locationData);
|
||
showStatus('Could not find marker for this location', 'error');
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('Error starting move:', error);
|
||
showStatus('Failed to start move mode', 'error');
|
||
}
|
||
}
|
||
});
|
||
|
||
// Improve popup button handling for mobile
|
||
map.on('popupopen', function(e) {
|
||
const popup = e.popup;
|
||
const content = popup.getContent();
|
||
|
||
// Create a temporary container to parse the HTML
|
||
const tempDiv = document.createElement('div');
|
||
tempDiv.innerHTML = content;
|
||
|
||
// Find buttons in the popup
|
||
const editBtn = tempDiv.querySelector('.edit-location-popup-btn');
|
||
const moveBtn = tempDiv.querySelector('.move-location-popup-btn');
|
||
|
||
if (editBtn || moveBtn) {
|
||
// Re-render popup with proper event handlers
|
||
setTimeout(() => {
|
||
const popupNode = popup._contentNode || popup._container;
|
||
if (!popupNode) return;
|
||
|
||
// Edit button
|
||
const editButton = popupNode.querySelector('.edit-location-popup-btn');
|
||
if (editButton) {
|
||
editButton.addEventListener('click', function(event) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
try {
|
||
const locationData = JSON.parse(this.getAttribute('data-location'));
|
||
openEditForm(locationData);
|
||
map.closePopup();
|
||
} catch (error) {
|
||
console.error('Error parsing location data:', error);
|
||
showStatus('Error opening edit form', 'error');
|
||
}
|
||
});
|
||
}
|
||
|
||
// Move button
|
||
const moveButton = popupNode.querySelector('.move-location-popup-btn');
|
||
if (moveButton) {
|
||
moveButton.addEventListener('click', async function(event) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
try {
|
||
const locationData = JSON.parse(this.getAttribute('data-location'));
|
||
const { startMovingMarker } = await import('./location-manager.js');
|
||
startMovingMarker(locationData, e.popup._source);
|
||
} catch (error) {
|
||
console.error('Error starting move:', error);
|
||
showStatus('Failed to start move mode', 'error');
|
||
}
|
||
});
|
||
}
|
||
}, 0);
|
||
}
|
||
});
|
||
|
||
// Add this after the existing event listeners
|
||
document.addEventListener('updateMoveButtons', (e) => {
|
||
isMoveMode = e.detail.isMoving;
|
||
|
||
if (isMoveMode) {
|
||
// Hide add location buttons during move mode
|
||
const addBtn = document.getElementById('add-location-btn');
|
||
const mobileAddBtn = document.getElementById('mobile-add-location-btn');
|
||
|
||
if (addBtn) addBtn.style.display = 'none';
|
||
if (mobileAddBtn) mobileAddBtn.style.display = 'none';
|
||
|
||
// Add cancel move button
|
||
addCancelMoveButton();
|
||
} else {
|
||
// Restore add location buttons
|
||
const addBtn = document.getElementById('add-location-btn');
|
||
const mobileAddBtn = document.getElementById('mobile-add-location-btn');
|
||
|
||
if (addBtn) addBtn.style.display = '';
|
||
if (mobileAddBtn) mobileAddBtn.style.display = '';
|
||
|
||
// Remove cancel move button
|
||
removeCancelMoveButton();
|
||
}
|
||
});
|
||
}
|
||
|
||
// Add this to the setupMapEventListeners function
|
||
export function setupMapEventListeners(mapInstance) {
|
||
// ...existing code...
|
||
|
||
// Handle move location button clicks in popups
|
||
mapInstance.on('popupopen', function(e) {
|
||
// ...existing code for edit button...
|
||
|
||
// Handle move button
|
||
const moveBtn = e.popup._contentNode?.querySelector('.move-location-popup-btn');
|
||
if (moveBtn) {
|
||
moveBtn.addEventListener('click', async function() {
|
||
try {
|
||
const locationData = JSON.parse(this.getAttribute('data-location'));
|
||
const marker = e.popup._source;
|
||
|
||
const { startMovingMarker } = await import('./location-manager.js');
|
||
startMovingMarker(locationData, marker);
|
||
} catch (error) {
|
||
console.error('Error starting move:', error);
|
||
showStatus('Failed to start move mode', 'error');
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
function addCancelMoveButton() {
|
||
// Desktop button
|
||
const mapControls = document.querySelector('.map-controls');
|
||
if (mapControls && !document.getElementById('cancel-move-btn')) {
|
||
const cancelBtn = document.createElement('button');
|
||
cancelBtn.id = 'cancel-move-btn';
|
||
cancelBtn.className = 'btn btn-danger';
|
||
cancelBtn.innerHTML = '<span class="btn-icon">✕</span><span class="btn-text">Cancel Move</span>';
|
||
cancelBtn.addEventListener('click', async () => {
|
||
const { cancelMove } = await import('./location-manager.js');
|
||
cancelMove();
|
||
});
|
||
mapControls.insertBefore(cancelBtn, mapControls.firstChild);
|
||
}
|
||
|
||
// Mobile button
|
||
const mobileSidebar = document.getElementById('mobile-sidebar');
|
||
if (mobileSidebar && !document.getElementById('mobile-cancel-move-btn')) {
|
||
const mobileCancelBtn = document.createElement('button');
|
||
mobileCancelBtn.id = 'mobile-cancel-move-btn';
|
||
mobileCancelBtn.className = 'btn btn-danger';
|
||
mobileCancelBtn.title = 'Cancel Move';
|
||
mobileCancelBtn.innerHTML = '✕';
|
||
mobileCancelBtn.addEventListener('click', async () => {
|
||
const { cancelMove } = await import('./location-manager.js');
|
||
cancelMove();
|
||
});
|
||
mobileSidebar.insertBefore(mobileCancelBtn, mobileSidebar.firstChild);
|
||
}
|
||
}
|
||
|
||
function removeCancelMoveButton() {
|
||
document.getElementById('cancel-move-btn')?.remove();
|
||
document.getElementById('mobile-cancel-move-btn')?.remove();
|
||
} |