// File system sync functionality document.getElementById('syncFilesBtn').addEventListener('click', async function() { const btn = this; const status = document.getElementById('syncStatus'); // Disable button and show loading state btn.disabled = true; btn.innerHTML = ' Syncing...'; status.textContent = 'Syncing file system...'; try { const response = await fetch('/api/admin/sync-files', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }); console.log('Sync response status:', response.status); console.log('Sync response headers:', Object.fromEntries(response.headers.entries())); const responseText = await response.text(); console.log('Sync response text:', responseText); let data; try { data = JSON.parse(responseText); console.log('Parsed sync response:', data); } catch (parseError) { console.error('JSON parse error:', parseError); throw new Error('Invalid response format from server'); } if (response.ok) { status.textContent = 'Sync completed successfully!'; status.className = 'text-success small'; } else { throw new Error(data.error || 'Sync failed'); } } catch (error) { console.error('Sync error:', error); status.textContent = error.message; status.className = 'text-danger small'; } finally { // Reset button state btn.disabled = false; btn.innerHTML = ' Sync File System'; // Clear status after 5 seconds setTimeout(() => { status.textContent = ''; status.className = 'text-muted small'; }, 5000); } }); // Database verification functionality document.getElementById('verifyDbBtn').addEventListener('click', async function() { const btn = this; const status = document.getElementById('verifyStatus'); const results = document.getElementById('verificationResults'); // Disable button and show loading state btn.disabled = true; btn.innerHTML = ' Verifying...'; status.textContent = 'Verifying database state...'; results.style.display = 'none'; try { const response = await fetch('/api/admin/verify-db-state', { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }); const data = await response.json(); console.log('Verification response:', data); if (!response.ok) { throw new Error(data.error || 'Verification failed'); } // Update summary const summary = document.getElementById('verificationSummary'); const totalIssues = (data.files_in_db_not_fs?.length || 0) + (data.files_in_fs_not_db?.length || 0) + (data.size_mismatches?.length || 0) + (data.modified_time_mismatches?.length || 0); summary.textContent = `Found ${totalIssues} issues across ${data.rooms_checked || 0} rooms.`; // Update counts and lists updateMismatchSection('dbNotFs', data.files_in_db_not_fs || []); updateMismatchSection('fsNotDb', data.files_in_fs_not_db || []); updateMismatchSection('sizeMismatch', data.size_mismatches || []); updateMismatchSection('timeMismatch', data.modified_time_mismatches || []); // Show results results.style.display = 'block'; status.textContent = 'Verification completed!'; status.className = 'text-success small'; } catch (error) { console.error('Verification error:', error); status.textContent = error.message; status.className = 'text-danger small'; } finally { // Reset button state btn.disabled = false; btn.innerHTML = ' Verify Database State'; } }); // Cleanup orphaned records functionality document.getElementById('cleanupOrphanedBtn').addEventListener('click', async function() { const btn = this; const status = document.getElementById('verifyStatus'); // Disable button and show loading state btn.disabled = true; btn.innerHTML = ' Cleaning up...'; status.textContent = 'Cleaning up orphaned records...'; try { const response = await fetch('/api/admin/cleanup-orphaned-records', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Cleanup failed'); } status.textContent = data.message; status.className = 'text-success small'; // If there were cleaned records, trigger a verification if (data.cleaned_records && data.cleaned_records.length > 0) { document.getElementById('verifyDbBtn').click(); } } catch (error) { console.error('Cleanup error:', error); status.textContent = error.message; status.className = 'text-danger small'; } finally { // Reset button state btn.disabled = false; btn.innerHTML = ' Cleanup Orphaned Records'; // Clear status after 5 seconds setTimeout(() => { status.textContent = ''; status.className = 'text-muted small'; }, 5000); } }); // Helper function to update mismatch sections function updateMismatchSection(sectionId, items) { const count = document.getElementById(`${sectionId}Count`); const list = document.getElementById(`${sectionId}List`); if (!count || !list) { console.error(`Missing elements for section ${sectionId}`); return; } count.textContent = items.length; if (items.length === 0) { list.innerHTML = '