Updated: add verification review detail

This commit is contained in:
2025-12-24 15:27:45 -05:00
parent 4a78348fc2
commit b0b0aa4994
4 changed files with 513 additions and 273 deletions
+7 -240
View File
@@ -639,15 +639,15 @@ function createTableRow(record, displayIndex) {
let locationAccuracyBadge;
if (record.verification_required && record.verification_status === 'pending') {
// Show Review Needed badge for pending verification
locationAccuracyBadge = `<span class="location-accuracy-badge badge-review-needed"
onclick="openVerificationPhotoModal('${record.id}')"
style="cursor: pointer;"
// Show Review Needed badge for pending verification - LINK to review page
locationAccuracyBadge = `<a href="/verification-review/${record.id}"
class="location-accuracy-badge badge-review-needed"
style="cursor: pointer; text-decoration: none;"
title="Click to review verification photo - Distance: ${record.location_accuracy ? record.location_accuracy.toFixed(3) : 'N/A'} miles">
<i class="fas fa-exclamation-triangle"></i>
Review Needed
<small>(${record.location_accuracy ? record.location_accuracy.toFixed(3) : 'N/A'} mi)</small>
</span>`;
</a>`;
} else if (record.verification_status === 'approved') {
// Show Verified badge for approved verification
locationAccuracyBadge = `<span class="location-accuracy-badge badge-verified"
@@ -838,11 +838,11 @@ function createTableRow(record, displayIndex) {
<div class="record-actions">
${
record.verification_required && record.verification_status === 'pending'
? `<button onclick="openVerificationPhotoModal('${record.id}')"
? `<a href="/verification-review/${record.id}"
class="action-btn btn-review"
title="Review Verification Photo">
<i class="fas fa-camera"></i>
</button>`
</a>`
: ''
}
${
@@ -1176,237 +1176,4 @@ document.addEventListener("DOMContentLoaded", function () {
}
console.log("Enhanced export functionality initialized");
});
// ============================================
// VERIFICATION PHOTO REVIEW FUNCTIONS
// ============================================
/**
* Open verification photo modal for review
* @param {string} recordId - The attendance record ID
*/
function openVerificationPhotoModal(recordId) {
console.log(`Opening verification photo modal for record: ${recordId}`);
const modal = document.getElementById("verificationPhotoModal");
const modalBody = document.getElementById("verificationPhotoModalBody");
if (!modal || !modalBody) {
console.error("Verification photo modal elements not found");
return;
}
// Show loading state
modalBody.innerHTML = `
<div class="verification-loading">
<i class="fas fa-spinner fa-spin"></i>
<p>Loading verification photo...</p>
</div>
`;
modal.style.display = "block";
// Fetch record details with verification photo
fetch(`/api/attendance/${recordId}/verification-details`)
.then((response) => {
if (!response.ok) {
throw new Error("Failed to fetch verification details");
}
return response.json();
})
.then((data) => {
if (!data.success) {
throw new Error(data.message || "Failed to load verification data");
}
renderVerificationPhotoModal(data.record);
})
.catch((error) => {
console.error("Error loading verification photo:", error);
modalBody.innerHTML = `
<div class="verification-error">
<i class="fas fa-exclamation-triangle"></i>
<p>Error loading verification photo. Please try again.</p>
<button onclick="closeVerificationPhotoModal()" class="btn btn-secondary">Close</button>
</div>
`;
});
}
/**
* Render verification photo modal content
* @param {Object} record - The attendance record with verification data
*/
function renderVerificationPhotoModal(record) {
const modalBody = document.getElementById("verificationPhotoModalBody");
const content = `
<div class="verification-photo-review">
<!-- Employee & Date Info -->
<div class="verification-header-info">
<h3>
<i class="fas fa-user"></i>
Employee: ${record.employee_id}
</h3>
<p>
<i class="fas fa-calendar"></i>
${record.check_in_date} at ${record.check_in_time}
</p>
</div>
<!-- Verification Photo -->
<div class="verification-photo-container">
${
record.verification_photo
? `<img src="${record.verification_photo}"
alt="Verification Photo"
class="verification-photo-large"
onclick="window.open(this.src, '_blank')"
style="cursor: zoom-in;"
title="Click to view full size" />`
: `<div class="no-photo">
<i class="fas fa-image"></i>
<p>No verification photo available</p>
</div>`
}
</div>
<!-- Location Details -->
<div class="verification-details-grid">
<div class="verification-detail-card">
<h4>Location Name</h4>
<p>${record.location_name}</p>
</div>
<div class="verification-detail-card">
<h4>Distance from QR</h4>
<p>${parseFloat(record.location_accuracy).toFixed(3)} miles</p>
</div>
<div class="verification-detail-card">
<h4>Verification Status</h4>
<p>
<span class="verification-status-pending">
<i class="fas fa-clock"></i>
Pending Review
</span>
</p>
</div>
<div class="verification-detail-card">
<h4>Device</h4>
<p>${record.device_info || "Unknown"}</p>
</div>
</div>
<!-- Address Information -->
<div class="verification-detail-card" style="grid-column: 1 / -1;">
<h4>Check-in Address</h4>
<p>${record.checked_in_address || "No address recorded"}</p>
</div>
<!-- Action Buttons -->
<div class="verification-actions">
<button onclick="updateVerificationStatus(${
record.id
}, 'approved')" class="btn-approve">
<i class="fas fa-check-circle"></i>
Approve Check-in
</button>
<button onclick="updateVerificationStatus(${
record.id
}, 'rejected')" class="btn-reject">
<i class="fas fa-times-circle"></i>
Reject Check-in
</button>
</div>
</div>
`;
modalBody.innerHTML = content;
}
/**
* Close verification photo modal
*/
function closeVerificationPhotoModal() {
const modal = document.getElementById("verificationPhotoModal");
if (modal) {
modal.style.display = "none";
}
}
/**
* Update verification status (approve/reject)
* @param {number} recordId - The attendance record ID
* @param {string} status - The new status ('approved' or 'rejected')
*/
function updateVerificationStatus(recordId, status) {
if (
!confirm(
`Are you sure you want to ${status} this verification?\n\nThis action will be logged for audit purposes.`
)
) {
return;
}
console.log(`Updating verification status for record ${recordId} to ${status}`);
// Show loading state
const modalBody = document.getElementById("verificationPhotoModalBody");
modalBody.innerHTML = `
<div class="verification-loading">
<i class="fas fa-spinner fa-spin"></i>
<p>Updating verification status...</p>
</div>
`;
// Send update request
fetch(`/verification-review/${recordId}/update`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
},
body: JSON.stringify({
status: status,
note: `Verification ${status} from attendance report review`,
}),
})
.then((response) => response.json())
.then((data) => {
if (data.success) {
alert(
`Verification ${status} successfully!\n\nThe page will reload to show the updated status.`
);
closeVerificationPhotoModal();
// Reload the page to show updated status
window.location.reload();
} else {
throw new Error(data.message || "Failed to update verification status");
}
})
.catch((error) => {
console.error("Error updating verification status:", error);
alert(`Error: ${error.message}\n\nPlease try again.`);
// Reload modal to show previous state
openVerificationPhotoModal(recordId);
});
}
// Close verification modal when clicking outside
window.addEventListener("click", function (event) {
const verificationModal = document.getElementById("verificationPhotoModal");
if (event.target === verificationModal) {
closeVerificationPhotoModal();
}
});
// Keyboard shortcut for closing verification modal
document.addEventListener("keydown", function (event) {
if (event.key === "Escape") {
closeVerificationPhotoModal();
}
});