Files
BountyBoard/web/static/js/reviews.js
T
etalon 0d28f69320 feat: 5 dramatic extra themes (neon/terminal/blueprint/sunset) + board/review/layout polish
- Themes: add neon (cyber gradient), terminal (green CRT), blueprint (graph
  paper) and sunset (vaporwave) alongside the default Light (Y2K paper) and
  Dark. Theme toggle now cycles all; profile selector lists them; server
  validates against a shared whitelist.
- Bounty cards now show the project (customer) name.
- Remove the celebratory emoji from the empty Review Queue.
- Full-width h1 underline rule; My Tasks columns stack vertically for more
  room per task; card action buttons wrap/right-align so they never overflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 10:44:07 +02:00

37 lines
1.3 KiB
JavaScript

import { api } from '/static/js/api.js';
import { subscribe, onPollFallback } from '/static/js/ws.js';
const host = document.getElementById('review-list');
const errorBox = document.getElementById('error');
const esc = (s) => String(s ?? '').replace(/[&<>"']/g, (c) => ({
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;',
}[c]));
async function load() {
try {
const res = await api('GET', '/api/v1/consultant/reviews');
host.replaceChildren(...res.tasks.map((t) => {
const card = document.createElement('div');
card.className = 'card';
const who = t.assignee
? (t.assignee.kind === 'ai' ? 'AI work performer' : 'developer')
: 'unknown';
card.innerHTML = `
<div class="spread">
<h3><a href="/tasks/${t.id}">${esc(t.title)}</a></h3>
<span class="badge accent">◈ ${t.bounty}</span>
</div>
<p class="muted">submitted by ${who} · updated ${new Date(t.updatedAt).toLocaleString()}</p>
<a class="btn primary" href="/tasks/${t.id}">Open review</a>`;
return card;
}));
if (!res.tasks.length) {
host.innerHTML = '<p class="muted">Nothing waiting for review.</p>';
}
} catch (e) { errorBox.textContent = e.message; }
}
subscribe('board', () => setTimeout(load, 300));
onPollFallback(load);
load();