From 04d51144cb1f19e396d27beeeba4d047c183fc7b Mon Sep 17 00:00:00 2001 From: Nguyen Ngo Date: Thu, 11 Sep 2025 16:00:10 -0400 Subject: [PATCH] Update check-in Location Services requirement --- static/css/qr_destination.css | 104 +++++++++++++++ static/js/qr_destination.js | 234 +++++++++++++++++++++++----------- 2 files changed, 267 insertions(+), 71 deletions(-) diff --git a/static/css/qr_destination.css b/static/css/qr_destination.css index 90d6d68..45add1b 100644 --- a/static/css/qr_destination.css +++ b/static/css/qr_destination.css @@ -843,4 +843,108 @@ body { --gray-700: #334155 !important; --gray-800: #1e293b !important; --gray-900: #0f172a !important; +} + +.location-warning-banner { + background: linear-gradient(135deg, #ff6b6b, #ee5a24); + color: white; + padding: 15px; + margin-bottom: 20px; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(238, 90, 36, 0.3); + animation: slideDown 0.3s ease-out; +} + +.warning-content { + display: flex; + align-items: flex-start; + gap: 12px; +} + +.warning-icon { + font-size: 24px; + color: #fff; + margin-top: 2px; +} + +.warning-text { + flex: 1; +} + +.warning-message { + display: block; + font-size: 14px; + line-height: 1.4; + margin-bottom: 12px; +} + +.warning-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + +.warning-retry-btn, +.warning-dismiss-btn { + background: rgba(255, 255, 255, 0.2); + border: 1px solid rgba(255, 255, 255, 0.3); + color: white; + padding: 8px 12px; + border-radius: 5px; + cursor: pointer; + font-size: 12px; + transition: all 0.2s ease; + display: flex; + align-items: center; + gap: 5px; +} + +.warning-retry-btn:hover, +.warning-dismiss-btn:hover { + background: rgba(255, 255, 255, 0.3); + transform: translateY(-1px); +} + +/* Blocked Form Styling */ +.location-blocked { + opacity: 0.6; + pointer-events: none; + position: relative; +} + +.location-blocked::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 107, 107, 0.1); + border-radius: 8px; + z-index: 1; +} + +/* Animation for warning banner */ +@keyframes slideDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Mobile responsive adjustments */ +@media (max-width: 768px) { + .warning-actions { + flex-direction: column; + } + + .warning-retry-btn, + .warning-dismiss-btn { + width: 100%; + justify-content: center; + } } \ No newline at end of file diff --git a/static/js/qr_destination.js b/static/js/qr_destination.js index 0ccc6c1..cadb2ac 100644 --- a/static/js/qr_destination.js +++ b/static/js/qr_destination.js @@ -144,6 +144,24 @@ function handleFormSubmit(event) { return; } + // STEP 1: Check Location Services FIRST + console.log("🔍 Step 1: Validating Location Services..."); + + checkLocationServicesStatus() + .then(() => { + // Location services are working, proceed with check-in + console.log("✅ Location Services validated successfully"); + proceedWithCheckin(); + }) + .catch((error) => { + // Location services are not working, block check-in + console.log("❌ Location Services validation failed:", error); + showLocationServicesBlockedMessage(); + return; + }); +} + +function proceedWithCheckin() { const employeeId = document.getElementById("employee_id")?.value?.trim(); if (!employeeId) { @@ -166,6 +184,21 @@ function handleFormSubmit(event) { submitCheckin(); } +/** + * Show message when check-in is blocked due to location services + */ +function showLocationServicesBlockedMessage() { + const messages = { + en: "Check-in blocked: Location Services must be enabled to continue.", + es: "Registro bloqueado: Los Servicios de Ubicación deben estar habilitados para continuar." + }; + + const currentLang = currentLanguage || "en"; + const message = messages[currentLang]; + + showCustomStatusMessage(message, "error"); +} + // ENHANCED CHECK-IN SUBMISSION WITH MULTIPLE CHECK-IN SUPPORT function submitCheckin() { if (isSubmitting) { @@ -713,45 +746,107 @@ function checkLocationServicesStatus() { // Check if geolocation is supported if (!navigator.geolocation) { showLocationServicesWarning("not_supported"); - return; + blockCheckInProcess(true); + return Promise.reject("Location services not supported"); } - // Test location access with a quick check - const timeoutId = setTimeout(() => { - showLocationServicesWarning("timeout"); - }, 3000); // 3 second timeout + return new Promise((resolve, reject) => { + // Test location access with a quick check + const timeoutId = setTimeout(() => { + showLocationServicesWarning("timeout"); + blockCheckInProcess(true); + reject("Location services timeout"); + }, 5000); // 5 second timeout - navigator.geolocation.getCurrentPosition( - (position) => { - // Success - location services are working - clearTimeout(timeoutId); - hideLocationServicesWarning(); - }, - (error) => { - // Error - location services may be disabled - clearTimeout(timeoutId); + navigator.geolocation.getCurrentPosition( + (position) => { + // Success - location services are working + clearTimeout(timeoutId); + hideLocationServicesWarning(); + blockCheckInProcess(false); + + // Log successful location access + console.log("✅ Location Services: ENABLED and working"); + + resolve(position); + }, + (error) => { + // Error - location services may be disabled + clearTimeout(timeoutId); + blockCheckInProcess(true); - switch (error.code) { - case error.PERMISSION_DENIED: - showLocationServicesWarning("permission_denied"); - break; - case error.POSITION_UNAVAILABLE: - showLocationServicesWarning("position_unavailable"); - break; - case error.TIMEOUT: - showLocationServicesWarning("timeout"); - break; - default: - showLocationServicesWarning("unknown_error"); - break; + switch (error.code) { + case error.PERMISSION_DENIED: + showLocationServicesWarning("permission_denied"); + console.log("❌ Location Services: PERMISSION DENIED"); + break; + case error.POSITION_UNAVAILABLE: + showLocationServicesWarning("position_unavailable"); + console.log("❌ Location Services: POSITION UNAVAILABLE"); + break; + case error.TIMEOUT: + showLocationServicesWarning("timeout"); + console.log("❌ Location Services: TIMEOUT"); + break; + default: + showLocationServicesWarning("unknown_error"); + console.log("❌ Location Services: UNKNOWN ERROR"); + break; + } + + reject(error); + }, + { + enableHighAccuracy: false, + timeout: 4000, + maximumAge: 30000, } - }, - { - enableHighAccuracy: false, - timeout: 2500, - maximumAge: 60000, + ); + }); +} + +function blockCheckInProcess(shouldBlock) { + const submitButton = document.getElementById("submitCheckin"); + const employeeIdInput = document.getElementById("employee_id"); + const form = document.getElementById("checkinForm"); + + if (shouldBlock) { + // Block check-in process + if (submitButton) { + submitButton.disabled = true; + submitButton.style.opacity = "0.5"; + submitButton.style.cursor = "not-allowed"; } - ); + + if (employeeIdInput) { + employeeIdInput.disabled = true; + employeeIdInput.style.opacity = "0.7"; + } + + if (form) { + form.classList.add("location-blocked"); + } + + console.log("🚫 Check-in process BLOCKED - Location Services required"); + } else { + // Unblock check-in process + if (submitButton) { + submitButton.disabled = false; + submitButton.style.opacity = "1"; + submitButton.style.cursor = "pointer"; + } + + if (employeeIdInput) { + employeeIdInput.disabled = false; + employeeIdInput.style.opacity = "1"; + } + + if (form) { + form.classList.remove("location-blocked"); + } + + console.log("✅ Check-in process UNBLOCKED - Location Services working"); + } } /** @@ -762,31 +857,31 @@ function showLocationServicesWarning(errorType) { hideLocationServicesWarning(); const warningMessages = { - en: { - not_supported: - "Location services are not supported by your browser.
Los servicios de ubicación no son compatibles con su navegador.", - permission_denied: - "Location access has been denied. Please enable location services for accurate check-in.
Se ha denegado el acceso a la ubicación. Habilite los servicios de ubicación para un registro preciso.", - position_unavailable: - "Location services appear to be disabled. Please turn on location services for accurate check-in.
Los servicios de ubicación parecen estar deshabilitados. Active los servicios de ubicación para un registro preciso.", - timeout: - "Location services may be disabled. Please check your location settings for accurate check-in.
Los servicios de ubicación pueden estar deshabilitados. Verifique su configuración de ubicación para un registro preciso.", - unknown_error: - "Unable to access location services. Please check your location settings.
No se puede acceder a los servicios de ubicación. Verifique su configuración de ubicación.", - }, - es: { - not_supported: - "Los servicios de ubicación no son compatibles con su navegador.", - permission_denied: - "Se ha denegado el acceso a la ubicación. Habilite los servicios de ubicación para un registro preciso.", - position_unavailable: - "Los servicios de ubicación parecen estar deshabilitados. Active los servicios de ubicación para un registro preciso.", - timeout: - "Los servicios de ubicación pueden estar deshabilitados. Verifique su configuración de ubicación para un registro preciso.", - unknown_error: - "No se puede acceder a los servicios de ubicación. Verifique su configuración de ubicación.", - }, - }; + en: { + not_supported: + "⚠️ Location Services Not Supported
Check-in is currently blocked.
Your browser does not support location services required for check-in.

Los servicios de ubicación no son compatibles. El registro está bloqueado.", + permission_denied: + "⚠️ Location Access Denied
Check-in is currently blocked.
Please enable location access in your browser settings to continue with check-in.

Acceso a ubicación denegado. Habilite el acceso para continuar.", + position_unavailable: + "⚠️ Location Services Disabled
Check-in is currently blocked.
Please turn on Location Services in your device settings and refresh the page.

Servicios de ubicación deshabilitados. Active los servicios y actualice la página.", + timeout: + "⚠️ Location Services Not Responding
Check-in is currently blocked.
Location services may be disabled. Please check your device settings.

Los servicios de ubicación no responden. Verifique la configuración.", + unknown_error: + "⚠️ Location Services Error
Check-in is currently blocked.
Unable to access location services. Please check your settings and try again.

Error de servicios de ubicación. Verifique la configuración.", + }, + es: { + not_supported: + "⚠️ Servicios de Ubicación No Compatibles
El registro está bloqueado.
Su navegador no es compatible con los servicios de ubicación requeridos.", + permission_denied: + "⚠️ Acceso a Ubicación Denegado
El registro está bloqueado.
Habilite el acceso a la ubicación en la configuración de su navegador.", + position_unavailable: + "⚠️ Servicios de Ubicación Deshabilitados
El registro está bloqueado.
Active los Servicios de Ubicación en la configuración y actualice la página.", + timeout: + "⚠️ Servicios de Ubicación No Responden
El registro está bloqueado.
Los servicios pueden estar deshabilitados. Verifique la configuración.", + unknown_error: + "⚠️ Error de Servicios de Ubicación
El registro está bloqueado.
No se puede acceder a los servicios. Verifique la configuración.", + }, +}; const currentLang = currentLanguage || "en"; const message = @@ -841,20 +936,17 @@ function hideLocationServicesWarning() { * Add this to your existing initialization */ function initializeLocationServicesCheck() { - // Check location services status when page loads + // Check location services status when page loads and block if necessary setTimeout(() => { - checkLocationServicesStatus(); + console.log("🔍 Initializing Location Services check..."); + checkLocationServicesStatus() + .then(() => { + console.log("✅ Initial Location Services check passed"); + }) + .catch(() => { + console.log("❌ Initial Location Services check failed - Check-in blocked"); + }); }, 1000); // Small delay to ensure page is fully loaded - // Also check before form submission - const originalHandleFormSubmit = handleFormSubmit; - window.handleFormSubmit = function (event) { - // Quick location check before submission - checkLocationServicesStatus(); - - // Continue with original form submission after brief delay - setTimeout(() => { - originalHandleFormSubmit.call(this, event); - }, 500); - }; + // Remove the override of handleFormSubmit since we've updated it directly }