`;
}
// Add form fields based on the main map form
previewHTML += `
☐ Yes☐ No
Notes & Comments
`;
// Add footer
if (footer) {
previewHTML += `
`;
}
// Update preview
const previewContent = document.getElementById('walk-sheet-preview-content');
if (previewContent) {
previewContent.innerHTML = previewHTML;
// Generate QR codes after DOM is updated
setTimeout(() => {
generatePreviewQRCodes();
}, 100);
} else {
console.warn('Walk sheet preview content container not found');
}
}
// Generate QR codes for preview
async function generatePreviewQRCodes() {
for (let i = 1; i <= 3; i++) {
const urlInput = document.getElementById(`qr-code-${i}-url`);
const url = urlInput?.value || '';
const qrContainer = document.getElementById(`preview-qr-${i}`);
if (url && qrContainer) {
try {
// Use our local QR code generation endpoint
const qrImageUrl = `/api/qr?text=${encodeURIComponent(url)}&size=100`;
qrContainer.innerHTML = ``;
} catch (error) {
console.error(`Failed to display QR code ${i}:`, error);
qrContainer.innerHTML = '
QR Error
';
}
} else if (qrContainer) {
// Clear empty QR containers
qrContainer.innerHTML = '';
}
}
}
// Print walk sheet
function printWalkSheet() {
// First generate fresh preview to ensure QR codes are generated
generateWalkSheetPreview();
// Wait for QR codes to generate, then print
setTimeout(() => {
// Create a print-specific window
const printContent = document.getElementById('walk-sheet-preview-content').innerHTML;
const printWindow = window.open('', '_blank');
printWindow.document.write(`
Walk Sheet - Print
${printContent}
`);
printWindow.document.close();
// Wait for images to load
printWindow.onload = function() {
setTimeout(() => {
printWindow.print();
printWindow.close();
}, 250);
};
}, 500);
}
// Load walk sheet configuration
async function loadWalkSheetConfig() {
try {
const response = await fetch('/api/admin/walk-sheet-config');
const data = await response.json();
if (data.success && data.data) {
// Populate form fields
const titleInput = document.getElementById('walk-sheet-title');
const subtitleInput = document.getElementById('walk-sheet-subtitle');
const footerInput = document.getElementById('walk-sheet-footer');
if (titleInput) titleInput.value = data.data.walk_sheet_title || '';
if (subtitleInput) subtitleInput.value = data.data.walk_sheet_subtitle || '';
if (footerInput) footerInput.value = data.data.walk_sheet_footer || '';
// Store QR code images if they exist
for (let i = 1; i <= 3; i++) {
const urlField = document.getElementById(`qr-code-${i}-url`);
const labelField = document.getElementById(`qr-code-${i}-label`);
if (urlField && data.data[`qr_code_${i}_url`]) {
urlField.value = data.data[`qr_code_${i}_url`];
}
if (labelField && data.data[`qr_code_${i}_label`]) {
labelField.value = data.data[`qr_code_${i}_label`];
}
// Store the QR code image URL if it exists
if (data.data[`qr_code_${i}_image`]) {
storedQRCodes[`qr_code_${i}_image`] = data.data[`qr_code_${i}_image`];
}
}
// Generate preview
generateWalkSheetPreview();
}
} catch (error) {
console.error('Failed to load walk sheet config:', error);
}
}
// Handle logout
async function handleLogout() {
if (!confirm('Are you sure you want to logout?')) {
return;
}
try {
const response = await fetch('/api/auth/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (response.ok) {
window.location.href = '/login.html';
} else {
showStatus('Logout failed. Please try again.', 'error');
}
} catch (error) {
console.error('Logout error:', error);
showStatus('Logout failed. Please try again.', 'error');
}
}
// Show status message
function showStatus(message, type = 'info') {
const container = document.getElementById('status-container');
const messageDiv = document.createElement('div');
messageDiv.className = `status-message ${type}`;
messageDiv.textContent = message;
container.appendChild(messageDiv);
// Auto-remove after 5 seconds
setTimeout(() => {
messageDiv.remove();
}, 5000);
}
// Escape HTML
function escapeHtml(text) {
if (text === null || text === undefined) {
return '';
}
const div = document.createElement('div');
div.textContent = String(text);
return div.innerHTML;
}
// Debounce function for input events
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}