feat: add HTML preview pane for templates via Carbone+LibreOffice
This commit is contained in:
@@ -96,7 +96,7 @@ async function loadCarboneTemplates() {
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// RENDER SAMPLE CV
|
||||
// RENDER SAMPLE CV (download PDF)
|
||||
// ============================================================
|
||||
async function renderSampleCV(templateId) {
|
||||
toast('Generating sample CV PDF...');
|
||||
@@ -137,6 +137,49 @@ async function renderSampleCV(templateId) {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// PREVIEW TEMPLATE (inline HTML preview)
|
||||
// ============================================================
|
||||
async function previewTemplate(templateId) {
|
||||
toast('Generating preview...');
|
||||
|
||||
try {
|
||||
// Get first candidate for sample data
|
||||
const candidatesResp = await fetch('/api/candidates?limit=1');
|
||||
const candidatesData = await candidatesResp.json();
|
||||
let cvData = null;
|
||||
|
||||
if (candidatesData.candidates && candidatesData.candidates.length > 0) {
|
||||
const fullResp = await fetch('/api/candidates/' + candidatesData.candidates[0].id);
|
||||
cvData = await fullResp.json();
|
||||
}
|
||||
|
||||
if (!cvData) {
|
||||
toast('Upload a CV first to preview', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const resp = await fetch(CARBONE_API + '/templates/' + templateId + '/preview', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ candidateData: cvData })
|
||||
});
|
||||
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json();
|
||||
throw new Error(err.error || 'Preview failed');
|
||||
}
|
||||
|
||||
const html = await resp.text();
|
||||
// Show the HTML in a modal with an iframe
|
||||
const body = '<iframe style="width:100%;height:700px;border:1px solid var(--border);border-radius:8px" srcdoc="' + html.replace(/"/g, '"') + '"></iframe>';
|
||||
showModal(body, 'Template Preview', 'large');
|
||||
toast('Preview generated');
|
||||
} catch (e) {
|
||||
toast('Preview failed: ' + e.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// DELETE TEMPLATE
|
||||
// ============================================================
|
||||
@@ -250,7 +293,8 @@ async function loadOnlyofficeTemplates() {
|
||||
</div>
|
||||
<div class="flex gap-8">
|
||||
<button class="btn btn-sm" onclick="openOnlyofficeEditor('${t.id}', '${t.name.replace(/'/g, "\\'")}')">Edit Online</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="renderSampleCV('${t.id}')">Preview PDF</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="previewTemplate('${t.id}')">Preview</button>
|
||||
<button class="btn btn-sm btn-outline" onclick="renderSampleCV('${t.id}')">Download PDF</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="deleteCarboneTemplate('${t.id}')">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -140,6 +140,6 @@
|
||||
<div class="modal-overlay" id="modal-overlay"></div>
|
||||
|
||||
<script src="/static/app.js?v=15"></script>
|
||||
<script src="/static/carbone.js?v=14"></script>
|
||||
<script src="/static/carbone.js?v=15"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user