// Upload and Prediction JavaScript // Image preview functionality function setupImagePreview(inputId, previewId, placeholderId) { const input = document.getElementById(inputId); const preview = document.getElementById(previewId); const placeholder = input.parentElement.querySelector('.upload-placeholder'); if (input) { input.addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { preview.src = e.target.result; preview.style.display = 'block'; if (placeholder) placeholder.style.display = 'none'; }; reader.readAsDataURL(file); } }); } } // Setup previews based on mode if (mode === 'multimodal') { setupImagePreview('fundusImage', 'fundusPreview'); setupImagePreview('octImage', 'octPreview'); } else if (mode === 'fundus') { setupImagePreview('fundusImage', 'fundusPreview'); } else if (mode === 'oct') { setupImagePreview('octImage', 'octPreview'); } // Form submission const form = document.getElementById('uploadForm'); const analyzeBtn = document.getElementById('analyzeBtn'); const btnText = document.getElementById('btnText'); const btnLoader = document.getElementById('btnLoader'); const errorMessage = document.getElementById('errorMessage'); const resultsSection = document.getElementById('resultsSection'); form.addEventListener('submit', async function(e) { e.preventDefault(); // Show loading state btnText.style.display = 'none'; btnLoader.style.display = 'inline-block'; analyzeBtn.disabled = true; errorMessage.style.display = 'none'; resultsSection.style.display = 'none'; try { const formData = new FormData(form); const endpoint = `/predict/${mode}`; const response = await fetch(endpoint, { method: 'POST', body: formData }); if (!response.ok) { throw new Error('Prediction failed'); } const result = await response.json(); // Display results displayResults(result); } catch (error) { console.error('Error:', error); errorMessage.textContent = 'An error occurred during analysis. Please try again.'; errorMessage.style.display = 'block'; } finally { // Reset button state btnText.style.display = 'inline'; btnLoader.style.display = 'none'; analyzeBtn.disabled = false; } }); function displayResults(result) { let html = ''; if (mode === 'fundus') { html = generateFundusResults(result); } else if (mode === 'oct') { html = generateOCTResults(result); } else if (mode === 'multimodal') { html = generateMultimodalResults(result); } resultsSection.innerHTML = html; resultsSection.style.display = 'block'; // Scroll to results resultsSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); } function generateFundusResults(result) { const isGlaucoma = result.prediction === 'GON+'; const headerClass = isGlaucoma ? 'warning' : 'success'; return `
Visualization not available
' }Visualization not available
' }Visualization not available
' }Visualization not available
' }