Spaces:
Sleeping
Sleeping
// Function to show the selected section and hide the others | |
function showSection(sectionId) { | |
// Show the selected section (in case it was hidden) | |
const activeSection = document.getElementById(sectionId); | |
if (activeSection) { | |
activeSection.style.display = 'block'; | |
// Scroll to the section smoothly | |
activeSection.scrollIntoView({ | |
behavior: 'smooth', | |
block: 'start' // Aligns the section at the top of the viewport | |
}); | |
} | |
} | |
function showCards() { | |
// Show cards section | |
document.querySelector('.cards').style.display = 'grid'; // or 'flex' depending on your layout | |
// Hide all tool sections | |
const sections = document.querySelectorAll('.tool-section'); | |
sections.forEach(section => { | |
section.style.display = 'none'; | |
}); | |
// Scroll to top | |
window.scrollTo({ top: 0, behavior: 'smooth' }); | |
} | |
document.addEventListener('DOMContentLoaded', () => { | |
// Set up card click handlers | |
document.querySelectorAll('.card').forEach(card => { | |
card.addEventListener('click', function() { | |
const sectionId = this.getAttribute('onclick').match(/'([^']+)'/)[1]; | |
showSection(sectionId); | |
}); | |
}); | |
// Hide all tool sections by default | |
const sections = document.querySelectorAll('.tool-section'); | |
sections.forEach(section => { | |
section.style.display = 'none'; | |
}); | |
// Show first section by default | |
showSection('document-image-analysis'); | |
// Helper functions | |
function preventDefaults(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
} | |
function highlight(element) { | |
element.classList.add('highlight'); | |
} | |
function unhighlight(element) { | |
element.classList.remove('highlight'); | |
} | |
function isValidFileType(file, types, extensions) { | |
return types.includes(file.type) || extensions.some(ext => file.name.endsWith(ext)); | |
} | |
function getFileIcon(file) { | |
if (file.type.startsWith('image/')) return '🖼️'; | |
if (file.type === 'application/pdf') return '📄'; | |
if (file.type.includes('wordprocessingml')) return '📝'; | |
if (file.type.includes('spreadsheetml') || file.type === 'text/csv') return '📊'; | |
return '📁'; | |
} | |
function formatFileSize(bytes) { | |
if (bytes === 0) return '0 Bytes'; | |
const k = 1024; | |
const sizes = ['Bytes', 'KB', 'MB', 'GB']; | |
const i = Math.floor(Math.log(bytes) / Math.log(k)); | |
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; | |
} | |
function showError(element, message) { | |
element.textContent = message; | |
element.classList.remove('hidden'); | |
} | |
function hideError(element) { | |
element.classList.add('hidden'); | |
} | |
function setLoading(button, isLoading, loadingText = 'Processing...') { | |
const btnText = button.querySelector('span:not(.spinner)'); | |
const spinner = button.querySelector('.spinner'); | |
button.disabled = isLoading; | |
btnText.textContent = isLoading ? loadingText : btnText.dataset.defaultText; | |
spinner.classList.toggle('hidden', !isLoading); | |
} | |
// Document Analysis Section Setup | |
const summarizeDropArea = document.getElementById('upload-area'); | |
const summarizeFileInput = document.getElementById('file-input'); | |
const summarizePreview = document.getElementById('file-preview'); | |
const textInput = document.getElementById('text-input'); | |
const summarizeBtn = document.getElementById('summarize-btn'); | |
const summarizeResult = document.getElementById('result-content'); | |
const summarizeError = document.getElementById('error-message'); | |
const languageSelect = document.getElementById('language-select'); | |
// Store default button text | |
summarizeBtn.querySelector('span').dataset.defaultText = 'Summarize Document'; | |
// Set up drag and drop for file upload | |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
summarizeDropArea.addEventListener(eventName, preventDefaults, false); | |
}); | |
['dragenter', 'dragover'].forEach(eventName => { | |
summarizeDropArea.addEventListener(eventName, () => highlight(summarizeDropArea), false); | |
}); | |
['dragleave', 'drop'].forEach(eventName => { | |
summarizeDropArea.addEventListener(eventName, () => unhighlight(summarizeDropArea), false); | |
}); | |
summarizeDropArea.addEventListener('drop', handleDrop, false); | |
summarizeDropArea.addEventListener('click', (e) => { | |
if (e.target === summarizeDropArea) { | |
summarizeFileInput.click(); | |
} | |
}); | |
summarizeFileInput.addEventListener('change', handleFileSelect); | |
textInput.addEventListener('input', validateInputs); | |
function handleDrop(e) { | |
const dt = e.dataTransfer; | |
const files = dt.files; | |
handleFiles(files); | |
} | |
function handleFileSelect(e) { | |
const files = e.target.files; | |
if (files.length) { | |
handleFiles(files); | |
} | |
} | |
function handleFiles(files) { | |
const file = files[0]; | |
const validTypes = [ | |
'application/pdf', | |
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', | |
'text/plain', | |
'image/jpeg', | |
'image/png' | |
]; | |
const validExtensions = ['.pdf', '.docx', '.txt']; | |
if (!isValidFileType(file, validTypes, validExtensions)) { | |
showError(summarizeError, "Unsupported file type. Please upload PDF, DOCX, TXT, or image files."); | |
return; | |
} | |
summarizePreview.innerHTML = ` | |
<div class="file-info"> | |
<span class="file-icon">${getFileIcon(file)}</span> | |
<div> | |
<strong>${file.name}</strong> | |
<span>${formatFileSize(file.size)}</span> | |
</div> | |
</div> | |
`; | |
validateInputs(); | |
} | |
function validateInputs() { | |
const hasFile = summarizeFileInput.files.length > 0; | |
const hasText = textInput.value.trim() !== ''; | |
summarizeBtn.disabled = !(hasFile || hasText); | |
} | |
// Summarize button click handler | |
summarizeBtn.addEventListener('click', async () => { | |
const file = summarizeFileInput.files[0]; | |
const text = textInput.value.trim(); | |
const language = languageSelect.value; | |
if (!file && !text) { | |
showError(summarizeError, "Please upload a file or enter text"); | |
return; | |
} | |
try { | |
setLoading(summarizeBtn, true); | |
hideError(summarizeError); | |
summarizeResult.textContent = ''; | |
const formData = new FormData(); | |
if (file) formData.append('file', file); | |
if (text) formData.append('text', text); | |
formData.append('language', language); | |
const response = await fetch('/summarize', { | |
method: 'POST', | |
body: formData | |
}); | |
if (!response.ok) { | |
const error = await response.json(); | |
throw new Error(error.detail || "Failed to summarize content"); | |
} | |
const result = await response.json(); | |
summarizeResult.textContent = result.summary; | |
} catch (error) { | |
showError(summarizeError, error.message); | |
console.error("Summarization error:", error); | |
} finally { | |
setLoading(summarizeBtn, false); | |
} | |
}); | |
// Question Answering Section Setup | |
const qaDropArea = document.getElementById('qa-upload-area'); | |
const qaFileInput = document.getElementById('qa-file-input'); | |
const qaPreview = document.getElementById('qa-file-preview'); | |
const qaQuestionInput = document.getElementById('qa-question'); | |
const qaSubmitBtn = document.getElementById('qa-submit-btn'); | |
const qaResult = document.getElementById('qa-answer'); | |
const qaError = document.getElementById('qa-error-message'); | |
const qaLanguageSelect = document.getElementById('qa-language'); | |
// Store default button text | |
qaSubmitBtn.querySelector('span').dataset.defaultText = 'Get Answer'; | |
// Setup event listeners | |
if (qaDropArea && qaFileInput) { | |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
qaDropArea.addEventListener(eventName, preventDefaults, false); | |
}); | |
['dragenter', 'dragover'].forEach(eventName => { | |
qaDropArea.addEventListener(eventName, () => highlight(qaDropArea), false); | |
}); | |
['dragleave', 'drop'].forEach(eventName => { | |
qaDropArea.addEventListener(eventName, () => unhighlight(qaDropArea), false); | |
}); | |
qaDropArea.addEventListener('drop', handleQADrop, false); | |
// Question Answering Section | |
qaDropArea.addEventListener('click', (e) => { | |
if (e.target === qaDropArea) { | |
qaFileInput.click(); | |
} | |
}); | |
qaFileInput.addEventListener('change', handleQAFileSelect); | |
} | |
if (qaQuestionInput && qaSubmitBtn) { | |
qaQuestionInput.addEventListener('input', validateQAInputs); | |
qaSubmitBtn.addEventListener('click', handleQASubmit); | |
} | |
function handleQADrop(e) { | |
const dt = e.dataTransfer; | |
const files = dt.files; | |
handleQAFiles(files); | |
} | |
function handleQAFileSelect(e) { | |
const files = e.target.files; | |
if (files.length) { | |
handleQAFiles(files); | |
} | |
} | |
function handleQAFiles(files) { | |
const file = files[0]; | |
const validTypes = [ | |
'application/pdf', | |
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', | |
'text/plain' | |
]; | |
const validExtensions = ['.pdf', '.docx', '.txt']; | |
if (!isValidFileType(file, validTypes, validExtensions)) { | |
showError(qaError, "Unsupported file type. Please upload PDF, DOCX, or TXT files."); | |
return; | |
} | |
qaPreview.innerHTML = ` | |
<div class="file-info"> | |
<span class="file-icon">${getFileIcon(file)}</span> | |
<div> | |
<strong>${file.name}</strong> | |
<span>${formatFileSize(file.size)}</span> | |
</div> | |
</div> | |
`; | |
validateQAInputs(); | |
} | |
function validateQAInputs() { | |
const hasFile = qaFileInput.files.length > 0; | |
const hasQuestion = qaQuestionInput.value.trim() !== ''; | |
qaSubmitBtn.disabled = !(hasFile && hasQuestion); | |
} | |
async function handleQASubmit() { | |
const file = qaFileInput.files[0]; | |
const question = qaQuestionInput.value.trim(); | |
const language = qaLanguageSelect.value; | |
if (!file) { | |
showError(qaError, "Please upload a document first"); | |
return; | |
} | |
if (!question) { | |
showError(qaError, "Please enter your question"); | |
return; | |
} | |
try { | |
setLoading(qaSubmitBtn, true); | |
hideError(qaError); | |
const formData = new FormData(); | |
formData.append('file', file); | |
formData.append('question', question); | |
formData.append('language', language); | |
const response = await fetch('/qa', { | |
method: 'POST', | |
body: formData | |
}); | |
if (!response.ok) { | |
const error = await response.json(); | |
throw new Error(error.detail || "Failed to get answer"); | |
} | |
const result = await response.json(); | |
displayQAResult(result); | |
} catch (error) { | |
showError(qaError, error.message); | |
console.error("QA Error:", error); | |
} finally { | |
setLoading(qaSubmitBtn, false); | |
} | |
} | |
function displayQAResult(result) { | |
qaResult.textContent = result.answer; | |
} | |
// Data Visualization Section Setup | |
const dataDropArea = document.getElementById('data-upload-area'); | |
const dataFileInput = document.getElementById('data-file-input'); | |
const dataPreview = document.getElementById('data-file-preview'); | |
const visualizeBtn = document.getElementById('visualize-btn'); | |
const visualizationPrompt = document.getElementById('visualization-prompt'); | |
const chartTypeSelect = document.getElementById('chart-type-select'); | |
const visualizationResult = document.getElementById('visualization-results'); | |
const visualizationError = document.getElementById('visualization-error'); | |
const visualizationImage = document.getElementById('generated-visualization'); | |
const pythonCodeOutput = document.getElementById('python-code-output'); | |
const dataPreviewContainer = document.getElementById('data-preview-container'); | |
const copyCodeBtn = document.getElementById('copy-code-btn'); | |
// Store default button text | |
visualizeBtn.querySelector('span').dataset.defaultText = 'Generate Visualization'; | |
// Setup drag and drop for data visualization | |
if (dataDropArea && dataFileInput) { | |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
dataDropArea.addEventListener(eventName, preventDefaults, false); | |
}); | |
['dragenter', 'dragover'].forEach(eventName => { | |
dataDropArea.addEventListener(eventName, () => highlight(dataDropArea), false); | |
}); | |
['dragleave', 'drop'].forEach(eventName => { | |
dataDropArea.addEventListener(eventName, () => unhighlight(dataDropArea), false); | |
}); | |
dataDropArea.addEventListener('drop', handleDataDrop, false); | |
// Data Visualization Section | |
dataDropArea.addEventListener('click', (e) => { | |
if (e.target === dataDropArea) { | |
dataFileInput.click(); | |
} | |
}); | |
dataFileInput.addEventListener('change', handleDataFileSelect); | |
} | |
if (visualizeBtn) { | |
visualizeBtn.addEventListener('click', handleVisualizationSubmit); | |
} | |
if (copyCodeBtn) { | |
copyCodeBtn.addEventListener('click', copyPythonCode); | |
} | |
function handleDataDrop(e) { | |
const dt = e.dataTransfer; | |
const files = dt.files; | |
handleDataFiles(files); | |
} | |
function handleDataFileSelect(e) { | |
const files = e.target.files; | |
if (files.length) { | |
handleDataFiles(files); | |
} | |
} | |
function handleDataFiles(files) { | |
const file = files[0]; | |
const validTypes = [ | |
'application/vnd.ms-excel', | |
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', | |
'text/csv' | |
]; | |
const validExtensions = ['.xlsx', '.xls', '.csv']; | |
if (!isValidFileType(file, validTypes, validExtensions)) { | |
showVisualizationError("Unsupported file type. Please upload Excel or CSV files."); | |
return; | |
} | |
dataPreview.innerHTML = ` | |
<div class="file-info"> | |
<span class="file-icon">${getFileIcon(file)}</span> | |
<div> | |
<strong>${file.name}</strong> | |
<span>${formatFileSize(file.size)}</span> | |
</div> | |
</div> | |
`; | |
} | |
async function handleVisualizationSubmit() { | |
const file = dataFileInput.files[0]; | |
const prompt = visualizationPrompt.value.trim(); | |
const chartType = chartTypeSelect.value; | |
if (!file) { | |
showVisualizationError("Please upload a file first"); | |
return; | |
} | |
try { | |
setLoading(visualizeBtn, true, 'Generating...'); | |
hideVisualizationError(); | |
visualizationResult.classList.add('hidden'); | |
const formData = new FormData(); | |
formData.append('file', file); | |
formData.append('request', prompt); | |
formData.append('chart_type', chartType); | |
const response = await fetch('/generate-visualization', { | |
method: 'POST', | |
body: formData | |
}); | |
if (!response.ok) { | |
const error = await response.json(); | |
throw new Error(error.detail || "Failed to generate visualization"); | |
} | |
const result = await response.json(); | |
displayVisualizationResult(result); | |
} catch (error) { | |
showVisualizationError(error.message); | |
console.error("Visualization error:", error); | |
} finally { | |
setLoading(visualizeBtn, false); | |
} | |
} | |
function displayVisualizationResult(result) { | |
visualizationImage.src = result.image_url; | |
pythonCodeOutput.textContent = result.python_code; | |
// Display data preview | |
dataPreviewContainer.innerHTML = ` | |
<p>Columns: ${result.columns.join(', ')}</p> | |
<small>Note: Only showing first few rows of data</small> | |
`; | |
visualizationResult.classList.remove('hidden'); | |
} | |
function showVisualizationError(message) { | |
visualizationError.textContent = message; | |
visualizationError.classList.remove('hidden'); | |
} | |
function hideVisualizationError() { | |
visualizationError.classList.add('hidden'); | |
} | |
function copyPythonCode() { | |
const code = pythonCodeOutput.textContent; | |
navigator.clipboard.writeText(code) | |
.then(() => { | |
copyCodeBtn.textContent = 'Copied!'; | |
setTimeout(() => { | |
copyCodeBtn.textContent = 'Copy Code'; | |
}, 2000); | |
}) | |
.catch(err => { | |
console.error('Failed to copy code:', err); | |
}); | |
} | |
}); |