dana-medical-site/internal/api/adminui/share.js
2026-10-14 13:33:13 +00:00

61 lines
2.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Дашборд по ссылке для маркетолога: та же таблица, что «По неделям» в админке (weekly.js),
только просмотр. Токен — в адресе после «#»: он не уходит на сервер в адресе, в журналы и в Referer;
запрос несёт его в заголовке Authorization. */
const $ = (s) => document.querySelector(s);
const el = (t, p = {}) => Object.assign(document.createElement(t), p);
function toast(msg, bad) {
if (!$('#sh-error').hidden) return; // страница ошибки уже всё сказала
const t = $('#toast');
t.textContent = msg; t.className = 'toast show' + (bad ? ' bad' : '');
setTimeout(() => { t.className = 'toast'; }, 2600);
}
// Клиника приходит с сервера вместе с данными: ссылка привязана к одной клинике.
const ReportClinic = {
key: '',
brand: '',
brands: { dana: 'DANA Medical', ochevidno: 'Очевидно' },
q: (path) => path,
};
const Share = {
token: decodeURIComponent(location.hash.slice(1)),
fail(text) {
$('#sh-main').hidden = true;
$('#sh-error').hidden = false;
if (text) $('#sh-error-text').textContent = text;
},
start() {
WeeklyDashboard.readOnly = true;
if (Share.token.length < 40) { Share.fail(); return; }
$('#sh-main').hidden = false;
for (const b of document.querySelectorAll('.sh-head [data-mode]')) {
b.onclick = () => {
WeeklyDashboard.setMode(b.dataset.mode);
for (const x of document.querySelectorAll('.sh-head [data-mode]')) x.setAttribute('aria-selected', String(x === b));
};
}
WeeklyDashboard.load();
},
};
async function api(path) {
if (path !== '/share/weekly-reports') throw new Error('Недоступно по ссылке');
const r = await fetch('/api/v1/share/weekly-reports', {
headers: { Authorization: 'Bearer ' + Share.token },
credentials: 'omit',
cache: 'no-store',
});
const body = await r.json().catch(() => ({}));
if (r.status === 401) { Share.fail(body.error?.message); throw new Error(body.error?.message || 'Ссылка недействительна'); }
if (!r.ok) throw new Error(body.error?.message || 'Ошибка ' + r.status);
ReportClinic.key = body.meta?.clinic || '';
ReportClinic.brand = ReportClinic.brands[ReportClinic.key] || body.meta?.title || '';
document.title = `${ReportClinic.brand} — маркетинговая аналитика`;
$('#sh-title').textContent = `${ReportClinic.brand} — маркетинговая аналитика`;
return body;
}