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

@@ -890,25 +890,100 @@ async function previewRevisedFile(fileId) {
const file = fileInfo.file;
// Download the file content
const contentResponse = await fetch(`/uploads/revised-notes/${file.filename}`);
// Get file content using the new API endpoint
const contentResponse = await fetch(`/api/revised-files/${fileId}/content`);
if (!contentResponse.ok) {
throw new Error('Failed to load file content');
}
const content = await contentResponse.text();
const contentResult = await contentResponse.json();
if (!contentResult.success) {
throw new Error('Failed to load file content');
}
const content = contentResult.content;
const modal = new bootstrap.Modal(document.getElementById('previewModal'));
// Create preview content with display mode toggle
document.getElementById('preview-content').innerHTML = `
<div class="alert alert-info">
<i class="fas fa-brain me-2"></i>
<strong>AI-Revised Content</strong> • ${file.revisionType} • From: ${file.originalFileName || 'Unknown'}
<div class="d-flex justify-content-between align-items-center mb-3">
<div class="alert alert-info mb-0 flex-grow-1 me-3">
<i class="fas fa-brain me-2"></i>
<strong>AI-Revised Content</strong> • ${file.revisionType} • From: ${file.originalFileName || 'Unknown'}
</div>
<div class="btn-group btn-group-sm" role="group" id="preview-display-mode">
<input type="radio" class="btn-check" name="previewDisplayMode" id="preview-mode-markdown" value="markdown" checked>
<label class="btn btn-outline-secondary" for="preview-mode-markdown" title="Show as Markdown">
<i class="fab fa-markdown"></i>
</label>
<input type="radio" class="btn-check" name="previewDisplayMode" id="preview-mode-html" value="html">
<label class="btn btn-outline-secondary" for="preview-mode-html" title="Render as HTML">
<i class="fas fa-code"></i>
</label>
</div>
</div>
<div class="border p-3 bg-light rounded" style="max-height: 400px; overflow-y: auto;">
<pre style="white-space: pre-wrap; word-wrap: break-word;">${escapeHtml(content)}</pre>
<div id="preview-content-container" class="border p-3 bg-light rounded" style="max-height: 400px; overflow-y: auto;">
<pre style="white-space: pre-wrap; word-wrap: break-word; margin: 0;">${escapeHtml(content)}</pre>
</div>
`;
// Add event listeners for display mode toggle
const modeMarkdown = document.getElementById('preview-mode-markdown');
const modeHtml = document.getElementById('preview-mode-html');
const contentContainer = document.getElementById('preview-content-container');
async function updatePreviewMode() {
const selectedMode = document.querySelector('input[name="previewDisplayMode"]:checked').value;
try {
const renderResponse = await fetch('/api/render-revised-content', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
content: content,
displayMode: selectedMode,
autoDetect: true
})
});
const renderResult = await renderResponse.json();
if (renderResult.success) {
if (selectedMode === 'html') {
let htmlContent = `<div class="rendered-markdown">${renderResult.renderedContent}</div>`;
if (renderResult.isMarkdownContent) {
htmlContent = `
<div class="alert alert-info alert-sm mb-2">
<small><i class="fas fa-info-circle me-1"></i>Markdown formatting detected and rendered</small>
</div>
${htmlContent}
`;
}
contentContainer.innerHTML = htmlContent;
contentContainer.style.backgroundColor = '#ffffff';
} else {
contentContainer.innerHTML = `<pre style="white-space: pre-wrap; word-wrap: break-word; margin: 0;">${escapeHtml(renderResult.renderedContent)}</pre>`;
contentContainer.style.backgroundColor = '#f8f9fa';
}
} else {
throw new Error(renderResult.error || 'Failed to render content');
}
} catch (error) {
console.error('Error rendering preview:', error);
// Fallback to escaped text
contentContainer.innerHTML = `<pre style="white-space: pre-wrap; word-wrap: break-word; margin: 0;">${escapeHtml(content)}</pre>`;
contentContainer.style.backgroundColor = '#f8f9fa';
}
}
modeMarkdown.addEventListener('change', updatePreviewMode);
modeHtml.addEventListener('change', updatePreviewMode);
modal.show();
} catch (error) {
console.error('Error previewing revised file:', error);