Update tracking page to detect Location Services

This commit is contained in:
Nguyen Ngo
2025-08-15 09:56:44 -04:00
parent 455105f832
commit 491a6f537c
2 changed files with 271 additions and 0 deletions
+150
View File
@@ -59,6 +59,7 @@ document.addEventListener("DOMContentLoaded", function () {
// CRITICAL: Initialize systems in correct order
initializeLanguage();
initializeLocationServicesCheck();
initializeStaffIdPersistence();
initializeForm();
initializeLocation();
@@ -733,3 +734,152 @@ function startClock() {
updateClock();
setInterval(updateClock, 1000);
}
function checkLocationServicesStatus() {
console.log("📱 Checking location services status...");
// Check if geolocation is supported
if (!navigator.geolocation) {
console.log("❌ Geolocation not supported by this browser");
showLocationServicesWarning("not_supported");
return;
}
// Test location access with a quick check
const timeoutId = setTimeout(() => {
console.log("⏰ Location permission check timed out");
showLocationServicesWarning("timeout");
}, 3000); // 3 second timeout
navigator.geolocation.getCurrentPosition(
(position) => {
// Success - location services are working
clearTimeout(timeoutId);
console.log("✅ Location services are available and enabled");
hideLocationServicesWarning();
},
(error) => {
// Error - location services may be disabled
clearTimeout(timeoutId);
console.log("❌ Location services error:", error.message);
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;
}
},
{
enableHighAccuracy: false,
timeout: 2500,
maximumAge: 60000
}
);
}
/**
* Show location services warning banner
*/
function showLocationServicesWarning(errorType) {
// Remove existing warning if present
hideLocationServicesWarning();
const warningMessages = {
en: {
not_supported: "Location services are not supported by your browser.<br>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.<br>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.<br>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.<br>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.<br>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."
}
};
const currentLang = currentLanguage || 'en';
const message = warningMessages[currentLang][errorType] || warningMessages['en'][errorType];
// Create warning banner
const warningBanner = document.createElement('div');
warningBanner.id = 'locationServicesWarning';
warningBanner.className = 'location-warning-banner';
warningBanner.innerHTML = `
<div class="warning-content">
<i class="fas fa-exclamation-triangle warning-icon"></i>
<div class="warning-text">
<span class="warning-message">${message}</span>
<div class="warning-actions">
<button type="button" class="warning-retry-btn" onclick="checkLocationServicesStatus()">
<i class="fas fa-redo"></i>
<span class="english-text">Retry</span>
<span class="language-separator">/</span>
<span class="spanish-text">Reintentar</span>
</button>
<button type="button" class="warning-dismiss-btn" onclick="hideLocationServicesWarning()">
<i class="fas fa-times"></i>
<span class="english-text">Dismiss</span>
<span class="language-separator">/</span>
<span class="spanish-text">Descartar</span>
</button>
</div>
</div>
</div>
`;
// Insert warning at the top of the page
const container = document.querySelector('.destination-container');
if (container) {
container.insertBefore(warningBanner, container.firstChild);
}
// Log warning event
console.log(`⚠️ Location services warning displayed: ${errorType}`);
}
/**
* Hide location services warning banner
*/
function hideLocationServicesWarning() {
const existingWarning = document.getElementById('locationServicesWarning');
if (existingWarning) {
existingWarning.remove();
console.log("✅ Location services warning hidden");
}
}
/**
* Modified DOMContentLoaded event handler
* Add this to your existing initialization
*/
function initializeLocationServicesCheck() {
// Check location services status when page loads
setTimeout(() => {
checkLocationServicesStatus();
}, 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);
};
}
+121
View File
@@ -601,6 +601,127 @@
gap: 0.75rem;
}
}
.location-warning-banner {
background: linear-gradient(135deg, #fef3c7, #fde68a);
border: 2px solid #f59e0b;
border-radius: var(--border-radius);
margin-bottom: 1rem;
padding: 1rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
animation: slideInWarning 0.5s ease-out;
}
.warning-content {
display: flex;
align-items: flex-start;
gap: 0.75rem;
}
.warning-icon {
color: #d97706;
font-size: 1.25rem;
margin-top: 0.125rem;
flex-shrink: 0;
}
.warning-text {
flex: 1;
}
.warning-message {
display: block;
color: #92400e;
font-weight: 500;
font-size: 0.95rem;
line-height: 1.5;
margin-bottom: 0.75rem;
}
.warning-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.warning-retry-btn,
.warning-dismiss-btn {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.5rem 0.75rem;
border: none;
border-radius: calc(var(--border-radius) * 0.75);
font-size: 0.85rem;
font-weight: 500;
cursor: pointer;
transition: var(--transition);
text-decoration: none;
}
.warning-retry-btn {
background: #f59e0b;
color: white;
}
.warning-retry-btn:hover {
background: #d97706;
transform: translateY(-1px);
}
.warning-dismiss-btn {
background: rgba(156, 163, 175, 0.2);
color: #6b7280;
border: 1px solid rgba(156, 163, 175, 0.3);
}
.warning-dismiss-btn:hover {
background: rgba(156, 163, 175, 0.3);
color: #4b5563;
}
/* Warning animation */
@keyframes slideInWarning {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Language styling for warning buttons */
.warning-retry-btn .language-separator,
.warning-dismiss-btn .language-separator {
opacity: 0.7;
margin: 0 0.25rem;
}
.warning-retry-btn .spanish-text,
.warning-dismiss-btn .spanish-text {
font-style: italic;
opacity: 0.9;
}
/* Responsive adjustments for warning */
@media (max-width: 640px) {
.warning-content {
flex-direction: column;
gap: 0.5rem;
}
.warning-actions {
justify-content: center;
}
.warning-retry-btn,
.warning-dismiss-btn {
flex: 1;
justify-content: center;
min-width: 120px;
}
}
</style>
</head>
<body class="{% if qr_code.location_event == 'Check Out' %}check-out{% else %}check-in{% endif %}">