import { apiGet, apiDownloadFetch, apiUrl } from '../api.js'; import { canEdit, pageHeaderHTML, showToast } from '../app.js'; let questionnairesList = []; let filterSearch = ''; export async function exportPage() { const app = document.getElementById('app'); app.innerHTML = ` ${pageHeaderHTML('Export Data')}
`; try { const data = await apiGet('questionnaires.php'); questionnairesList = data.questionnaires || []; renderExport(); } catch (e) { showToast(e.message, 'error'); document.getElementById('exportContent').innerHTML = `

${esc(e.message)}

`; } } function renderExport() { const container = document.getElementById('exportContent'); if (!questionnairesList.length) { container.innerHTML = `

No questionnaires

Create questionnaires first to export data.

`; return; } const bundleBlock = canEdit() ? `

Export questionnaires (JSON)

Download all questionnaires with questions, answer options, and every translation. Use Import questionnaires on the dashboard to restore this file on another server.

` : ''; container.innerHTML = ` ${bundleBlock}

Download CSV files with client responses (filtered by your role). Use All versions for every upload per client, including cycle, session, and start/finish times.

Questionnaire Version State Questions Completed Actions
`; document.getElementById('exportListSearch').addEventListener('input', (e) => { filterSearch = e.target.value; renderExportTableBody(); }); renderExportTableBody(); wireExportActions(); } function exportRowSearchText(q) { return [q.name, q.questionnaireID, q.version, q.state].filter(Boolean).join(' '); } function renderExportTableBody() { const body = document.getElementById('exportTableBody'); const countEl = document.getElementById('exportListCount'); if (!body) return; const q = filterSearch.trim().toLowerCase(); const filtered = q ? questionnairesList.filter(item => exportRowSearchText(item).toLowerCase().includes(q)) : questionnairesList; if (!filtered.length) { body.innerHTML = ` No questionnaires match `; if (countEl) { countEl.textContent = q ? `0 of ${questionnairesList.length} questionnaires` : ''; } return; } body.innerHTML = filtered.map(item => exportRowHTML(item)).join(''); if (countEl) { countEl.textContent = q ? `${filtered.length} of ${questionnairesList.length} questionnaires` : `${questionnairesList.length} questionnaire${questionnairesList.length === 1 ? '' : 's'}`; } body.querySelectorAll('.export-btn').forEach(btn => { btn.addEventListener('click', onExportCsvClick); }); body.querySelectorAll('.export-btn-all').forEach(btn => { btn.addEventListener('click', onExportAllVersionsClick); }); } function exportRowHTML(q) { return ` ${esc(q.name)} ${esc(q.version || '—')} ${esc(q.state || 'draft')} ${q.questionCount || 0} ${q.completedCount ?? 0} Results `; } function wireExportActions() { document.getElementById('exportBundleBtn')?.addEventListener('click', async () => { const btn = document.getElementById('exportBundleBtn'); btn.disabled = true; const prev = btn.textContent; btn.textContent = 'Preparing…'; try { const res = await apiDownloadFetch(apiUrl('export?bundle=1')); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.error?.message || err.error || 'Export failed'); } const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; const stamp = new Date().toISOString().slice(0, 10); a.download = `questionnaires_bundle_${stamp}.json`; a.click(); URL.revokeObjectURL(url); showToast('Questionnaire bundle downloaded', 'success'); } catch (e) { showToast(e.message, 'error'); } finally { btn.disabled = false; btn.textContent = prev; } }); } async function downloadExportCsv(btn, url, filename) { const res = await apiDownloadFetch(url); if (!res.ok) { const err = await res.json().catch(() => ({ error: 'Download failed' })); throw new Error(err.error?.message || err.error || 'Download failed'); } const blob = await res.blob(); const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = filename; a.click(); URL.revokeObjectURL(blobUrl); } async function onExportCsvClick(ev) { const btn = ev.currentTarget; btn.disabled = true; const prev = btn.textContent; btn.textContent = 'Downloading…'; try { const url = apiUrl(`export?questionnaireID=${encodeURIComponent(btn.dataset.id)}`); await downloadExportCsv(btn, url, `${btn.dataset.name}_v${btn.dataset.version}.csv`); showToast('Download started', 'success'); } catch (e) { showToast(e.message, 'error'); } finally { btn.disabled = false; btn.textContent = prev; } } async function onExportAllVersionsClick(ev) { const btn = ev.currentTarget; btn.disabled = true; const prev = btn.textContent; btn.textContent = 'Downloading…'; try { const url = apiUrl(`export?questionnaireID=${encodeURIComponent(btn.dataset.id)}&allVersions=1`); const stamp = new Date().toISOString().slice(0, 10); await downloadExportCsv(btn, url, `${btn.dataset.name}_all_versions_${stamp}.csv`); showToast('All versions download started', 'success'); } catch (e) { showToast(e.message, 'error'); } finally { btn.disabled = false; btn.textContent = prev; } } function esc(s) { const d = document.createElement('div'); d.textContent = s ?? ''; return d.innerHTML; }