- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
152 lines
5.3 KiB
JavaScript
152 lines
5.3 KiB
JavaScript
/**
|
|
* Test script for JavaScript upload functionality
|
|
*/
|
|
import uploadManager, { FileValidator } from './utils/upload.js';
|
|
|
|
// Wait for DOM to be ready
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const fileInput = document.getElementById('test-upload');
|
|
const uploadButton = document.getElementById('upload-button');
|
|
const progressBar = document.getElementById('progress-bar');
|
|
const progressText = document.getElementById('progress-text');
|
|
const results = document.getElementById('results');
|
|
|
|
if (!fileInput || !uploadButton) {
|
|
console.log('Upload test elements not found on this page');
|
|
return;
|
|
}
|
|
|
|
uploadButton.addEventListener('click', async () => {
|
|
const files = Array.from(fileInput.files);
|
|
|
|
if (files.length === 0) {
|
|
showMessage('Please select at least one file', 'error');
|
|
return;
|
|
}
|
|
|
|
// Validate files
|
|
for (const file of files) {
|
|
const errors = FileValidator.validateImage(file);
|
|
if (errors.length > 0) {
|
|
showMessage(`File ${file.name}: ${errors.join(', ')}`, 'error');
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
uploadButton.disabled = true;
|
|
showMessage('Starting upload...', 'info');
|
|
|
|
if (files.length === 1) {
|
|
// Single file upload
|
|
await uploadSingleFile(files[0]);
|
|
} else {
|
|
// Multiple file upload
|
|
await uploadMultipleFiles(files);
|
|
}
|
|
|
|
} catch (error) {
|
|
showMessage(`Upload failed: ${error.message}`, 'error');
|
|
} finally {
|
|
uploadButton.disabled = false;
|
|
progressBar.style.width = '0%';
|
|
progressText.textContent = '';
|
|
}
|
|
});
|
|
|
|
async function uploadSingleFile(file) {
|
|
const result = await uploadManager.uploadImage(file, {
|
|
altText: `Uploaded image: ${file.name}`,
|
|
onProgress: (percent, loaded, total) => {
|
|
updateProgress(percent, `Uploading ${file.name}...`);
|
|
}
|
|
});
|
|
|
|
showUploadResult(result, file.name);
|
|
}
|
|
|
|
async function uploadMultipleFiles(files) {
|
|
const results = await uploadManager.uploadMultipleImages(files, {
|
|
onProgress: (overallPercent, currentIndex, totalFiles) => {
|
|
updateProgress(overallPercent, `Uploading file ${currentIndex + 1} of ${totalFiles}...`);
|
|
},
|
|
onFileComplete: (result, index, total) => {
|
|
showMessage(`Completed ${index + 1}/${total}: ${files[index].name}`, 'success');
|
|
}
|
|
});
|
|
|
|
showMessage(`Upload completed. ${results.filter(r => r.success).length}/${results.length} files successful`, 'info');
|
|
|
|
results.forEach(result => {
|
|
showUploadResult(result.success ? result.data : null, result.file, result.error);
|
|
});
|
|
}
|
|
|
|
function updateProgress(percent, text) {
|
|
progressBar.style.width = `${percent}%`;
|
|
progressText.textContent = `${text} (${Math.round(percent)}%)`;
|
|
}
|
|
|
|
function showMessage(message, type = 'info') {
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.className = `message message-${type}`;
|
|
messageDiv.textContent = message;
|
|
|
|
results.insertBefore(messageDiv, results.firstChild);
|
|
|
|
// Remove after 5 seconds
|
|
setTimeout(() => {
|
|
if (messageDiv.parentNode) {
|
|
messageDiv.remove();
|
|
}
|
|
}, 5000);
|
|
}
|
|
|
|
function showUploadResult(uploadData, fileName, error = null) {
|
|
const resultDiv = document.createElement('div');
|
|
resultDiv.className = 'upload-result';
|
|
|
|
if (error) {
|
|
resultDiv.innerHTML = `
|
|
<h4>❌ ${fileName}</h4>
|
|
<p class="error">Error: ${error}</p>
|
|
`;
|
|
} else {
|
|
resultDiv.innerHTML = `
|
|
<h4>✅ ${fileName}</h4>
|
|
<div class="result-details">
|
|
<p><strong>ULID:</strong> ${uploadData.ulid}</p>
|
|
<p><strong>Filename:</strong> ${uploadData.filename}</p>
|
|
<p><strong>Size:</strong> ${uploadData.file_size.human_readable}</p>
|
|
<p><strong>Dimensions:</strong> ${uploadData.dimensions.width}x${uploadData.dimensions.height}</p>
|
|
<p><strong>MIME Type:</strong> ${uploadData.mime_type}</p>
|
|
<img src="${uploadData.thumbnail_url}" alt="${uploadData.alt_text}" style="max-width: 150px; margin-top: 10px;">
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
results.appendChild(resultDiv);
|
|
}
|
|
});
|
|
|
|
// Test CSRF token functionality
|
|
async function testCsrfTokens() {
|
|
try {
|
|
console.log('Testing CSRF token generation...');
|
|
const tokens = await uploadManager.getCsrfTokens('/api/images', 'post');
|
|
console.log('CSRF tokens received:', {
|
|
form_id: tokens.form_id,
|
|
token: tokens.token.substring(0, 10) + '...',
|
|
headers: tokens.headers
|
|
});
|
|
return tokens;
|
|
} catch (error) {
|
|
console.error('CSRF token test failed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Make test function available globally for console testing
|
|
window.testCsrfTokens = testCsrfTokens;
|
|
window.uploadManager = uploadManager;
|
|
window.FileValidator = FileValidator; |