/* reports.js — Seção "Relatórios" do dashboard: listagem de comparações salvas e página de detalhe. A renderização de tabelas/gráficos vive em comparison-view.js (componente compartilhado com a pré-visualização da página Benchmarks); este arquivo só busca dados e monta a página. Exposto como ReportsPage.render(container); app.js chama em Pages.reports. */ const ReportsPage = (() => { const esc = UI.escapeHtml; function handleErr(ex) { if (ex && ex.status === 401) { location.reload(); return; } UI.toast("Erro: " + (ex && ex.message ? ex.message : ex), "bad"); } let detailId = null; async function render(container) { if (detailId) return renderDetail(container, detailId); return renderList(container); } // ======================================================================= LISTA async function renderList(container) { container.innerHTML = `
Carregando relatórios…
`; let items; try { const data = await API.reports(); items = data.items || []; } catch (ex) { handleErr(ex); return; } let html = `

Relatórios (${items.length})

Comparativos salvos a partir de benchmarks concluídos.
`; if (!items.length) { html += `
Nenhum relatório ainda. Vá em "Benchmarks", selecione ao menos 2 concluídos e clique em "Comparar".
`; } else { html += `
${items.map(reportRow).join("")}
TítuloDataBenchmarksPerfisResumo
`; } container.innerHTML = html; document.getElementById("rp-reload").onclick = () => renderList(container); container.querySelectorAll("[data-rp-view]").forEach((b) => (b.onclick = () => { detailId = b.dataset.rpView; renderDetail(container, detailId); })); container.querySelectorAll("[data-rp-pdf]").forEach((b) => (b.onclick = () => window.open(API.reportPdfUrl(b.dataset.rpPdf), "_blank", "noopener"))); container.querySelectorAll("[data-rp-del]").forEach((b) => (b.onclick = () => onDelete(container, b.dataset.rpDel, b.dataset.name))); } function reportRow(r) { return ` ${esc(r.title)} ${esc(UI.dt(r.createdAt))} ${r.benchmarkCount} ${(r.profiles || []).map((p) => `${esc(p)}`).join(" ")} ${esc(r.summary || "—")} `; } async function onDelete(container, id, name) { const ok = await UI.confirm({ title: `Remover o relatório "${name}"?`, text: "O relatório e os dados salvos dele são removidos. Os benchmarks que deram origem a ele NÃO são afetados.", confirmLabel: "Remover relatório", danger: true, }); if (!ok) return; try { await API.reportDelete(id); UI.toast("Relatório removido.", "ok"); renderList(container); } catch (ex) { handleErr(ex); } } // ====================================================================== DETALHE async function renderDetail(container, id) { container.innerHTML = `
Carregando relatório…
`; let r; try { r = await API.report(id); } catch (ex) { detailId = null; handleErr(ex); renderList(container); return; } let html = `

${esc(r.title)}

Gerado em ${esc(UI.dt(r.createdAt))} · ${r.benchmarkCount} benchmarks comparados
`; html += ComparisonView.render(r); container.innerHTML = html; document.getElementById("rp-back").onclick = () => { detailId = null; renderList(container); }; document.getElementById("rp-pdf-btn").onclick = () => window.open(API.reportPdfUrl(r.id), "_blank", "noopener"); } return { render }; })();