Update index.html
This commit is contained in:
@@ -268,14 +268,200 @@
|
||||
// Form Submissions
|
||||
uploadForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
// Add your upload logic here
|
||||
const files = fileInput.files;
|
||||
|
||||
if (files.length === 0) {
|
||||
uploadStatus.innerHTML = '<span class="text-red-500">Please select files to upload</span>';
|
||||
return;
|
||||
}
|
||||
|
||||
uploadProgress.classList.remove('hidden');
|
||||
const progressBar = uploadProgress.querySelector('.bg-blue-600');
|
||||
uploadStatus.textContent = 'Starting upload...';
|
||||
|
||||
try {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
uploadStatus.textContent = `Uploading ${file.name} (${i + 1}/${files.length})...`;
|
||||
console.log(`Uploading file: ${file.name}`);
|
||||
|
||||
try {
|
||||
const response = await fetch('/documents/upload', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem('apiKey') || ''}`
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
console.log('Response status:', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(`Upload failed: ${errorData.detail || response.statusText}`);
|
||||
}
|
||||
|
||||
// Update progress
|
||||
const progress = ((i + 1) / files.length) * 100;
|
||||
progressBar.style.width = `${progress}%`;
|
||||
console.log(`Progress: ${progress}%`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Upload error:', error);
|
||||
uploadStatus.innerHTML = `<span class="text-red-500">Error uploading ${file.name}: ${error.message}</span>`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// All files uploaded successfully
|
||||
uploadStatus.innerHTML = '<span class="text-green-500">All files uploaded successfully!</span>';
|
||||
progressBar.style.width = '100%';
|
||||
|
||||
// Clear the file input and selection display
|
||||
setTimeout(() => {
|
||||
fileInput.value = '';
|
||||
selectedFiles.innerHTML = '';
|
||||
uploadProgress.classList.add('hidden');
|
||||
progressBar.style.width = '0%';
|
||||
}, 3000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('General upload error:', error);
|
||||
uploadStatus.innerHTML = `<span class="text-red-500">Upload failed: ${error.message}</span>`;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
queryForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
// Add your query logic here
|
||||
const query = queryInput.value.trim();
|
||||
|
||||
if (!query) {
|
||||
queryResponse.innerHTML = '<p class="text-red-500">Please enter a query</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
queryResponse.innerHTML = `
|
||||
<div class="animate-pulse">
|
||||
<div class="flex items-center space-x-2">
|
||||
<svg class="animate-spin h-5 w-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<span class="text-slate-600">Processing your query...</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
try {
|
||||
console.log('Sending query:', query);
|
||||
|
||||
const response = await fetch('/query', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${localStorage.getItem('apiKey') || ''}`
|
||||
},
|
||||
body: JSON.stringify({ query })
|
||||
});
|
||||
|
||||
console.log('Response status:', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(`Query failed: ${errorData.detail || response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Query response:', data);
|
||||
|
||||
// Format and display the response
|
||||
if (data.response) {
|
||||
// Use marked.js to render markdown
|
||||
queryResponse.innerHTML = `
|
||||
<div class="prose prose-slate max-w-none">
|
||||
${marked.parse(data.response)}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
queryResponse.innerHTML = '<p class="text-slate-600">No response data received</p>';
|
||||
}
|
||||
|
||||
// Optional: Add sources if available
|
||||
if (data.sources && data.sources.length > 0) {
|
||||
const sourcesHtml = `
|
||||
<div class="mt-4 pt-4 border-t border-slate-200">
|
||||
<h4 class="text-sm font-medium text-slate-700 mb-2">Sources:</h4>
|
||||
<ul class="text-sm text-slate-600 space-y-1">
|
||||
${data.sources.map(source => `
|
||||
<li class="flex items-center space-x-2">
|
||||
<svg class="w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
<span>${source}</span>
|
||||
</li>
|
||||
`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
queryResponse.insertAdjacentHTML('beforeend', sourcesHtml);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Query error:', error);
|
||||
queryResponse.innerHTML = `
|
||||
<div class="text-red-500 space-y-2">
|
||||
<p class="font-medium">Error processing query:</p>
|
||||
<p class="text-sm">${error.message}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Optional: Add a copy button for the response
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.className = 'mt-4 px-3 py-1 text-sm text-slate-600 hover:text-slate-800 border border-slate-300 rounded hover:bg-slate-50 transition-colors';
|
||||
copyButton.innerHTML = `
|
||||
<span class="flex items-center space-x-1">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span>Copy Response</span>
|
||||
</span>
|
||||
`;
|
||||
copyButton.onclick = () => {
|
||||
const textToCopy = queryResponse.textContent;
|
||||
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||
copyButton.innerHTML = `
|
||||
<span class="flex items-center space-x-1">
|
||||
<svg class="w-4 h-4 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span>Copied!</span>
|
||||
</span>
|
||||
`;
|
||||
setTimeout(() => {
|
||||
copyButton.innerHTML = `
|
||||
<span class="flex items-center space-x-1">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span>Copy Response</span>
|
||||
</span>
|
||||
`;
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
queryResponse.appendChild(copyButton);
|
||||
});
|
||||
|
||||
|
||||
// Modal Controls
|
||||
$('#settingsBtn').addEventListener('click', () => settingsModal.classList.remove('hidden'));
|
||||
$('#settingsBtn').addEventListener('click', () => settingsModal.classList.remove('hidden'));
|
||||
|
Reference in New Issue
Block a user