Files
barometer-server/website/js/pages/home.js
tom.hempel 7fefc264f4
Some checks failed
PHPUnit / test (push) Has been cancelled
session cylces and adjustments
2026-06-29 13:26:08 +02:00

110 lines
4.9 KiB
JavaScript

import { apiGet } from '../api.js';
import { getRole, pageHeaderHTML, showToast } from '../app.js';
export async function homeDashboardPage() {
const app = document.getElementById('app');
const role = getRole();
const isAdmin = role === 'admin';
app.innerHTML = `
${pageHeaderHTML('Overview', '', {
subtitle: `Ressourcenbarometer administration for your ${role === 'admin' ? 'organization' : 'supervised counselors'}`,
})}
<div id="homeDashboardContent"><div class="spinner"></div></div>
`;
try {
const ov = await apiGet('analytics.php?overview=1');
renderHomeDashboard(ov, isAdmin);
} catch (e) {
showToast(e.message, 'error');
document.getElementById('homeDashboardContent').innerHTML =
`<p class="error-text">${esc(e.message)}</p>`;
}
}
function renderHomeDashboard(ov, isAdmin) {
const el = document.getElementById('homeDashboardContent');
const qPreview = (ov.questionnaires || []).slice(0, 6).map(q => `
<tr>
<td>${esc(q.name)}</td>
<td>${q.completedCount ?? 0} / ${q.eligibleCount ?? 0}</td>
<td>${q.completionRatio ?? 0}%</td>
</tr>
`).join('');
const links = [
{ href: '#/sessions', label: 'Sessions', desc: 'Assign session measures to program visits' },
{ href: '#/questionnaires', label: 'Session measures', desc: 'Edit instruments, order, and categories' },
{ href: '#/clients', label: 'Clients', desc: 'Client codes, counselors, response history' },
{ href: '#/coaches', label: 'Counselor activity', desc: 'Uploads and workload per counselor' },
{ href: '#/insights', label: 'Insights', desc: 'Charts, completion rates, follow-up' },
{ href: '#/export', label: 'Export data', desc: 'Download CSV and bundles' },
{ href: '#/assignments', label: 'Assign clients', desc: 'Move clients between counselors' },
{ href: '#/users', label: 'Users', desc: 'Admins, supervisors, and counselors' },
{ href: '#/translations', label: 'Translations', desc: 'German source and other languages' },
];
if (isAdmin) {
links.push({ href: '#/dev', label: 'Admin settings', desc: 'Dev import, exports, database tools' });
}
el.innerHTML = `
<div class="insights-kpi-grid">
<a href="#/clients" class="insights-kpi card home-kpi-link">
<div class="insights-kpi-value">${ov.clientCount ?? 0}</div>
<div class="insights-kpi-label">Clients</div>
</a>
<a href="#/insights" class="insights-kpi card home-kpi-link">
<div class="insights-kpi-value">${ov.clientsWithCompletions ?? 0}</div>
<div class="insights-kpi-label">With completions</div>
</a>
<a href="#/coaches" class="insights-kpi card home-kpi-link">
<div class="insights-kpi-value">${ov.submissionsLast7d ?? 0}</div>
<div class="insights-kpi-label">Uploads (7 days)</div>
</a>
<a href="#/coaches" class="insights-kpi card home-kpi-link">
<div class="insights-kpi-value">${ov.submissionsLast30d ?? 0}</div>
<div class="insights-kpi-label">Uploads (30 days)</div>
</a>
</div>
<div class="card" style="margin-top:20px">
<h3 style="margin:0 0 12px">Quick links</h3>
<div class="home-link-grid">
${links.map(l => `
<a href="${l.href}" class="home-link-card">
<span class="home-link-title">${esc(l.label)}</span>
<span class="home-link-desc">${esc(l.desc)}</span>
</a>
`).join('')}
</div>
</div>
<div class="card" style="margin-top:20px">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
<h3 style="margin:0">Measure completion</h3>
<a href="#/insights" class="btn btn-sm">Full report</a>
</div>
${(ov.questionnaires || []).length ? `
<div class="table-wrapper">
<table class="data-table data-table-compact">
<thead>
<tr><th>Session measure</th><th>Completed</th><th>Rate</th></tr>
</thead>
<tbody>${qPreview}${(ov.questionnaires.length > 6)
? `<tr><td colspan="3" class="data-toolbar-hint" style="text-align:center">+ ${ov.questionnaires.length - 6} more — see Insights</td></tr>`
: ''}</tbody>
</table>
</div>
` : '<p class="data-toolbar-hint">No active session measures.</p>'}
</div>
`;
}
function esc(s) {
const d = document.createElement('div');
d.textContent = s ?? '';
return d.innerHTML;
}