import { showFlashMessage } from "./helpers"; // Add custom CSS for popup styling const addPopupStyles = () => { if (!document.querySelector('#area-popup-styles')) { const style = document.createElement('style'); style.id = 'area-popup-styles'; style.textContent = ` .area-form-popup, .area-info-popup { background: transparent !important; } .area-form-popup .leaflet-popup-content-wrapper, .area-info-popup .leaflet-popup-content-wrapper { background: transparent !important; padding: 0 !important; margin: 0 !important; border-radius: 0 !important; box-shadow: none !important; border: none !important; } .area-form-popup .leaflet-popup-content, .area-info-popup .leaflet-popup-content { margin: 0 !important; padding: 0 1rem 0 0 !important; background: transparent !important; border-radius: 1rem !important; overflow: hidden !important; width: 100% !important; max-width: none !important; } .area-form-popup .leaflet-popup-tip, .area-info-popup .leaflet-popup-tip { background: transparent !important; border: none !important; box-shadow: none !important; } .area-form-popup .leaflet-popup, .area-info-popup .leaflet-popup { margin-bottom: 0 !important; } .area-form-popup .leaflet-popup-close-button, .area-info-popup .leaflet-popup-close-button { right: 1.25rem !important; top: 1.25rem !important; width: 1.5rem !important; height: 1.5rem !important; padding: 0 !important; color: oklch(var(--bc) / 0.6) !important; background: oklch(var(--b2)) !important; border-radius: 0.5rem !important; border: 1px solid oklch(var(--bc) / 0.2) !important; font-size: 1rem !important; font-weight: bold !important; line-height: 1 !important; display: flex !important; align-items: center !important; justify-content: center !important; transition: all 0.2s ease !important; } .area-form-popup .leaflet-popup-close-button:hover, .area-info-popup .leaflet-popup-close-button:hover { background: oklch(var(--b3)) !important; color: oklch(var(--bc)) !important; border-color: oklch(var(--bc) / 0.3) !important; } `; document.head.appendChild(style); } }; export function handleAreaCreated(areasLayer, layer, apiKey) { // Add popup styles addPopupStyles(); const radius = layer.getRadius(); const center = layer.getLatLng(); // Configure the layer with the same settings as existing areas layer.setStyle({ color: 'red', fillColor: '#f03', fillOpacity: 0.5, weight: 2, interactive: true, bubblingMouseEvents: false }); // Set the pane to match existing areas layer.options.pane = 'areasPane'; const formHtml = `

New Area

`; layer.bindPopup(formHtml, { maxWidth: 400, minWidth: 384, maxHeight: 600, closeButton: true, closeOnClick: false, className: 'area-form-popup', autoPan: true, keepInView: true }).openPopup(); areasLayer.addLayer(layer); // Bind the event handler immediately after opening the popup setTimeout(() => { const form = document.getElementById('circle-form'); const saveButton = document.getElementById('save-area-btn'); const nameInput = document.getElementById('circle-name'); if (!form || !saveButton || !nameInput) { console.error('Required elements not found'); return; } // Focus the name input nameInput.focus(); // Remove any existing click handlers const newSaveButton = saveButton.cloneNode(true); saveButton.parentNode.replaceChild(newSaveButton, saveButton); // Add click handler newSaveButton.addEventListener('click', (e) => { console.log('Save button clicked'); e.preventDefault(); e.stopPropagation(); if (!nameInput.value.trim()) { nameInput.classList.add('input-error', 'border-error'); return; } const formData = new FormData(form); saveArea(formData, areasLayer, layer, apiKey); }); }, 100); // Small delay to ensure DOM is ready } export function saveArea(formData, areasLayer, layer, apiKey) { const data = {}; formData.forEach((value, key) => { const keys = key.split('[').map(k => k.replace(']', '')); if (keys.length > 1) { if (!data[keys[0]]) data[keys[0]] = {}; data[keys[0]][keys[1]] = value; } else { data[keys[0]] = value; } }); fetch(`/api/v1/areas?api_key=${apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json'}, body: JSON.stringify(data) }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { layer.closePopup(); layer.bindPopup(`

${data.name}

Radius: ${Math.round(data.radius)} meters

`, { maxWidth: 340, minWidth: 320, className: 'area-info-popup', closeButton: true, closeOnClick: false }).openPopup(); // Add event listener for the delete button layer.on('popupopen', () => { const deleteButton = document.querySelector('.delete-area'); if (deleteButton) { deleteButton.addEventListener('click', (e) => { e.preventDefault(); deleteArea(data.id, areasLayer, layer, apiKey); }); } }); }) .catch(error => { console.error('There was a problem with the save request:', error); }); } export function deleteArea(id, areasLayer, layer, apiKey) { fetch(`/api/v1/areas/${id}?api_key=${apiKey}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { areasLayer.removeLayer(layer); // Remove the layer from the areas layer group showFlashMessage('notice', `Area was successfully deleted!`); }) .catch(error => { console.error('There was a problem with the delete request:', error); }); } export function fetchAndDrawAreas(areasLayer, apiKey) { // Add popup styles addPopupStyles(); fetch(`/api/v1/areas?api_key=${apiKey}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // Clear existing areas areasLayer.clearLayers(); data.forEach(area => { if (area.latitude && area.longitude && area.radius && area.name && area.id) { // Convert string coordinates to numbers const lat = parseFloat(area.latitude); const lng = parseFloat(area.longitude); const radius = parseFloat(area.radius); // Create circle with custom pane const circle = L.circle([lat, lng], { radius: radius, color: 'red', fillColor: '#f03', fillOpacity: 0.5, weight: 2, interactive: true, bubblingMouseEvents: false, pane: 'areasPane' }); // Bind popup content with proper theme-aware styling const popupContent = `

${area.name}

Radius
${Math.round(radius)} meters
Center
[${lat.toFixed(4)}, ${lng.toFixed(4)}]
Area ${area.id}
`; circle.bindPopup(popupContent, { maxWidth: 400, minWidth: 384, className: 'area-info-popup', closeButton: true, closeOnClick: false }); // Add delete button handler when popup opens circle.on('popupopen', () => { const deleteButton = document.querySelector('.delete-area[data-id="' + area.id + '"]'); if (deleteButton) { deleteButton.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); if (confirm('Are you sure you want to delete this area?')) { deleteArea(area.id, areasLayer, circle, apiKey); } }); } }); // Add to layer group areasLayer.addLayer(circle); // Wait for the circle to be added to the DOM setTimeout(() => { const circlePath = circle.getElement(); if (circlePath) { // Add CSS styles circlePath.style.cursor = 'pointer'; circlePath.style.transition = 'all 0.3s ease'; // Add direct DOM event listeners circlePath.addEventListener('click', (e) => { e.stopPropagation(); circle.openPopup(); }); circlePath.addEventListener('mouseenter', (e) => { e.stopPropagation(); circle.setStyle({ fillOpacity: 0.8, weight: 3 }); }); circlePath.addEventListener('mouseleave', (e) => { e.stopPropagation(); circle.setStyle({ fillOpacity: 0.5, weight: 2 }); }); } }, 100); } }); }) .catch(error => { console.error('There was a problem with the fetch request:', error); }); }