ReplyFlow / app /static /js /dashboard.js
nvikou's picture
Initial commit
582520a verified
Raw History Blame Contribute Delete
2.78 kB
(() => {
async function loadStats() {
const res = await fetch("/api/dashboard/stats");
const data = await res.json();
document.getElementById("s-total").textContent =
data.total_conversations;
document.getElementById("s-rate").textContent =
`${data.resolution_rate}%`;
document.getElementById("s-appt").textContent =
data.appointments_booked;
document.getElementById("s-hand").textContent = data.handed_off;
document.getElementById("s-unans").textContent =
data.unanswered_count;
document.getElementById("s-leads").textContent =
data.leads_complete;
const unansBody = document.getElementById("unans-body");
unansBody.innerHTML = "";
(data.recent_unanswered || []).forEach((q) => {
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${q.id}</td>
<td>#${q.conversation_id}</td>
<td>${escapeHtml(q.question)}</td>
<td>${formatWhen(q.created_at)}</td>
`;
unansBody.appendChild(tr);
});
}
async function loadConversations() {
const res = await fetch("/api/conversations");
const rows = await res.json();
const body = document.getElementById("conv-body");
body.innerHTML = "";
rows.forEach((c) => {
const status = c.handed_off
? '<span class="badge warn">handoff</span>'
: c.appointment_booked
? '<span class="badge ok">booked</span>'
: `<span class="badge">${c.status}</span>`;
const tr = document.createElement("tr");
tr.innerHTML = `
<td>#${c.id}</td>
<td>${c.channel}</td>
<td>${c.language}</td>
<td>${escapeHtml(c.lead_name || "—")}</td>
<td>${status}</td>
<td>${c.message_count}</td>
<td>${formatWhen(c.created_at)}</td>
<td>
<a href="/api/conversations/${c.id}" target="_blank" rel="noopener">Open</a>
·
<a href="/api/conversations/${c.id}/export">Export CSV</a>
</td>
`;
body.appendChild(tr);
});
}
function formatWhen(value) {
try {
return new Date(value).toLocaleString();
} catch (_) {
return value;
}
}
function escapeHtml(text) {
return String(text)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;");
}
loadStats();
loadConversations();
})();