/** * Document Handler Module (PDF, DOCX, DOC) * UPDATED: Updates workflow progress after document load */ function initPdfHandler() { const uploadZone = document.getElementById('uploadZone'); const docInput = document.getElementById('docInput'); if (!uploadZone || !docInput) return; uploadZone.addEventListener('click', (e) => { if (e.target.closest('button')) return; docInput.click(); }); docInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { handleDocumentFile(file); } }); uploadZone.addEventListener('dragover', (e) => { e.preventDefault(); uploadZone.classList.add('drag-over'); }); uploadZone.addEventListener('dragleave', () => { uploadZone.classList.remove('drag-over'); }); uploadZone.addEventListener('drop', (e) => { e.preventDefault(); uploadZone.classList.remove('drag-over'); const files = e.dataTransfer.files; if (files.length > 0) { const file = files[0]; const name = file.name.toLowerCase(); if (name.endsWith('.pdf') || name.endsWith('.docx') || name.endsWith('.doc')) { handleDocumentFile(file); } else { alert('Please drop a valid PDF, DOCX, or DOC file.'); } } }); console.log('📄 Document handler initialized (PDF, DOCX, DOC)'); } function handleDocumentFile(file) { const name = file.name.toLowerCase(); if (name.endsWith('.pdf')) { handlePdfFile(file); } else if (name.endsWith('.docx') || name.endsWith('.doc')) { handleWordFile(file); } else { alert('Unsupported file type. Please upload a PDF, DOCX, or DOC file.'); } } async function handlePdfFile(file) { if (!file.name.toLowerCase().endsWith('.pdf')) { alert('Please select a valid PDF file.'); return; } showLoader('Processing PDF...', `Extracting content from ${file.name}`); const formData = new FormData(); formData.append('file', file); try { const response = await fetch('/api/upload-pdf', { method: 'POST', body: formData }); const data = await response.json(); if (data.error) { throw new Error(data.error); } console.log(`✅ PDF processed: ${data.page_count} pages, ${data.blocks.length} blocks`); const projectName = file.name.replace('.pdf', ''); document.getElementById('projectName').value = projectName; currentProject.name = projectName; renderDocumentBlocks(data.blocks); document.getElementById('uploadSection').style.display = 'none'; document.getElementById('editorSection').style.display = 'block'; hideLoader(); showNotification(`PDF processed: ${data.blocks.length} blocks extracted`, 'success'); updateWorkflowProgress('edit'); } catch (error) { hideLoader(); console.error('PDF processing error:', error); alert('Failed to process PDF: ' + error.message); } } async function handleWordFile(file) { const name = file.name.toLowerCase(); if (!name.endsWith('.docx') && !name.endsWith('.doc')) { alert('Please select a valid DOCX or DOC file.'); return; } const fileType = name.endsWith('.docx') ? 'DOCX' : 'DOC'; showLoader(`Processing ${fileType}...`, `Extracting content from ${file.name}`); const formData = new FormData(); formData.append('file', file); try { const response = await fetch('/api/upload-docx', { method: 'POST', body: formData }); const data = await response.json(); if (data.error) { throw new Error(data.error); } console.log(`✅ ${fileType} processed: ${data.blocks.length} blocks`); const projectName = file.name.replace(/\.(docx|doc)$/i, ''); document.getElementById('projectName').value = projectName; currentProject.name = projectName; renderDocumentBlocks(data.blocks); document.getElementById('uploadSection').style.display = 'none'; document.getElementById('editorSection').style.display = 'block'; hideLoader(); showNotification(`${fileType} processed: ${data.blocks.length} blocks extracted`, 'success'); updateWorkflowProgress('edit'); } catch (error) { hideLoader(); console.error(`${fileType} processing error:`, error); alert(`Failed to process ${fileType}: ` + error.message); } } function renderDocumentBlocks(blocks) { const editor = document.getElementById('markdownEditor'); editor.innerHTML = ''; editorBlocks = []; const emptyMessage = document.getElementById('emptyEditorMessage'); if (emptyMessage) { emptyMessage.style.display = 'none'; } addChapterMarker(1); for (const block of blocks) { let type = 'paragraph'; let content = block.content || ''; if (block.type === 'image') { type = 'image'; } else if (block.type === 'heading1' || content.startsWith('# ')) { type = 'heading1'; } else if (block.type === 'heading2' || content.startsWith('## ')) { type = 'heading2'; } else if (block.type === 'heading3' || content.startsWith('### ')) { type = 'heading3'; } else if (block.type === 'list_item' || content.startsWith('- ')) { type = 'bulletList'; } else if (block.type === 'quote' || content.startsWith('> ')) { type = 'quote'; } else if (block.type === 'table') { type = 'table'; } let images = []; if (block.type === 'image' && block.data) { images = [{ data: block.data, format: block.format || 'png', alt_text: 'Document Image', position: 'before' }]; content = ``; } const lastChild = editor.lastElementChild; const blockId = addBlock(type, content, lastChild, images); if (block.type === 'image' && block.data) { const blockEl = document.getElementById(blockId); if (blockEl) { const contentDiv = blockEl.querySelector('.md-block-content'); if (contentDiv) { contentDiv.innerHTML = `