Feature: Moderation SLA — Altersanzeige + Overdue-Alarm täglich 12:00, SW by-v591
This commit is contained in:
parent
87039994ce
commit
d00284184b
4 changed files with 113 additions and 6 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '590'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '591'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VERSION = '1.2.1'; // ← semantische Version, wird bei make release gesetzt
|
||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||
|
||||
|
|
|
|||
|
|
@ -1460,6 +1460,19 @@ window.Page_admin = (() => {
|
|||
// ------------------------------------------------------------------
|
||||
// TAB: MODERATION
|
||||
// ------------------------------------------------------------------
|
||||
function _ageLabel(createdAt) {
|
||||
if (!createdAt) return '';
|
||||
const h = (Date.now() - new Date(createdAt + 'Z').getTime()) / 3600000;
|
||||
const overdue = h >= 24;
|
||||
const label = h < 1 ? '<1h' : h < 24 ? `${Math.floor(h)}h` : `${Math.floor(h/24)}d ${Math.floor(h%24)}h`;
|
||||
return `<span style="font-size:var(--text-xs);font-weight:700;padding:1px 7px;border-radius:999px;
|
||||
margin-left:6px;${overdue
|
||||
? 'background:#fef2f2;color:#dc2626;border:1px solid #fca5a5'
|
||||
: 'background:var(--c-surface-2);color:var(--c-text-muted);border:1px solid var(--c-border)'}">
|
||||
${overdue ? '⚠️ ' : ''}${label}
|
||||
</span>`;
|
||||
}
|
||||
|
||||
function _historySection(label, items, renderItem) {
|
||||
const id = `hist-${label.replace(/\W/g,'').toLowerCase()}`;
|
||||
return `
|
||||
|
|
@ -1560,7 +1573,7 @@ window.Page_admin = (() => {
|
|||
html += `<div class="card adm-table-card" style="margin-bottom:var(--space-3)"><div class="adm-table-scroll"><table class="adm-table">
|
||||
<thead><tr style="background:var(--c-surface-2);text-align:left">
|
||||
<th class="adm-th">Rasse</th><th class="adm-th">Name / Zwingername</th>
|
||||
<th class="adm-th">Ort</th><th class="adm-th">VDH</th><th class="adm-th">Website</th><th class="adm-th"></th>
|
||||
<th class="adm-th">Ort</th><th class="adm-th">VDH</th><th class="adm-th">Alter</th><th class="adm-th">Website</th><th class="adm-th"></th>
|
||||
</tr></thead><tbody>
|
||||
${zuchterPending.map((z, i) => `
|
||||
<tr style="${i%2===1?'background:var(--c-surface-2)':''}">
|
||||
|
|
@ -1568,6 +1581,7 @@ window.Page_admin = (() => {
|
|||
<td class="adm-td">${_esc(z.name)}${z.zwingername ? `<br><span style="color:var(--c-text-muted);font-size:var(--text-xs)">${_esc(z.zwingername)}</span>` : ''}</td>
|
||||
<td class="adm-td">${_esc([z.plz, z.ort, z.bundesland].filter(Boolean).join(' '))}</td>
|
||||
<td class="adm-td">${z.vdh_mitglied ? `<span style="color:var(--c-success);display:flex;align-items:center;gap:2px"><svg class="ph-icon" style="width:14px;height:14px" aria-hidden="true"><use href="/icons/phosphor.svg#check"></use></svg> VDH</span>` : '—'}</td>
|
||||
<td class="adm-td">${_ageLabel(z.created_at)}</td>
|
||||
<td class="adm-td">${z.website ? `<a href="${_esc(z.website)}" target="_blank" style="color:var(--c-primary);font-size:var(--text-xs)">Link</a>` : '—'}</td>
|
||||
<td class="adm-td" style="text-align:right;white-space:nowrap">
|
||||
<button class="btn btn-sm btn-primary adm-zuchter-approve" data-id="${z.id}" style="margin-right:4px"><svg class="ph-icon" style="width:14px;height:14px" aria-hidden="true"><use href="/icons/phosphor.svg#check"></use></svg> Freigeben</button>
|
||||
|
|
@ -1599,7 +1613,8 @@ window.Page_admin = (() => {
|
|||
<img src="${_esc(f.foto_url)}" alt=""
|
||||
style="width:100%;height:140px;object-fit:cover;border-radius:var(--radius-md);margin-bottom:var(--space-3)">
|
||||
<div style="font-weight:var(--weight-semibold);font-size:var(--text-sm)">${_esc(f.rasse_name)}</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-bottom:var(--space-3)">von ${_esc(f.user_name)}</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-bottom:var(--space-2)">von ${_esc(f.user_name)}</div>
|
||||
<div style="margin-bottom:var(--space-3)">${_ageLabel(f.created_at)}</div>
|
||||
${f.aktuell_foto ? `<img src="${_esc(f.aktuell_foto)}" alt="Aktuell"
|
||||
style="width:100%;height:80px;object-fit:cover;border-radius:var(--radius-sm);
|
||||
opacity:.5;margin-bottom:var(--space-2)">
|
||||
|
|
@ -1637,8 +1652,9 @@ window.Page_admin = (() => {
|
|||
<div class="card" style="padding:var(--space-4);border-left:3px solid var(--c-danger)">
|
||||
<div style="display:flex;align-items:flex-start;gap:var(--space-3)">
|
||||
<div style="flex:1;min-width:0">
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-bottom:var(--space-1)">
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-bottom:var(--space-1);display:flex;align-items:center;flex-wrap:wrap;gap:4px">
|
||||
${_esc(r.target_type)} #${r.target_id} · Gemeldet von <strong>${_esc(r.melder_name || '?')}</strong>
|
||||
${_ageLabel(r.created_at)}
|
||||
</div>
|
||||
<div style="font-size:var(--text-sm);font-weight:var(--weight-semibold);margin-bottom:var(--space-1)">
|
||||
Grund: ${_esc(r.grund)}
|
||||
|
|
@ -1682,6 +1698,7 @@ window.Page_admin = (() => {
|
|||
<th class="adm-th">Alt</th>
|
||||
<th class="adm-th">Neu</th>
|
||||
<th class="adm-th">Von</th>
|
||||
<th class="adm-th">Alter</th>
|
||||
<th class="adm-th"></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
|
|
@ -1692,6 +1709,7 @@ window.Page_admin = (() => {
|
|||
<td class="adm-td" style="color:var(--c-text-muted);font-size:var(--text-xs)">${_esc(e.old_value || '—')}</td>
|
||||
<td class="adm-td" style="font-size:var(--text-xs)">${_esc(e.new_value || '—')}</td>
|
||||
<td class="adm-td" style="color:var(--c-text-muted)">${_esc(e.einreicher_name || '?')}</td>
|
||||
<td class="adm-td">${_ageLabel(e.created_at)}</td>
|
||||
<td class="adm-td" style="text-align:right;white-space:nowrap">
|
||||
<button class="btn btn-sm btn-primary adm-poi-approve" data-id="${e.id}" style="margin-right:4px">
|
||||
${UI.icon('check')}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue