// Main JavaScript for SpeciScan document.addEventListener('DOMContentLoaded', function() { // DOM Elements const uploadForm = document.getElementById('upload-form'); const nameForm = document.getElementById('name-form'); const fileInput = document.getElementById('file-input'); const fileName = document.getElementById('file-name'); const uploadZone = document.getElementById('upload-zone'); const resultsContainer = document.getElementById('results'); const loadingOverlay = document.getElementById('loading-overlay'); // Handle drag and drop for file upload uploadZone.addEventListener('dragover', function(e) { e.preventDefault(); uploadZone.classList.add('dragover'); }); uploadZone.addEventListener('dragleave', function() { uploadZone.classList.remove('dragover'); }); uploadZone.addEventListener('drop', function(e) { e.preventDefault(); uploadZone.classList.remove('dragover'); if (e.dataTransfer.files.length) { fileInput.files = e.dataTransfer.files; updateFileName(); } }); // Update file name display when file is selected fileInput.addEventListener('change', updateFileName); function updateFileName() { if (fileInput.files.length > 0) { fileName.textContent = fileInput.files[0].name; uploadZone.classList.add('has-file'); } else { fileName.textContent = ''; uploadZone.classList.remove('has-file'); } } // Handle image upload form submission uploadForm.addEventListener('submit', function(e) { e.preventDefault(); if (fileInput.files.length === 0) { alert('Please select an image file.'); return; } const formData = new FormData(); formData.append('file', fileInput.files[0]); // Show loading overlay loadingOverlay.classList.add('active'); // Submit form data to server fetch('/upload_image', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // Hide loading overlay loadingOverlay.classList.remove('active'); // Display results displayResults(data); }) .catch(error => { // Hide loading overlay loadingOverlay.classList.remove('active'); console.error('Error:', error); alert('Error: ' + error.message); }); }); // Handle species name form submission nameForm.addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(nameForm); // Show loading overlay loadingOverlay.classList.add('active'); // Submit form data to server fetch('/search_by_name', { method: 'POST', body: formData }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // Hide loading overlay loadingOverlay.classList.remove('active'); // Display results displayResults(data); }) .catch(error => { // Hide loading overlay loadingOverlay.classList.remove('active'); console.error('Error:', error); alert('Error: ' + error.message); }); }); // Handle suggestion chips const suggestionChips = document.querySelectorAll('.chip'); const speciesNameInput = nameForm.querySelector('input[name="species_name"]'); suggestionChips.forEach(chip => { chip.addEventListener('click', function() { const speciesName = this.getAttribute('data-species'); speciesNameInput.value = speciesName; nameForm.dispatchEvent(new Event('submit')); }); }); // Function to display results function displayResults(data) { // Scroll to results resultsContainer.scrollIntoView({ behavior: 'smooth' }); // Check if we have valid data if (data.error) { resultsContainer.innerHTML = `
`; resultsContainer.classList.add('active'); return; } // Extract data const speciesData = data.species_data; const images = data.images; // Check if species data contains an error if (speciesData.error) { // If we have some basic information despite the error, display it with a notice if (speciesData.title) { let errorHtml = ` `; // Build the complete HTML for limited results const resultsHtml = `${speciesData.title}
${errorHtml}${speciesData.description || 'No description available.'}
${image.description || 'No description available'}
By: ${image.author}No images available.
'; } // Get the main image from the first gallery image or use a placeholder const mainImageUrl = images && images.length > 0 && !images[0].error ? images[0].url : 'https://via.placeholder.com/300x250?text=No+Image+Available'; // Build the complete HTML for results const resultsHtml = `${speciesData.title}
${speciesData.description || 'No description available.'}
${speciesData.habitat || 'Habitat information not available.'}
Data sources: ${speciesData.data_sources.join(', ')}