From 65c786d3db1a52173385597c67177a75473fd3c9 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 16 Jul 2025 18:25:50 -0600 Subject: [PATCH] new system for address confrimation --- map/app/public/css/style.css | 22 +++++ map/app/public/index.html | 10 +- map/app/public/js/location-manager.js | 23 +++++ map/app/public/js/ui-controls.js | 128 +++++++++++++++++++++++--- map/files-explainer.md | 6 +- 5 files changed, 166 insertions(+), 23 deletions(-) diff --git a/map/app/public/css/style.css b/map/app/public/css/style.css index 140053b..0ff22ea 100644 --- a/map/app/public/css/style.css +++ b/map/app/public/css/style.css @@ -177,6 +177,28 @@ body { background-color: #c0392b; } +/* Disabled button styles */ +.btn:disabled { + opacity: 0.6; + cursor: not-allowed; + background-color: #6c757d; +} + +.btn:disabled:hover { + background-color: #6c757d; + transform: none; +} + +.btn-primary:disabled { + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-primary:disabled:hover { + background-color: #6c757d; + border-color: #6c757d; +} + /* Crosshair for location selection */ .crosshair { position: absolute; diff --git a/map/app/public/index.html b/map/app/public/index.html index 4d08825..4785ada 100644 --- a/map/app/public/index.html +++ b/map/app/public/index.html @@ -171,8 +171,8 @@
-
@@ -282,8 +282,8 @@
-
@@ -336,7 +336,7 @@ - diff --git a/map/app/public/js/location-manager.js b/map/app/public/js/location-manager.js index c091257..91218c9 100644 --- a/map/app/public/js/location-manager.js +++ b/map/app/public/js/location-manager.js @@ -2,6 +2,7 @@ import { map } from './map-manager.js'; import { showStatus, updateLocationCount, escapeHtml } from './utils.js'; import { currentUser } from './auth.js'; +import { resetAddressConfirmation } from './ui-controls.js'; export let markers = []; export let currentEditingLocation = null; @@ -144,6 +145,14 @@ function createPopupContent(location) { export async function handleAddLocation(e) { e.preventDefault(); + // Check if address is confirmed + const { getAddressConfirmationState } = await import('./ui-controls.js'); + const { isAddressConfirmed } = getAddressConfirmationState(); + if (!isAddressConfirmed) { + showStatus('Please confirm the address before saving the location', 'warning'); + return; + } + const formData = new FormData(e.target); const data = {}; @@ -202,6 +211,9 @@ export function openEditForm(location) { return; } + // Reset address confirmation state + resetAddressConfirmation('edit'); + // Store the ID in a data attribute for later use document.getElementById('edit-location-id').value = locationId; document.getElementById('edit-location-id').setAttribute('data-location-id', locationId); @@ -235,6 +247,14 @@ export async function handleEditLocation(e) { if (!currentEditingLocation) return; + // Check if address is confirmed + const { getAddressConfirmationState } = await import('./ui-controls.js'); + const { isEditAddressConfirmed } = getAddressConfirmationState(); + if (!isEditAddressConfirmed) { + showStatus('Please confirm the address before saving changes', 'warning'); + return; + } + // Get the stored location ID const locationIdElement = document.getElementById('edit-location-id'); const locationId = locationIdElement.getAttribute('data-location-id') || locationIdElement.value; @@ -345,6 +365,9 @@ export function openAddModal(lat, lng) { const lngInput = document.getElementById('location-lng'); const geoInput = document.getElementById('geo-location'); + // Reset address confirmation state + resetAddressConfirmation('add'); + // Set coordinates latInput.value = lat.toFixed(8); lngInput.value = lng.toFixed(8); diff --git a/map/app/public/js/ui-controls.js b/map/app/public/js/ui-controls.js index 28113b8..3faf1aa 100644 --- a/map/app/public/js/ui-controls.js +++ b/map/app/public/js/ui-controls.js @@ -5,6 +5,16 @@ import { loadLocations, handleAddLocation, handleEditLocation, handleDeleteLocat export let userLocationMarker = null; export let isAddingLocation = false; +export let isAddressConfirmed = false; +export let isEditAddressConfirmed = false; + +// Export function to get current confirmation states +export function getAddressConfirmationState() { + return { + isAddressConfirmed, + isEditAddressConfirmed + }; +} // Add logout function async function logout() { @@ -192,19 +202,21 @@ export function toggleFullscreen() { } } -export async function lookupAddress(mode) { - let latInput, lngInput, addressInput; +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 lookup mode:', mode); + console.error('Invalid confirm mode:', mode); return; } @@ -221,12 +233,37 @@ export async function lookupAddress(mode) { return; } - // Show loading state + // Get the confirm button const button = mode === 'add' ? - document.getElementById('lookup-address-add-btn') : - document.getElementById('lookup-address-edit-btn'); + 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...'; @@ -248,7 +285,27 @@ export async function lookupAddress(mode) { const address = data.data.formattedAddress || data.data.fullAddress; if (address) { addressInput.value = address; - showStatus('Address found!', 'success'); + + // 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'); } @@ -260,14 +317,47 @@ export async function lookupAddress(mode) { console.error('Address lookup error:', error); showStatus(`Address lookup failed: ${error.message}`, 'error'); } finally { - // Restore button state - if (button) { + // 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'); @@ -282,6 +372,8 @@ export function setupGeoLocationSync() { if (lat && lng) { addGeoInput.value = `${lat};${lng}`; } + // Reset address confirmation when coordinates change + resetAddressConfirmation('add'); }); }); @@ -291,6 +383,8 @@ export function setupGeoLocationSync() { addLatInput.value = coords.lat; addLngInput.value = coords.lng; } + // Reset address confirmation when geo-location changes + resetAddressConfirmation('add'); }); } @@ -307,6 +401,8 @@ export function setupGeoLocationSync() { if (lat && lng) { editGeoInput.value = `${lat};${lng}`; } + // Reset address confirmation when coordinates change + resetAddressConfirmation('edit'); }); }); @@ -316,6 +412,8 @@ export function setupGeoLocationSync() { editLatInput.value = coords.lat; editLngInput.value = coords.lng; } + // Reset address confirmation when geo-location changes + resetAddressConfirmation('edit'); }); } } @@ -376,13 +474,13 @@ export function setupEventListeners() { // Delete button document.getElementById('delete-location-btn')?.addEventListener('click', handleDeleteLocation); - // Address lookup buttons - document.getElementById('lookup-address-add-btn')?.addEventListener('click', () => { - lookupAddress('add'); + // Address confirm buttons + document.getElementById('confirm-address-add-btn')?.addEventListener('click', () => { + confirmAddress('add'); }); - document.getElementById('lookup-address-edit-btn')?.addEventListener('click', () => { - lookupAddress('edit'); + document.getElementById('confirm-address-edit-btn')?.addEventListener('click', () => { + confirmAddress('edit'); }); // Auto address lookup event listener @@ -391,7 +489,7 @@ export function setupEventListeners() { if (mode === 'add') { // Add a small delay to ensure the form is fully rendered setTimeout(() => { - lookupAddress('add'); + confirmAddress('add'); }, 200); } }); diff --git a/map/files-explainer.md b/map/files-explainer.md index 759fd1d..efefe38 100644 --- a/map/files-explainer.md +++ b/map/files-explainer.md @@ -112,7 +112,7 @@ Favicon for the web application. # app/public/index.html -Main map viewer HTML page for the canvassing application. +Main map viewer HTML page for the canvassing application. Features "Confirm Address" functionality that requires users to confirm the geocoded address before saving location data. # app/public/login.html @@ -136,7 +136,7 @@ Global configuration constants for the frontend app. # app/public/js/location-manager.js -JavaScript for loading, displaying, and managing map locations on the frontend. +JavaScript for loading, displaying, and managing map locations on the frontend. Includes address confirmation validation that prevents saving locations until the geocoded address is confirmed by the user. # app/public/js/main.js @@ -156,7 +156,7 @@ JavaScript for volunteer shift signup, management, and UI logic with both grid a # app/public/js/ui-controls.js -JavaScript for UI controls, event handlers, and user interaction logic. +JavaScript for UI controls, event handlers, and user interaction logic. Includes address confirmation functionality that manages state for ensuring users confirm geocoded addresses before saving locations. # app/public/js/utils.js