Files
Void-Homelab/public/views/page.js
root 16f2083253 feat(ui): blackflame theming pass — edit toggle, md tables, back button, Little Blue action cards
- markdown_editor Edit toggle uses themed ghost button
- .md-preview gets full blackflame styling incl. tables (migrated BookStack tables now render as tables)
- reusable back button on page/reference/project/resource reading views
- Little Blue actions regrouped into themed cards, pairing Start/Stop per guest

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 23:02:32 +10:00

59 lines
1.8 KiB
JavaScript

// Page view: header + markdown editor + backlinks panel.
import { api } from '../api.js';
import { el, mount } from '../dom.js';
import { markdownEditor } from '../components/markdown_editor.js';
import { backButton } from '../components/backbtn.js';
export async function render(main, ctx) {
const id = ctx.params.id;
mount(main, el('p', { class: 'view-sub muted' }, 'Loading …'));
let page;
try { page = await api.get('/api/pages/' + id); }
catch (e) {
mount(main,
el('h1', { class: 'view-h1' }, 'Page not found'),
el('p', { class: 'view-sub muted' }, e.message)
);
return;
}
const editor = markdownEditor({
initial: page.body_md || '',
save: (value) => api.patch('/api/pages/' + id, { body_md: value })
});
const backlinksCard = el('div', { class: 'card' },
el('h3', {}, 'Backlinks'),
el('div', { id: 'backlinks-list' }, el('span', { class: 'muted' }, 'Loading …'))
);
mount(main,
backButton(),
el('h1', { class: 'view-h1' }, page.title),
el('p', { class: 'view-sub muted' }, '/' + page.slug),
editor,
backlinksCard
);
try {
const links = await api.get('/api/pages/' + id + '/backlinks');
const list = document.getElementById('backlinks-list');
if (!links.length) mount(list, el('span', { class: 'muted' }, 'No backlinks yet.'));
else mount(list,
el('ul', { class: 'plain' }, links.map(l =>
el('li', {},
el('span', { class: 'status idle' }, l.from_type),
' ',
l.source_title || el('span', { class: 'muted' }, '(untitled)'),
' ',
el('span', { class: 'muted', style: { fontSize: '11px' } }, 'rel: ' + l.relation)
)
))
);
} catch (e) {
const list = document.getElementById('backlinks-list');
if (list) mount(list, el('span', { class: 'muted' }, 'Could not load: ' + e.message));
}
}