import { apiAction, toast } from './api.js';
import { initUserPanel } from './ui-user.js';
import { mountLogoutButton, ensureFloatingLogout } from './ui-auth.js';
const state = {
counts: { templates: 0, sections: 0, blocks: 0, snippets: 0, renders_total: 0 },
usage: [],
};
async function ensureAuthenticated() {
try {
const me = await apiAction('auth.me', { method: 'GET' });
if (!me?.ok || !me?.user) {
if (!window.DISABLE_AUTH_REDIRECT) {
window.location.href = '/login.php';
}
return false;
}
window.__currentUser = me.user;
document.documentElement.classList.remove('auth-pending');
return true;
} catch {
return false;
}
}
function ensureAccess() {
const role = (window.__currentUser?.role || '').toLowerCase();
if (role !== 'owner' && role !== 'admin') {
toast('Kein Zugriff auf das Dashboard', false);
window.location.href = '/admin/profile.php';
return false;
}
return true;
}
function renderCounts(counts) {
const mapping = {
templates: 'count-templates',
sections: 'count-sections',
blocks: 'count-blocks',
snippets: 'count-snippets',
renders_total: 'count-usage',
};
Object.entries(mapping).forEach(([key, id]) => {
const el = document.getElementById(id);
if (!el) return;
const value = counts[key] ?? 0;
el.textContent = typeof value === 'number' ? value.toLocaleString('de-DE') : value;
});
}
function formatDate(value) {
if (!value) return '–';
try {
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return date.toLocaleString('de-DE');
} catch {
return value;
}
}
function renderUsage(list) {
const table = document.getElementById('usageTable');
if (!table) return;
const tbody = table.querySelector('tbody');
if (!tbody) return;
if (!list.length) {
tbody.innerHTML = '
| Noch keine Daten vorhanden. |
';
return;
}
tbody.innerHTML = list.map(item => `
| ${escapeHtml(item.name)} |
${item.render_count.toLocaleString('de-DE')} |
${escapeHtml(formatDate(item.last_rendered_at || item.updated_at))} |
|
`).join('');
}
function escapeHtml(str) {
return String(str ?? '')
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
async function loadMetrics() {
try {
const res = await apiAction('dashboard.metrics', { method: 'GET' });
if (!res?.ok) throw new Error(res?.error || 'Dashboard konnte nicht geladen werden');
state.counts = res.counts || state.counts;
state.usage = Array.isArray(res.usage) ? res.usage : [];
renderCounts(state.counts);
renderUsage(state.usage);
} catch (err) {
toast(err.message || 'Fehler beim Laden', false);
}
}
async function resetUsage(templateId) {
try {
await apiAction('dashboard.reset_usage', { method: 'POST', data: { template_id: templateId } });
toast('Zähler zurückgesetzt', true);
await loadMetrics();
} catch (err) {
toast(err.message || 'Zurücksetzen fehlgeschlagen', false);
}
}
function bindEvents() {
const refresh = document.getElementById('btn-refresh-dashboard');
refresh?.addEventListener('click', () => loadMetrics());
const table = document.getElementById('usageTable');
table?.addEventListener('click', ev => {
const btn = ev.target.closest('button[data-reset]');
if (!btn) return;
const id = Number(btn.getAttribute('data-reset'));
if (!id) return;
if (confirm('Zähler für dieses Template wirklich löschen?')) {
resetUsage(id);
}
});
}
document.addEventListener('DOMContentLoaded', async () => {
const ok = await ensureAuthenticated();
if (!ok) return;
if (!ensureAccess()) return;
initUserPanel();
bindEvents();
await loadMetrics();
mountLogoutButton('#btn-logout', { redirect: '/login.php' });
ensureFloatingLogout({ redirect: '/login.php' });
});