Add HTML & Markdown preview in dashboard and revise pages

This commit is contained in:
inubimambo
2025-07-12 13:53:07 +08:00
parent 51c3c6b577
commit a08f767841
7 changed files with 1653 additions and 207 deletions

View File

@@ -35,7 +35,20 @@
</div>
</div>
<div class="col-md-6">
<h5>AI-Revised Notes</h5>
<div class="d-flex justify-content-between align-items-center mb-2">
<h5>AI-Revised Notes</h5>
<div class="btn-group btn-group-sm" role="group" id="display-mode-toggle" style="display: none;">
<input type="radio" class="btn-check" name="displayMode" id="mode-markdown" value="markdown" checked>
<label class="btn btn-outline-secondary" for="mode-markdown" title="Show as Markdown">
<i class="fab fa-markdown"></i>
</label>
<input type="radio" class="btn-check" name="displayMode" id="mode-html" value="html">
<label class="btn btn-outline-secondary" for="mode-html" title="Render as HTML">
<i class="fas fa-code"></i>
</label>
</div>
</div>
<div id="revised-content" class="border p-3 bg-white rounded" style="height: 400px; overflow-y: auto;">
<p class="text-muted text-center mt-5">Select a revision type and click "Revise" to see AI-enhanced notes here.</p>
</div>
@@ -139,11 +152,72 @@ document.addEventListener('DOMContentLoaded', function() {
const revisionType = document.getElementById('revision-type');
const saveBtn = document.getElementById('save-btn');
const downloadBtn = document.getElementById('download-btn');
const displayModeToggle = document.getElementById('display-mode-toggle');
const modeMarkdown = document.getElementById('mode-markdown');
const modeHtml = document.getElementById('mode-html');
const fileId = '<%= file.id %>';
const content = <%- JSON.stringify(content) %>;
let currentRevisedContent = '';
let currentRevisionType = '';
let currentDisplayMode = 'markdown';
// Handle display mode changes
function updateDisplayMode() {
if (!currentRevisedContent) return;
const selectedMode = document.querySelector('input[name="displayMode"]:checked').value;
currentDisplayMode = selectedMode;
renderRevisedContent(currentRevisedContent, selectedMode);
}
// Render revised content based on display mode
async function renderRevisedContent(content, displayMode = 'markdown') {
try {
const response = await fetch('/api/render-revised-content', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
content: content,
displayMode: displayMode,
autoDetect: true
})
});
const result = await response.json();
if (result.success) {
if (displayMode === 'html') {
// Render as HTML
revisedContent.innerHTML = `<div class="rendered-markdown">${result.renderedContent}</div>`;
// Show format detection info if available
if (result.isMarkdownContent) {
const formatInfo = document.createElement('div');
formatInfo.className = 'alert alert-info alert-sm mb-2';
formatInfo.innerHTML = '<small><i class="fas fa-info-circle me-1"></i>Markdown formatting detected and rendered</small>';
revisedContent.insertBefore(formatInfo, revisedContent.firstChild);
}
} else {
// Show as raw markdown/text
revisedContent.innerHTML = `<pre class="mb-0" style="white-space: pre-wrap; word-wrap: break-word;">${escapeHtml(result.renderedContent)}</pre>`;
}
} else {
throw new Error(result.error || 'Failed to render content');
}
} catch (error) {
console.error('Error rendering content:', error);
// Fallback to escaped text
revisedContent.innerHTML = `<pre class="mb-0" style="white-space: pre-wrap; word-wrap: break-word;">${escapeHtml(content)}</pre>`;
}
}
// Add event listeners for display mode toggle
modeMarkdown.addEventListener('change', updateDisplayMode);
modeHtml.addEventListener('change', updateDisplayMode);
reviseBtn.addEventListener('click', async function() {
const type = revisionType.value;
@@ -153,6 +227,7 @@ document.addEventListener('DOMContentLoaded', function() {
reviseBtn.disabled = true;
revisionProgress.classList.remove('d-none');
displayModeToggle.style.display = 'none'; // Hide toggle during processing
revisedContent.innerHTML = '<div class="text-center mt-5"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Processing...</span></div><p class="mt-2">AI is processing your notes...</p></div>';
try {
@@ -175,9 +250,15 @@ document.addEventListener('DOMContentLoaded', function() {
console.log('Revision result:', result);
if (result.success) {
revisedContent.innerHTML = '<pre class="mb-0" style="white-space: pre-wrap; word-wrap: break-word;">' + escapeHtml(result.revisedContent) + '</pre>';
currentRevisedContent = result.revisedContent;
currentRevisionType = type;
// Show display mode toggle
displayModeToggle.style.display = 'block';
// Render content based on current display mode
await renderRevisedContent(currentRevisedContent, currentDisplayMode);
saveBtn.disabled = false;
downloadBtn.disabled = false;
} else {