| async function correctText() { | |
| const inputText = document.getElementById("inputText").value; | |
| const outputTextElem = document.getElementById("outputText"); | |
| const btn = document.getElementById("submitBtn"); | |
| const loading = document.getElementById("loading"); | |
| const analysisSection = document.getElementById("analysisSection"); | |
| const mode = document.querySelector('input[name="modelType"]:checked').value; | |
| analysisSection.style.display = "none"; | |
| outputTextElem.value = ""; | |
| if (!inputText.trim()) { | |
| document.getElementById("inputText").focus(); | |
| return; | |
| } | |
| btn.disabled = true; | |
| loading.style.display = "flex"; | |
| try { | |
| const response = await fetch('/correct', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ | |
| text: inputText, | |
| mode: mode | |
| }) | |
| }); | |
| const data = await response.json(); | |
| if (data.error) { | |
| outputTextElem.value = "Lỗi: " + data.error; | |
| } else { | |
| outputTextElem.value = data.result; | |
| const alignmentData = data.alignment || []; | |
| renderAnalysis(alignmentData); | |
| analysisSection.style.display = "block"; | |
| setTimeout(() => { | |
| analysisSection.scrollIntoView({ behavior: 'smooth', block: 'start' }); | |
| }, 100); | |
| } | |
| } catch (error) { | |
| outputTextElem.value = "Lỗi kết nối: " + error; | |
| console.error(error); | |
| } finally { | |
| btn.disabled = false; | |
| loading.style.display = "none"; | |
| } | |
| } | |
| function handleModeChange() { | |
| document.getElementById("analysisSection").style.display = "none"; | |
| document.getElementById("outputText").value = ""; | |
| document.getElementById("inputText").focus(); | |
| } | |
| function renderAnalysis(alignmentData) { | |
| const highlightContainer = document.getElementById("highlightedText"); | |
| const tableBody = document.getElementById("comparisonTableBody"); | |
| highlightContainer.innerHTML = ""; | |
| tableBody.innerHTML = ""; | |
| let htmlHighlight = ""; | |
| let hasChange = false; | |
| alignmentData.forEach(item => { | |
| const original = item.original; | |
| const corrected = item.corrected; | |
| const confidence = item.confidence; | |
| const type = item.type; | |
| let scoreText = confidence.toFixed(1) + "%"; | |
| let scoreColor = "#999"; | |
| if (confidence >= 90) scoreColor = "#2e7d32"; | |
| else if (confidence >= 70) scoreColor = "#f57f17"; | |
| else scoreColor = "#c62828"; | |
| if (type === 'equal') { | |
| htmlHighlight += `<span>${original}</span> `; | |
| } | |
| else if (type === 'replace') { | |
| hasChange = true; | |
| htmlHighlight += `<span class="highlight-word" title="Sửa thành: ${corrected} (${scoreText})">${original}</span> `; | |
| addTableRow(tableBody, original, corrected, scoreText, scoreColor); | |
| } | |
| else if (type === 'delete') { | |
| hasChange = true; | |
| htmlHighlight += `<span class="highlight-word" style="text-decoration: line-through; opacity: 0.7;" title="Đã xóa">${original}</span> `; | |
| addTableRow(tableBody, original, "(Xóa)", "-", "#c62828"); | |
| } | |
| else if (type === 'insert') { | |
| hasChange = true; | |
| htmlHighlight += `<span class="highlight-word" style="border-bottom: 2px solid #2e7d32;" title="Thêm mới">[+${corrected}]</span> `; | |
| addTableRow(tableBody, "(Thêm)", corrected, scoreText, scoreColor); | |
| } | |
| }); | |
| highlightContainer.innerHTML = htmlHighlight.trim(); | |
| if (!hasChange) { | |
| tableBody.innerHTML = `<tr><td colspan="3" style="color:#888; text-align:center; padding: 20px;">Văn bản không có thay đổi nào.</td></tr>`; | |
| } | |
| } | |
| function addTableRow(tbody, col1, col2, score, color) { | |
| const row = document.createElement("tr"); | |
| row.innerHTML = ` | |
| <td style="color: #d32f2f;">${col1}</td> | |
| <td style="color: #2e7d32; font-weight:bold;">${col2}</td> | |
| <td style="color: ${color}; font-weight:600;">${score}</td> | |
| `; | |
| tbody.appendChild(row); | |
| } |