Updated: get coordinates with 10 decimal

This commit is contained in:
2025-08-07 20:40:13 -04:00
parent d6c08a0f44
commit 75291274c3
4 changed files with 174 additions and 150 deletions
+15 -15
View File
@@ -90,7 +90,7 @@ class QRCode(db.Model):
def coordinates_display(self): def coordinates_display(self):
"""Get formatted coordinates for display""" """Get formatted coordinates for display"""
if self.has_coordinates: if self.has_coordinates:
return f"{self.address_latitude:.8f}, {self.address_longitude:.8f}" return f"{self.address_latitude:.10f}, {self.address_longitude:.10f}"
return "Coordinates not available" return "Coordinates not available"
def update_coordinates(self, latitude, longitude, accuracy='geocoded'): def update_coordinates(self, latitude, longitude, accuracy='geocoded'):
@@ -155,7 +155,7 @@ class AttendanceData(db.Model):
def coordinates_display(self): def coordinates_display(self):
"""Get formatted coordinates for display""" """Get formatted coordinates for display"""
if self.has_location_data: if self.has_location_data:
return f"{self.latitude:.8f}, {self.longitude:.8f}" return f"{self.latitude:.10f}, {self.longitude:.10f}"
return "No GPS data" return "No GPS data"
def to_dict(self): def to_dict(self):
@@ -268,7 +268,7 @@ def get_coordinates_from_address_enhanced(address):
accuracy = 'poor' accuracy = 'poor'
print(f"✅ Enhanced geocoding successful:") print(f"✅ Enhanced geocoding successful:")
print(f" Coordinates: {lat:.8f}, {lng:.8f}") print(f" Coordinates: {lat:.10f}, {lng:.10f}")
print(f" Accuracy: {accuracy}") print(f" Accuracy: {accuracy}")
return lat, lng, accuracy return lat, lng, accuracy
@@ -324,7 +324,7 @@ def geocode_address_enhanced(address):
accuracy = 'low' accuracy = 'low'
print(f"✅ Geocoded address: {address}") print(f"✅ Geocoded address: {address}")
print(f" Coordinates: {lat:.8f}, {lng:.8f}") print(f" Coordinates: {lat:.10f}, {lng:.10f}")
print(f" Accuracy: {accuracy} ({place_type})") print(f" Accuracy: {accuracy} ({place_type})")
return lat, lng, accuracy return lat, lng, accuracy
@@ -376,8 +376,8 @@ def calculate_distance_miles(lat1, lng1, lat2, lng2):
distance = round(distance, 4) distance = round(distance, 4)
print(f"📏 Enhanced distance calculation:") print(f"📏 Enhanced distance calculation:")
print(f" Point 1: {lat1*180/3.14159:.8f}, {lng1*180/3.14159:.8f}") print(f" Point 1: {lat1*180/3.14159:.10f}, {lng1*180/3.14159:.10f}")
print(f" Point 2: {lat2*180/3.14159:.8f}, {lng2*180/3.14159:.8f}") print(f" Point 2: {lat2*180/3.14159:.10f}, {lng2*180/3.14159:.10f}")
print(f" Distance: {distance:.4f} miles") print(f" Distance: {distance:.4f} miles")
return distance return distance
@@ -455,7 +455,7 @@ def calculate_location_accuracy_enhanced(qr_address, checkin_address, checkin_la
print(f"❌ Could not geocode QR address: {qr_address}") print(f"❌ Could not geocode QR address: {qr_address}")
return None return None
print(f"✅ QR location coordinates: {qr_lat:.8f}, {qr_lng:.8f} (accuracy: {qr_accuracy})") print(f"✅ QR location coordinates: {qr_lat:.10f}, {qr_lng:.10f} (accuracy: {qr_accuracy})")
# Step 2: Determine check-in coordinates # Step 2: Determine check-in coordinates
print(f"\n📱 Step 2: Determining check-in coordinates...") print(f"\n📱 Step 2: Determining check-in coordinates...")
@@ -475,7 +475,7 @@ def calculate_location_accuracy_enhanced(qr_address, checkin_address, checkin_la
checkin_coords_lat = lat_val checkin_coords_lat = lat_val
checkin_coords_lng = lng_val checkin_coords_lng = lng_val
checkin_source = "gps" checkin_source = "gps"
print(f"✅ Using GPS coordinates: {lat_val:.8f}, {lng_val:.8f}") print(f"✅ Using GPS coordinates: {lat_val:.10f}, {lng_val:.10f}")
else: else:
print(f"⚠️ Invalid GPS coordinates: {lat_val}, {lng_val}") print(f"⚠️ Invalid GPS coordinates: {lat_val}, {lng_val}")
except (ValueError, TypeError): except (ValueError, TypeError):
@@ -487,7 +487,7 @@ def calculate_location_accuracy_enhanced(qr_address, checkin_address, checkin_la
checkin_coords_lat, checkin_coords_lng, checkin_accuracy = get_coordinates_from_address_enhanced(checkin_address) checkin_coords_lat, checkin_coords_lng, checkin_accuracy = get_coordinates_from_address_enhanced(checkin_address)
if checkin_coords_lat is not None: if checkin_coords_lat is not None:
checkin_source = "address" checkin_source = "address"
print(f"✅ Using geocoded coordinates: {checkin_coords_lat:.8f}, {checkin_coords_lng:.8f} (accuracy: {checkin_accuracy})") print(f"✅ Using geocoded coordinates: {checkin_coords_lat:.10f}, {checkin_coords_lng:.10f} (accuracy: {checkin_accuracy})")
# Check if we have valid coordinates for both locations # Check if we have valid coordinates for both locations
if checkin_coords_lat is None or checkin_coords_lng is None: if checkin_coords_lat is None or checkin_coords_lng is None:
@@ -502,8 +502,8 @@ def calculate_location_accuracy_enhanced(qr_address, checkin_address, checkin_la
if distance is not None: if distance is not None:
print(f"✅ Enhanced location accuracy calculated successfully!") print(f"✅ Enhanced location accuracy calculated successfully!")
print(f" QR Location: {qr_lat:.8f}, {qr_lng:.8f}") print(f" QR Location: {qr_lat:.10f}, {qr_lng:.10f}")
print(f" Check-in Location: {checkin_coords_lat:.8f}, {checkin_coords_lng:.8f}") print(f" Check-in Location: {checkin_coords_lat:.10f}, {checkin_coords_lng:.10f}")
print(f" Source: {checkin_source}") print(f" Source: {checkin_source}")
print(f" Distance: {distance:.4f} miles") print(f" Distance: {distance:.4f} miles")
print(f" Accuracy Level: {get_location_accuracy_level_enhanced(distance)}") print(f" Accuracy Level: {get_location_accuracy_level_enhanced(distance)}")
@@ -1387,7 +1387,7 @@ def geocode_address():
'latitude': lat, 'latitude': lat,
'longitude': lng, 'longitude': lng,
'accuracy': accuracy, 'accuracy': accuracy,
'coordinates_display': f"{lat:.8f}, {lng:.8f}" 'coordinates_display': f"{lat:.10f}, {lng:.10f}"
}, },
'message': f'Address geocoded successfully with {accuracy} accuracy' 'message': f'Address geocoded successfully with {accuracy} accuracy'
}) })
@@ -1745,7 +1745,7 @@ def create_qr_code():
new_qr_code.address_longitude = lng new_qr_code.address_longitude = lng
new_qr_code.coordinate_accuracy = coordinate_accuracy new_qr_code.coordinate_accuracy = coordinate_accuracy
new_qr_code.coordinates_updated_date = datetime.utcnow() new_qr_code.coordinates_updated_date = datetime.utcnow()
print(f"✅ Added coordinates to QR code: {lat:.8f}, {lng:.8f}") print(f"✅ Added coordinates to QR code: {lat:.10f}, {lng:.10f}")
except (ValueError, TypeError) as e: except (ValueError, TypeError) as e:
print(f"⚠️ Invalid coordinates provided: {e}") print(f"⚠️ Invalid coordinates provided: {e}")
@@ -1810,7 +1810,7 @@ def edit_qr_code(qr_id):
qr_code.address_longitude = lng qr_code.address_longitude = lng
qr_code.coordinate_accuracy = coordinate_accuracy qr_code.coordinate_accuracy = coordinate_accuracy
qr_code.coordinates_updated_date = datetime.utcnow() qr_code.coordinates_updated_date = datetime.utcnow()
print(f"✅ Updated coordinates for QR code: {lat:.8f}, {lng:.8f}") print(f"✅ Updated coordinates for QR code: {lat:.10f}, {lng:.10f}")
except (ValueError, TypeError) as e: except (ValueError, TypeError) as e:
print(f"⚠️ Invalid coordinates provided during edit: {e}") print(f"⚠️ Invalid coordinates provided during edit: {e}")
@@ -2347,7 +2347,7 @@ def attendance_report():
'gps_accuracy': gps_accuracy, 'gps_accuracy': gps_accuracy,
'accuracy_level': get_location_accuracy_level(location_accuracy) if location_accuracy else 'unknown', 'accuracy_level': get_location_accuracy_level(location_accuracy) if location_accuracy else 'unknown',
'has_location_data': record.latitude is not None and record.longitude is not None, 'has_location_data': record.latitude is not None and record.longitude is not None,
'coordinates': f"{record.latitude:.8f}, {record.longitude:.8f}" if record.latitude and record.longitude else "No GPS data", 'coordinates': f"{record.latitude:.10f}, {record.longitude:.10f}" if record.latitude and record.longitude else "No GPS data",
'has_location_accuracy_feature': has_location_accuracy 'has_location_accuracy_feature': has_location_accuracy
} }
processed_records.append(record_dict) processed_records.append(record_dict)
+153 -129
View File
@@ -21,58 +21,58 @@ let locationRequestActive = false;
let locationWatchId = null; let locationWatchId = null;
// BILINGUAL FUNCTIONALITY (PRESERVED FROM ORIGINAL) // BILINGUAL FUNCTIONALITY (PRESERVED FROM ORIGINAL)
let currentLanguage = 'en'; let currentLanguage = "en";
const translations = { const translations = {
en: { en: {
languageText: 'EN', languageText: "EN",
statusMessages: { statusMessages: {
processing: 'Processing check-in...', processing: "Processing check-in...",
success: 'Check-in successful!', success: "Check-in successful!",
error: 'Check-in failed. Please try again.', error: "Check-in failed. Please try again.",
duplicate: 'You have already checked in today.', duplicate: "You have already checked in today.",
tooSoon: 'Please wait before checking in again.', tooSoon: "Please wait before checking in again.",
multipleSuccess: 'Submitted successfully!', multipleSuccess: "Submitted successfully!",
invalidId: 'Please enter a valid Employee ID.', invalidId: "Please enter a valid Employee ID.",
locationError: 'Unable to get location data.', locationError: "Unable to get location data.",
networkError: 'Network error. Please check your connection.' networkError: "Network error. Please check your connection.",
} },
}, },
es: { es: {
languageText: 'ES', languageText: "ES",
statusMessages: { statusMessages: {
processing: 'Procesando registro...', processing: "Procesando registro...",
success: '¡Registro exitoso!', success: "¡Registro exitoso!",
error: 'Error en el registro. Por favor intente de nuevo.', error: "Error en el registro. Por favor intente de nuevo.",
duplicate: 'Ya se ha registrado hoy.', duplicate: "Ya se ha registrado hoy.",
tooSoon: 'Por favor espere antes de registrarse nuevamente.', tooSoon: "Por favor espere antes de registrarse nuevamente.",
multipleSuccess: 'Submitted successful!!', multipleSuccess: "Submitted successful!!",
invalidId: 'Por favor ingrese un ID de empleado válido.', invalidId: "Por favor ingrese un ID de empleado válido.",
locationError: 'No se pudo obtener datos de ubicación.', locationError: "No se pudo obtener datos de ubicación.",
networkError: 'Error de red. Verifique su conexión.' networkError: "Error de red. Verifique su conexión.",
} },
} },
}; };
// DOM Content Loaded Event (PRESERVED FROM ORIGINAL) // DOM Content Loaded Event (PRESERVED FROM ORIGINAL)
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function () {
console.log("🎯 QR Destination page loaded"); console.log("🎯 QR Destination page loaded");
// Initialize language functionality // Initialize language functionality
initializeLanguage(); initializeLanguage();
// Initialize form handling // Initialize form handling
initializeForm(); initializeForm();
// Initialize location services // Initialize location services
initializeLocation(); initializeLocation();
// Start real-time clock // Start real-time clock
startClock(); startClock();
// Add fade-in animation to elements // Add fade-in animation to elements
setTimeout(() => { setTimeout(() => {
document.querySelectorAll('.fade-transition').forEach(el => { document.querySelectorAll(".fade-transition").forEach((el) => {
el.classList.add('active'); el.classList.add("active");
}); });
}, 100); }, 100);
}); });
@@ -81,16 +81,16 @@ document.addEventListener("DOMContentLoaded", function() {
function initializeForm() { function initializeForm() {
const form = document.getElementById("checkinForm"); const form = document.getElementById("checkinForm");
const submitButton = document.getElementById("submitCheckin"); const submitButton = document.getElementById("submitCheckin");
if (form && submitButton) { if (form && submitButton) {
form.addEventListener("submit", handleFormSubmit); form.addEventListener("submit", handleFormSubmit);
// Add real-time Employee ID validation // Add real-time Employee ID validation
const employeeIdInput = document.getElementById("employee_id"); const employeeIdInput = document.getElementById("employee_id");
if (employeeIdInput) { if (employeeIdInput) {
employeeIdInput.addEventListener("input", validateEmployeeId); employeeIdInput.addEventListener("input", validateEmployeeId);
employeeIdInput.addEventListener("keypress", function(e) { employeeIdInput.addEventListener("keypress", function (e) {
if (e.key === 'Enter') { if (e.key === "Enter") {
e.preventDefault(); e.preventDefault();
handleFormSubmit(e); handleFormSubmit(e);
} }
@@ -101,29 +101,31 @@ function initializeForm() {
function handleFormSubmit(event) { function handleFormSubmit(event) {
event.preventDefault(); event.preventDefault();
if (isSubmitting) { if (isSubmitting) {
console.log("⏳ Check-in already in progress, ignoring duplicate submission"); console.log(
"⏳ Check-in already in progress, ignoring duplicate submission"
);
return; return;
} }
console.log("🎯 Form submission triggered"); console.log("🎯 Form submission triggered");
const employeeId = document.getElementById("employee_id")?.value?.trim(); const employeeId = document.getElementById("employee_id")?.value?.trim();
if (!employeeId) { if (!employeeId) {
showLocalizedStatusMessage('invalidId', 'error'); showLocalizedStatusMessage("invalidId", "error");
return; return;
} }
if (employeeId.length < 2) { if (employeeId.length < 2) {
showLocalizedStatusMessage('invalidId', 'error'); showLocalizedStatusMessage("invalidId", "error");
return; return;
} }
// Show processing status // Show processing status
showLocalizedStatusMessage('processing', 'info'); showLocalizedStatusMessage("processing", "info");
// Submit the check-in // Submit the check-in
submitCheckin(); submitCheckin();
} }
@@ -131,32 +133,38 @@ function handleFormSubmit(event) {
// ENHANCED CHECK-IN SUBMISSION WITH MULTIPLE CHECK-IN SUPPORT // ENHANCED CHECK-IN SUBMISSION WITH MULTIPLE CHECK-IN SUPPORT
function submitCheckin() { function submitCheckin() {
console.log("🚀 Starting check-in submission process"); console.log("🚀 Starting check-in submission process");
if (isSubmitting) { if (isSubmitting) {
console.log("⏳ Already submitting, aborting"); console.log("⏳ Already submitting, aborting");
return; return;
} }
isSubmitting = true; isSubmitting = true;
updateSubmitButton(true); updateSubmitButton(true);
const employeeId = document.getElementById("employee_id").value.trim(); const employeeId = document.getElementById("employee_id").value.trim();
if (!employeeId) { if (!employeeId) {
showLocalizedStatusMessage('invalidId', 'error'); showLocalizedStatusMessage("invalidId", "error");
isSubmitting = false; isSubmitting = false;
updateSubmitButton(false); updateSubmitButton(false);
return; return;
} }
console.log(`👤 Employee ID: ${employeeId}`); console.log(`👤 Employee ID: ${employeeId}`);
console.log(`📍 User location:`, userLocation); console.log(`📍 User location:`, userLocation);
// Prepare form data // Prepare form data
const formData = new FormData(); const formData = new FormData();
formData.append("employee_id", employeeId); formData.append("employee_id", employeeId);
formData.append("latitude", userLocation.latitude ? userLocation.latitude.toFixed(8) : ""); formData.append(
formData.append("longitude", userLocation.longitude ? userLocation.longitude.toFixed(8) : ""); "latitude",
userLocation.latitude ? userLocation.latitude.toFixed(10) : ""
);
formData.append(
"longitude",
userLocation.longitude ? userLocation.longitude.toFixed(10) : ""
);
formData.append("accuracy", userLocation.accuracy || ""); formData.append("accuracy", userLocation.accuracy || "");
formData.append("altitude", userLocation.altitude || ""); formData.append("altitude", userLocation.altitude || "");
formData.append("location_source", userLocation.source || "manual"); formData.append("location_source", userLocation.source || "manual");
@@ -197,17 +205,20 @@ function handleCheckinResponse(data) {
if (data.success) { if (data.success) {
handleCheckinSuccess(data); handleCheckinSuccess(data);
} else { } else {
const errorMsg = data.message || 'Submission failed'; const errorMsg = data.message || "Submission failed";
console.log("❌ Submission failed:", errorMsg); console.log("❌ Submission failed:", errorMsg);
// NEW: Handle different types of check-in failures // NEW: Handle different types of check-in failures
if (errorMsg.toLowerCase().includes('already submitted')) { if (errorMsg.toLowerCase().includes("already submitted")) {
showLocalizedStatusMessage('duplicate', 'warning'); showLocalizedStatusMessage("duplicate", "warning");
} else if (errorMsg.toLowerCase().includes('submit again in') || errorMsg.toLowerCase().includes('minutes')) { } else if (
errorMsg.toLowerCase().includes("submit again in") ||
errorMsg.toLowerCase().includes("minutes")
) {
// Handle 30-minute interval message // Handle 30-minute interval message
showCustomStatusMessage(errorMsg, 'warning'); showCustomStatusMessage(errorMsg, "warning");
} else { } else {
showLocalizedStatusMessage('error', 'error'); showLocalizedStatusMessage("error", "error");
} }
} }
} }
@@ -215,18 +226,18 @@ function handleCheckinResponse(data) {
// ENHANCED SUCCESS HANDLING WITH MULTIPLE CHECK-IN INFO // ENHANCED SUCCESS HANDLING WITH MULTIPLE CHECK-IN INFO
function handleCheckinSuccess(data) { function handleCheckinSuccess(data) {
console.log("✅ Submitted successful!"); console.log("✅ Submitted successful!");
const responseData = data.data || data || {}; const responseData = data.data || data || {};
const checkinCount = responseData.checkin_count_today || 1; const checkinCount = responseData.checkin_count_today || 1;
const checkinSequence = responseData.checkin_sequence || 'Check-in'; const checkinSequence = responseData.checkin_sequence || "Check-in";
// Show appropriate success message based on check-in count // Show appropriate success message based on check-in count
if (checkinCount > 1) { if (checkinCount > 1) {
showLocalizedStatusMessage('multipleSuccess', 'success'); showLocalizedStatusMessage("multipleSuccess", "success");
} else { } else {
showLocalizedStatusMessage('success', 'success'); showLocalizedStatusMessage("success", "success");
} }
// Hide form (PRESERVED FROM ORIGINAL) // Hide form (PRESERVED FROM ORIGINAL)
const form = document.getElementById("checkinForm"); const form = document.getElementById("checkinForm");
if (form) { if (form) {
@@ -237,7 +248,7 @@ function handleCheckinSuccess(data) {
const successCard = document.getElementById("successCard"); const successCard = document.getElementById("successCard");
if (successCard) { if (successCard) {
successCard.style.display = "block"; successCard.style.display = "block";
successCard.classList.add('active'); successCard.classList.add("active");
const updateElement = (id, value) => { const updateElement = (id, value) => {
const el = document.getElementById(id); const el = document.getElementById(id);
@@ -248,34 +259,40 @@ function handleCheckinSuccess(data) {
const employeeId = responseData.employee_id || "Unknown"; const employeeId = responseData.employee_id || "Unknown";
const location = responseData.location || "Unknown Location"; const location = responseData.location || "Unknown Location";
const event = responseData.event || responseData.location_event || "Check-in"; const event =
const checkInTime = responseData.check_in_time || new Date().toLocaleTimeString(); responseData.event || responseData.location_event || "Check-in";
const checkInDate = responseData.check_in_date || new Date().toLocaleDateString(); const checkInTime =
responseData.check_in_time || new Date().toLocaleTimeString();
const checkInDate =
responseData.check_in_date || new Date().toLocaleDateString();
updateElement("successEmployeeId", employeeId); updateElement("successEmployeeId", employeeId);
updateElement("successLocation", location); updateElement("successLocation", location);
updateElement("successEvent", event); updateElement("successEvent", event);
updateElement("successCheckInTime", checkInTime); updateElement("successCheckInTime", checkInTime);
updateElement("successCheckInDate", checkInDate); updateElement("successCheckInDate", checkInDate);
// NEW: Add check-in sequence information // NEW: Add check-in sequence information
updateElement("successCheckinSequence", checkinSequence); updateElement("successCheckinSequence", checkinSequence);
// Update additional info if available // Update additional info if available
if (responseData.device_info) { if (responseData.device_info) {
updateElement("successDeviceInfo", responseData.device_info); updateElement("successDeviceInfo", responseData.device_info);
} }
if (responseData.coordinates) { if (responseData.coordinates) {
updateElement("successCoordinates", responseData.coordinates); updateElement("successCoordinates", responseData.coordinates);
} }
if (responseData.address) { if (responseData.address) {
updateElement("successAddress", responseData.address); updateElement("successAddress", responseData.address);
} }
if (responseData.location_accuracy) { if (responseData.location_accuracy) {
updateElement("successLocationAccuracy", `${responseData.location_accuracy} miles`); updateElement(
"successLocationAccuracy",
`${responseData.location_accuracy} miles`
);
} }
} }
@@ -303,8 +320,8 @@ function addCheckInAgainOption() {
</button> </button>
</div> </div>
`; `;
successCard.insertAdjacentHTML('beforeend', checkInAgainHtml); successCard.insertAdjacentHTML("beforeend", checkInAgainHtml);
// Apply current language translations // Apply current language translations
applyTranslations(); applyTranslations();
} }
@@ -313,30 +330,30 @@ function addCheckInAgainOption() {
// NEW: Reset form for new check-in // NEW: Reset form for new check-in
function resetForNewCheckin() { function resetForNewCheckin() {
console.log("🔄 Resetting for new check-in"); console.log("🔄 Resetting for new check-in");
// Show form again // Show form again
const form = document.getElementById("checkinForm"); const form = document.getElementById("checkinForm");
if (form) { if (form) {
form.style.display = "block"; form.style.display = "block";
} }
// Hide success card // Hide success card
const successCard = document.getElementById("successCard"); const successCard = document.getElementById("successCard");
if (successCard) { if (successCard) {
successCard.style.display = "none"; successCard.style.display = "none";
successCard.classList.remove('active'); successCard.classList.remove("active");
} }
// Clear previous employee ID // Clear previous employee ID
const employeeIdInput = document.getElementById("employee_id"); const employeeIdInput = document.getElementById("employee_id");
if (employeeIdInput) { if (employeeIdInput) {
employeeIdInput.value = ''; employeeIdInput.value = "";
employeeIdInput.focus(); employeeIdInput.focus();
} }
// Clear status messages // Clear status messages
clearStatusMessages(); clearStatusMessages();
// Reset location if needed // Reset location if needed
if (!userLocation.latitude || !userLocation.longitude) { if (!userLocation.latitude || !userLocation.longitude) {
requestLocationData(); requestLocationData();
@@ -344,7 +361,7 @@ function resetForNewCheckin() {
} }
// NEW: Show custom status message (for interval warnings) // NEW: Show custom status message (for interval warnings)
function showCustomStatusMessage(message, type = 'info') { function showCustomStatusMessage(message, type = "info") {
const statusContainer = document.getElementById("statusMessage"); const statusContainer = document.getElementById("statusMessage");
if (statusContainer) { if (statusContainer) {
statusContainer.className = `status-message ${type}`; statusContainer.className = `status-message ${type}`;
@@ -355,7 +372,7 @@ function showCustomStatusMessage(message, type = 'info') {
</div> </div>
`; `;
statusContainer.style.display = "block"; statusContainer.style.display = "block";
// Auto-hide after 5 seconds // Auto-hide after 5 seconds
setTimeout(() => { setTimeout(() => {
statusContainer.style.display = "none"; statusContainer.style.display = "none";
@@ -366,20 +383,25 @@ function showCustomStatusMessage(message, type = 'info') {
// Helper function to get appropriate icon for status type // Helper function to get appropriate icon for status type
function getStatusIcon(type) { function getStatusIcon(type) {
switch (type) { switch (type) {
case 'success': return 'fa-check-circle'; case "success":
case 'error': return 'fa-exclamation-circle'; return "fa-check-circle";
case 'warning': return 'fa-clock'; case "error":
case 'info': return "fa-exclamation-circle";
default: return 'fa-info-circle'; case "warning":
return "fa-clock";
case "info":
default:
return "fa-info-circle";
} }
} }
// PRESERVED: All other existing functions remain unchanged // PRESERVED: All other existing functions remain unchanged
function showLocalizedStatusMessage(messageKey, type = 'info') { function showLocalizedStatusMessage(messageKey, type = "info") {
const message = translations[currentLanguage].statusMessages[messageKey] || const message =
translations['en'].statusMessages[messageKey] || translations[currentLanguage].statusMessages[messageKey] ||
'Status update'; translations["en"].statusMessages[messageKey] ||
"Status update";
showCustomStatusMessage(message, type); showCustomStatusMessage(message, type);
} }
@@ -392,7 +414,7 @@ function clearStatusMessages() {
function handleCheckinError(error) { function handleCheckinError(error) {
console.error("❌ Check-in submission error:", error); console.error("❌ Check-in submission error:", error);
showLocalizedStatusMessage('networkError', 'error'); showLocalizedStatusMessage("networkError", "error");
} }
function updateSubmitButton(isLoading) { function updateSubmitButton(isLoading) {
@@ -400,10 +422,12 @@ function updateSubmitButton(isLoading) {
if (submitButton) { if (submitButton) {
if (isLoading) { if (isLoading) {
submitButton.disabled = true; submitButton.disabled = true;
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <span data-en="Processing..." data-es="Procesando...">Processing...</span>'; submitButton.innerHTML =
'<i class="fas fa-spinner fa-spin"></i> <span data-en="Processing..." data-es="Procesando...">Processing...</span>';
} else { } else {
submitButton.disabled = false; submitButton.disabled = false;
submitButton.innerHTML = '<i class="fas fa-user-check"></i> <span data-en="Submit" data-es="Someter">Submit</span>'; submitButton.innerHTML =
'<i class="fas fa-user-check"></i> <span data-en="Submit" data-es="Someter">Submit</span>';
} }
applyTranslations(); applyTranslations();
} }
@@ -412,18 +436,18 @@ function updateSubmitButton(isLoading) {
function validateEmployeeId() { function validateEmployeeId() {
const employeeIdInput = document.getElementById("employee_id"); const employeeIdInput = document.getElementById("employee_id");
const submitButton = document.getElementById("submitCheckin"); const submitButton = document.getElementById("submitCheckin");
if (employeeIdInput && submitButton) { if (employeeIdInput && submitButton) {
const isValid = employeeIdInput.value.trim().length >= 2; const isValid = employeeIdInput.value.trim().length >= 2;
submitButton.disabled = !isValid || isSubmitting; submitButton.disabled = !isValid || isSubmitting;
if (isValid) { if (isValid) {
employeeIdInput.classList.remove('invalid'); employeeIdInput.classList.remove("invalid");
employeeIdInput.classList.add('valid'); employeeIdInput.classList.add("valid");
} else { } else {
employeeIdInput.classList.remove('valid'); employeeIdInput.classList.remove("valid");
if (employeeIdInput.value.length > 0) { if (employeeIdInput.value.length > 0) {
employeeIdInput.classList.add('invalid'); employeeIdInput.classList.add("invalid");
} }
} }
} }
@@ -440,22 +464,22 @@ function requestLocationData() {
console.log("📍 Location request already active, skipping"); console.log("📍 Location request already active, skipping");
return; return;
} }
if (!navigator.geolocation) { if (!navigator.geolocation) {
console.log("❌ Geolocation not supported"); console.log("❌ Geolocation not supported");
userLocation.source = "manual"; userLocation.source = "manual";
return; return;
} }
locationRequestActive = true; locationRequestActive = true;
console.log("📍 Requesting location data..."); console.log("📍 Requesting location data...");
const options = { const options = {
enableHighAccuracy: true, enableHighAccuracy: true,
timeout: 10000, timeout: 10000,
maximumAge: 300000 maximumAge: 300000,
}; };
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
handleLocationSuccess, handleLocationSuccess,
handleLocationError, handleLocationError,
@@ -465,7 +489,7 @@ function requestLocationData() {
function handleLocationSuccess(position) { function handleLocationSuccess(position) {
console.log("✅ Location obtained successfully"); console.log("✅ Location obtained successfully");
userLocation = { userLocation = {
latitude: position.coords.latitude, latitude: position.coords.latitude,
longitude: position.coords.longitude, longitude: position.coords.longitude,
@@ -473,14 +497,14 @@ function handleLocationSuccess(position) {
altitude: position.coords.altitude, altitude: position.coords.altitude,
timestamp: new Date(), timestamp: new Date(),
source: "gps", source: "gps",
address: null address: null,
}; };
console.log("📍 Location data:", userLocation); console.log("📍 Location data:", userLocation);
// Reverse geocode to get address // Reverse geocode to get address
reverseGeocode(userLocation.latitude, userLocation.longitude); reverseGeocode(userLocation.latitude, userLocation.longitude);
locationRequestActive = false; locationRequestActive = false;
} }
@@ -498,26 +522,26 @@ function reverseGeocode(lat, lng) {
// Language functionality remains unchanged // Language functionality remains unchanged
function initializeLanguage() { function initializeLanguage() {
const languageToggle = document.getElementById('languageToggle'); const languageToggle = document.getElementById("languageToggle");
if (languageToggle) { if (languageToggle) {
languageToggle.addEventListener('click', toggleLanguage); languageToggle.addEventListener("click", toggleLanguage);
} }
applyTranslations(); applyTranslations();
} }
function toggleLanguage() { function toggleLanguage() {
currentLanguage = currentLanguage === 'en' ? 'es' : 'en'; currentLanguage = currentLanguage === "en" ? "es" : "en";
applyTranslations(); applyTranslations();
console.log(`🌐 Language switched to: ${currentLanguage}`); console.log(`🌐 Language switched to: ${currentLanguage}`);
} }
function applyTranslations() { function applyTranslations() {
const languageText = document.getElementById('languageText'); const languageText = document.getElementById("languageText");
if (languageText) { if (languageText) {
languageText.textContent = translations[currentLanguage].languageText; languageText.textContent = translations[currentLanguage].languageText;
} }
document.querySelectorAll(`[data-${currentLanguage}]`).forEach(element => { document.querySelectorAll(`[data-${currentLanguage}]`).forEach((element) => {
element.textContent = element.getAttribute(`data-${currentLanguage}`); element.textContent = element.getAttribute(`data-${currentLanguage}`);
}); });
} }
@@ -525,12 +549,12 @@ function applyTranslations() {
function startClock() { function startClock() {
function updateClock() { function updateClock() {
currentTime = new Date(); currentTime = new Date();
const timeElements = document.querySelectorAll('.current-time'); const timeElements = document.querySelectorAll(".current-time");
timeElements.forEach(el => { timeElements.forEach((el) => {
el.textContent = currentTime.toLocaleTimeString(); el.textContent = currentTime.toLocaleTimeString();
}); });
} }
updateClock(); updateClock();
setInterval(updateClock, 1000); setInterval(updateClock, 1000);
} }
+2 -2
View File
@@ -723,8 +723,8 @@
lngDisplay.textContent = coordinatesData.longitude.toFixed(10); lngDisplay.textContent = coordinatesData.longitude.toFixed(10);
clearBtn.style.display = "inline-flex"; clearBtn.style.display = "inline-flex";
} else { } else {
latDisplay.textContent = "---.------"; latDisplay.textContent = "---.----------";
lngDisplay.textContent = "---.------"; lngDisplay.textContent = "---.----------";
clearBtn.style.display = "none"; clearBtn.style.display = "none";
} }
} }
+4 -4
View File
@@ -916,12 +916,12 @@
const clearBtn = document.getElementById('clearCoordinatesBtn'); const clearBtn = document.getElementById('clearCoordinatesBtn');
if (coordinatesData.latitude && coordinatesData.longitude) { if (coordinatesData.latitude && coordinatesData.longitude) {
latDisplay.textContent = coordinatesData.latitude.toFixed(6); latDisplay.textContent = coordinatesData.latitude.toFixed(10);
lngDisplay.textContent = coordinatesData.longitude.toFixed(6); lngDisplay.textContent = coordinatesData.longitude.toFixed(10);
clearBtn.style.display = 'inline-flex'; clearBtn.style.display = 'inline-flex';
} else { } else {
latDisplay.textContent = '---.------'; latDisplay.textContent = '---.----------';
lngDisplay.textContent = '---.------'; lngDisplay.textContent = '---.----------';
clearBtn.style.display = 'none'; clearBtn.style.display = 'none';
} }
} }