/* Дашборд по ссылке для маркетолога: та же таблица, что «По неделям» в админке (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; }