app.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. /**
  2. * Dashboard shell. CG-13 builds the Chart.js views on top of this; for now it
  3. * just proves the gated API and the vendored chart library are both reachable.
  4. */
  5. /** Every fetch goes through here so an expired session lands on /login instead
  6. * of failing silently mid-render. */
  7. export async function api(path) {
  8. const response = await fetch(path, { headers: { accept: 'application/json' } });
  9. if (response.status === 401) {
  10. window.location.href = `/login?next=${encodeURIComponent(window.location.pathname)}`;
  11. throw new Error('session expired');
  12. }
  13. if (!response.ok) throw new Error(`${path} responded ${response.status}`);
  14. return response.json();
  15. }
  16. function set(id, text, bad = false) {
  17. const el = document.getElementById(id);
  18. if (!el) return;
  19. el.textContent = text;
  20. el.classList.toggle('bad', bad);
  21. }
  22. set(
  23. 'chart-status',
  24. typeof window.Chart === 'string' || window.Chart === undefined
  25. ? 'Not loaded'
  26. : `Chart.js ${window.Chart.version}`,
  27. window.Chart === undefined,
  28. );
  29. try {
  30. const health = await api('/api/health');
  31. set('db-status', health.ok ? 'Connected' : 'Unavailable', !health.ok);
  32. set('latest-event', health.database?.latest_event_day ?? 'No events yet');
  33. set('latest-rollup', health.database?.latest_rollup_day ?? 'No rollups yet');
  34. } catch (err) {
  35. set('db-status', String(err.message ?? err), true);
  36. }