'use strict';
(function () {
const S = { loaded: false, busy: false };
const byId = (id) => document.getElementById(id);
const el = (tag, cls, text) => window.PA.el(tag, cls, text);
function tr(key, vars) {
return window.PA.t(key, vars);
}
function empty(text) {
return el('p', 'empty small', text);
}
function statItem(label, value) {
const item = el('div', 'dash-stat');
item.appendChild(el('strong', '', String(value)));
item.appendChild(el('span', '', label));
return item;
}
function renderStats(stats) {
const box = byId('dashStats');
box.replaceChildren();
box.appendChild(statItem(tr('dash.projects'), stats.projects || 0));
box.appendChild(statItem(tr('dash.reading'), stats.papers || 0));
box.appendChild(statItem(tr('dash.analyses'), stats.analyses || 0));
box.appendChild(statItem(tr('dash.notes'), stats.notes || 0));
}
function openProject(projectId) {
window.PA.showTab('projects');
if (window.ProjectUI) window.ProjectUI.open(projectId);
}
function projectRow(project) {
const row = el('button', 'dash-row dash-project-row');
row.type = 'button';
const mark = el('span', 'dash-project-mark', project.icon || '◈');
if (project.color) mark.style.color = project.color;
const main = el('span', 'dash-row-main');
main.appendChild(el('strong', '', project.name));
main.appendChild(el('small', '', tr('dash.projectMeta', {
papers: project.paper_count || 0,
questions: project.question_count || 0,
notes: project.note_count || 0
})));
row.appendChild(mark);
row.appendChild(main);
row.appendChild(el('span', 'dash-row-side', project.research_status || 'active'));
row.addEventListener('click', () => openProject(project.id));
return row;
}
function paperRow(paper) {
const row = el('div', 'dash-row');
const main = el('span', 'dash-row-main');
main.appendChild(el('strong', '', paper.title || paper.doi));
main.appendChild(el('small', '', [paper.project_name, paper.journal_key,
(paper.published_date || '').slice(0, 4)].filter(Boolean).join(' · ')));
row.appendChild(main);
if (paper.project_id) {
const open = el('button', 'secondary tiny', tr('dash.open'));
open.type = 'button';
open.addEventListener('click', () => openProject(paper.project_id));
row.appendChild(open);
}
return row;
}
function analysisRow(item) {
const row = el('div', 'dash-row');
const main = el('span', 'dash-row-main');
main.appendChild(el('strong', '', item.title || item.doi));
main.appendChild(el('small', '', [item.journal_key, item.analysis_level,
window.PA.formatDate(item.analysis_at)].filter(Boolean).join(' · ')));
row.appendChild(main);
const open = el('button', 'secondary tiny', tr('dash.view'));
open.type = 'button';
open.addEventListener('click', () => {
if (window.ReviewUI && window.ReviewUI.openAnalysis) {
window.ReviewUI.openAnalysis(item.doi);
}
});
row.appendChild(open);
return row;
}
function noteRow(note) {
const row = el('div', 'dash-row dash-note-row');
const main = el('span', 'dash-row-main');
main.appendChild(el('strong', '', note.title || tr('dash.notes')));
main.appendChild(el('small', '', (note.content_md || '').slice(0, 120)));
row.appendChild(main);
if (note.project_name) row.appendChild(el('span', 'dash-row-side', note.project_name));
return row;
}
function progressRow(item) {
const row = el('div', 'dash-row');
const main = el('span', 'dash-row-main');
main.appendChild(el('strong', '', item.title));
main.appendChild(el('small', '', [item.project_name, item.occurred_at,
item.progress_percent != null ? item.progress_percent + '%' : ''].filter(Boolean).join(' · ')));
row.appendChild(main);
return row;
}
function renderList(id, items, renderer, emptyText) {
const box = byId(id);
box.replaceChildren();
if (!items || !items.length) {
box.appendChild(empty(emptyText));
return;
}
items.forEach((item) => box.appendChild(renderer(item)));
}
async function load() {
if (!S.loaded) return;
if (S.busy) return;
S.busy = true;
try {
const data = await window.PA.api('/api/dashboard');
renderStats(data.stats || {});
renderList('dashProjects', data.projects, projectRow, tr('dash.noProjects'));
renderList('dashReading', data.recent_reading, paperRow, tr('dash.noReading'));
renderList('dashToRead', data.to_read, paperRow, tr('dash.noToRead'));
renderList('dashAnalyses', data.recent_analyses, analysisRow, tr('dash.noAnalyses'));
renderList('dashNotes', data.recent_notes, noteRow, tr('dash.noNotes'));
renderList('dashProgress', data.recent_progress, progressRow, tr('dash.noProgress'));
} catch (error) {
window.PA.toast(error.message);
} finally {
S.busy = false;
}
}
function init() {
if (S.loaded) return;
S.loaded = true;
const newBtn = byId('dashNewProject');
if (newBtn) newBtn.addEventListener('click', () => {
window.PA.showTab('projects');
if (window.ProjectUI) window.ProjectUI.newProject();
});
const refresh = byId('dashRefresh');
if (refresh) refresh.addEventListener('click', load);
}
window.DashboardUI = {
onShow() {
init();
load();
},
onLanguage() {
if (S.loaded) load();
},
refresh: load
};
})();