/** * PDF Survey Importer Module for TPU Survey * Handles PDF upload, smart extraction preview, and saving to database */ let currentPdfSurveyData = null; // ============================================================ // 1. Initial Upload Modal // ============================================================ function showImportPdfModal() { const html = `
💡
ระบบนำเข้าแบบประเมินจาก PDF อัจฉริยะ:
รองรับไฟล์ PDF แบบประเมินภาษาไทย (เช่น เอกสาร Word ที่บันทึกเป็น PDF) ระบบจะช่วยแยก ตอนที่ 1 (ข้อมูลทั่วไป), ตอนที่ 2 (ตารางความพึงพอใจ 5 ระดับ), และ ตอนที่ 3 (ข้อเสนอแนะ) พร้อมให้ตรวจสอบและแก้ไขก่อนบันทึกจริง
📄
คลิกเพื่อเลือกไฟล์ PDF หรือลากไฟล์มาวางที่นี่
รองรับไฟล์ .pdf ขนาดไม่เกิน 20MB
`; const footer = ` `; const modalId = Modal.create('📄 นำเข้าแบบประเมินจากไฟล์ PDF', html, footer, 'modal-lg'); const modalEl = document.getElementById(modalId); if (modalEl) modalEl.id = 'importPdfModal'; initPdfDropZone(); } function initPdfDropZone() { const dropZone = document.getElementById('pdfDropZone'); if (!dropZone) return; ['dragenter', 'dragover'].forEach(eventName => { dropZone.addEventListener(eventName, (e) => { e.preventDefault(); e.stopPropagation(); dropZone.classList.add('drag-over'); }, false); }); ['dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, (e) => { e.preventDefault(); e.stopPropagation(); dropZone.classList.remove('drag-over'); }, false); }); dropZone.addEventListener('drop', (e) => { const dt = e.dataTransfer; const files = dt.files; if (files.length > 0) { const input = document.getElementById('pdfFileInput'); if (input) { input.files = files; handlePdfFileSelected(input); } } }, false); } function handlePdfFileSelected(input) { if (!input.files || input.files.length === 0) return; const file = input.files[0]; if (!file.name.toLowerCase().endsWith('.pdf')) { Toast.error('กรุณาเลือกไฟล์เอกสาร .pdf เท่านั้น'); input.value = ''; return; } const infoBox = document.getElementById('pdfSelectedInfo'); const nameEl = document.getElementById('pdfFileName'); const sizeEl = document.getElementById('pdfFileSize'); const btn = document.getElementById('btnProcessPdf'); if (nameEl) nameEl.textContent = file.name; if (sizeEl) sizeEl.textContent = (file.size / (1024 * 1024)).toFixed(2) + ' MB'; if (infoBox) infoBox.style.display = 'flex'; if (btn) btn.disabled = false; } function clearSelectedPdf(e) { if (e) e.stopPropagation(); const input = document.getElementById('pdfFileInput'); if (input) input.value = ''; const infoBox = document.getElementById('pdfSelectedInfo'); if (infoBox) infoBox.style.display = 'none'; const btn = document.getElementById('btnProcessPdf'); if (btn) btn.disabled = true; } // ============================================================ // 2. Upload & Parse PDF // ============================================================ async function processPdfUpload() { const input = document.getElementById('pdfFileInput'); if (!input || !input.files || input.files.length === 0) { Toast.warning('กรุณาเลือกไฟล์ PDF ก่อน'); return; } const btn = document.getElementById('btnProcessPdf'); const processingState = document.getElementById('pdfProcessingState'); const dropZone = document.getElementById('pdfDropZone'); const selectedInfo = document.getElementById('pdfSelectedInfo'); if (btn) btn.disabled = true; if (dropZone) dropZone.style.display = 'none'; if (selectedInfo) selectedInfo.style.display = 'none'; if (processingState) processingState.style.display = 'block'; const formData = new FormData(); formData.append('pdf_file', input.files[0]); try { const res = await API.upload('import_pdf.php?action=parsePdf', formData); if (!res.survey) { throw new Error('ไม่พบโครงสร้างแบบประเมินในไฟล์ PDF'); } currentPdfSurveyData = res.survey; // Close upload modal Modal.hide('importPdfModal'); document.getElementById('importPdfModal')?.remove(); // Show Interactive Preview & Edit Modal showPdfPreviewModal(currentPdfSurveyData); } catch (err) { Toast.error(err.message || 'เกิดข้อผิดพลาดในการประมวลผลไฟล์ PDF'); if (dropZone) dropZone.style.display = 'block'; if (selectedInfo) selectedInfo.style.display = 'flex'; if (processingState) processingState.style.display = 'none'; if (btn) btn.disabled = false; } } // ============================================================ // 3. Interactive Preview & Editor Modal // ============================================================ function showPdfPreviewModal(surveyData) { // Calculate Stats let totalQuestions = 0; let totalHeadings = 0; (surveyData.sections || []).forEach(sec => { totalQuestions += (sec.questions || []).length; (sec.headings || []).forEach(h => { totalHeadings++; totalQuestions += (h.questions || []).length; }); }); let sectionsHtml = ''; (surveyData.sections || []).forEach((sec, sIdx) => { let secBadgeClass = 'badge-primary'; let secBadgeText = 'ตอนที่ ' + (sIdx + 1); if (sec.category === 'general') { secBadgeText += ' (ข้อมูลทั่วไป)'; } else if (sec.category === 'rating') { secBadgeText += ' (เกณฑ์ประเมิน 5 ระดับ)'; } else if (sec.category === 'suggestion') { secBadgeText += ' (ข้อเสนอแนะ)'; } let contentHtml = ''; // Render Headings & Subquestions if (sec.headings && sec.headings.length > 0) { sec.headings.forEach((h, hIdx) => { let questionsList = ''; (h.questions || []).forEach((q, qIdx) => { questionsList += `
${hIdx + 1}.${qIdx + 1} คะแนน 1-5
`; }); contentHtml += `
📌 ด้าน/หมวด:
${questionsList}
`; }); } // Render Direct Questions in this section if (sec.questions && sec.questions.length > 0) { sec.questions.forEach((q, qIdx) => { let optionsBadges = ''; if (q.options && q.options.length > 0) { optionsBadges = `
ตัวเลือก: ${q.options.map(opt => `${escapeHtml(opt)}`).join('')}
`; } let typeLabel = q.question_type === 'text' ? 'ข้อความ/ข้อเสนอแนะ' : (q.options ? 'หลายตัวเลือก (Choice)' : 'คะแนน 1-5'); contentHtml += `
${qIdx + 1}. ${typeLabel}
${optionsBadges}
`; }); } sectionsHtml += `
${secBadgeText}
${contentHtml}
`; }); const html = `
✨ ตรวจสอบความถูกต้องของแบบประเมิน
ระบบสกัดข้อมูลจาก PDF เรียบร้อยแล้ว ท่านสามารถแก้ไขข้อความหรือปรับปรุงคำถามได้โดยตรงในหน้านี้
${surveyData.sections?.length || 0}
ตอน/ส่วน
${totalHeadings}
ด้านประเมิน
${totalQuestions}
ข้อคำถาม
${sectionsHtml}
`; const footer = ` `; const modalId = Modal.create('📄 ตรวจสอบและปรับแต่งแบบประเมินจาก PDF', html, footer, 'modal-xl'); const modalEl = document.getElementById(modalId); if (modalEl) modalEl.id = 'pdfPreviewModal'; } function deletePdfQuestionRow(rowId) { const el = document.getElementById(rowId); if (el) { el.style.opacity = '0'; setTimeout(() => el.remove(), 200); } } function addPdfQuestionToHeading(secIdx, headIdx) { const qText = prompt('พิมพ์ข้อคำถามใหม่:'); if (!qText || !qText.trim()) return; const headCard = document.getElementById(`head_card_${secIdx}_${headIdx}`); if (!headCard) return; const container = headCard.querySelector('.pdf-questions-container'); if (!container) return; const count = container.querySelectorAll('.pdf-q-row').length + 1; const newId = `q_row_${secIdx}_${headIdx}_new_${Date.now()}`; const newRow = document.createElement('div'); newRow.id = newId; newRow.className = 'pdf-q-row'; newRow.style.cssText = 'display:flex;gap:10px;align-items:center;margin-bottom:8px;background:#fff;padding:8px 12px;border-radius:6px;border:1px solid #e2e8f0;'; newRow.innerHTML = ` + คะแนน 1-5 `; container.appendChild(newRow); } // ============================================================ // 4. Confirm & Save to Database // ============================================================ async function submitFinalPdfSurvey() { const titleInput = document.getElementById('pdfPreviewTitle'); const descInput = document.getElementById('pdfPreviewDesc'); const btn = document.getElementById('btnConfirmImportPdf'); const title = titleInput?.value?.trim(); if (!title) { Toast.warning('กรุณาระบุชื่อแบบประเมิน'); titleInput?.focus(); return; } if (!currentPdfSurveyData) { Toast.error('ไม่พบข้อมูลแบบประเมิน'); return; } // Serialize edited fields back into currentPdfSurveyData currentPdfSurveyData.title = title; currentPdfSurveyData.description = descInput?.value?.trim() || ''; // Update section titles document.querySelectorAll('.pdf-sec-title').forEach(el => { const sIdx = parseInt(el.getAttribute('data-sec')); if (currentPdfSurveyData.sections[sIdx]) { currentPdfSurveyData.sections[sIdx].title = el.value.trim(); } }); // Update heading titles & heading questions (currentPdfSurveyData.sections || []).forEach((sec, sIdx) => { if (sec.headings) { sec.headings.forEach((h, hIdx) => { const headTitleEl = document.querySelector(`.pdf-head-title[data-sec="${sIdx}"][data-head="${hIdx}"]`); if (headTitleEl) { h.title = headTitleEl.value.trim(); } // Re-collect active question rows inside this heading const headCard = document.getElementById(`head_card_${sIdx}_${hIdx}`); if (headCard) { const qInputs = headCard.querySelectorAll('.pdf-q-text'); const updatedQuestions = []; qInputs.forEach(qi => { const qVal = qi.value.trim(); if (qVal) { updatedQuestions.push({ question_text: qVal, question_type: 'radio', is_required: 1, options: null, scale_min: 1, scale_max: 5 }); } }); h.questions = updatedQuestions; } }); } // Direct questions in this section if (sec.questions) { const updatedDirect = []; document.querySelectorAll(`.pdf-direct-q-text[data-sec="${sIdx}"]`).forEach(qi => { const qVal = qi.value.trim(); const qIdx = parseInt(qi.getAttribute('data-q')); const originalQ = sec.questions[qIdx] || {}; if (qVal) { updatedDirect.push({ ...originalQ, question_text: qVal }); } }); sec.questions = updatedDirect; } }); if (btn) { btn.disabled = true; btn.textContent = '⏳ กำลังบันทึกแบบประเมินลงฐานข้อมูล...'; } try { const res = await API.post('import_pdf.php?action=confirmImport', { survey_data: currentPdfSurveyData }); Toast.success(res.message || 'สร้างแบบประเมินจาก PDF สำเร็จแล้ว!'); // Close preview modal Modal.hide('pdfPreviewModal'); document.getElementById('pdfPreviewModal')?.remove(); // Refresh surveys list if (typeof loadSurveys === 'function') loadSurveys(); if (typeof loadTeacherSurveys === 'function') loadTeacherSurveys(); // Show Success Action Prompt showImportSuccessPrompt(res.survey_id, res.unique_link, res.title); } catch (err) { Toast.error(err.message || 'เกิดข้อผิดพลาดในการบันทึกแบบประเมิน'); } finally { if (btn) { btn.disabled = false; btn.textContent = '✅ ยืนยันและสร้างแบบประเมินทันที'; } } } function showImportSuccessPrompt(surveyId, link, title) { const fullUrl = `${window.location.origin}${getAppBasePath()}/respond.php?link=${link}`; const editUrl = `${getAppBasePath()}/edit.html?id=${surveyId}`; const html = `
🎉

นำเข้าแบบประเมินสำเร็จเรียบร้อย!

"${escapeHtml(title)}" พร้อมเปิดให้ทำแบบประเมินแล้ว

✏️ ปรับแต่งฟอร์มใน Editor 👁️ ทดลองเปิดทำแบบประเมิน
`; const footer = ` `; const modalId = Modal.create('✨ สำเร็จ', html, footer, 'modal-md'); const modalEl = document.getElementById(modalId); if (modalEl) modalEl.id = 'pdfSuccessModal'; } // Global Window Bindings window.showImportPdfModal = showImportPdfModal; window.handlePdfFileSelected = handlePdfFileSelected; window.clearSelectedPdf = clearSelectedPdf; window.processPdfUpload = processPdfUpload; window.showPdfPreviewModal = showPdfPreviewModal; window.deletePdfQuestionRow = deletePdfQuestionRow; window.addPdfQuestionToHeading = addPdfQuestionToHeading; window.submitFinalPdfSurvey = submitFinalPdfSurvey; window.showImportSuccessPrompt = showImportSuccessPrompt;