cms: WYSIWYG-Editor (Toast UI), Profilseite, ziehbare Vorschau, Pill-Optik
- echtes WYSIWYG statt Markdown-Sterne: Formatierung live, speichert Markdown, Bild-Upload via Toolbar. Editor nimmt den meisten Platz, Metadaten kompakt oben. - Vorschau standardmäßig aus (kein toter Raum) + ziehbarer Trenner Editor↔Vorschau. - Profilseite (Nav Inhalte/Profil): Profilbild-Upload + Kurztext, gespeichert als data/authors.json (vom Theme via site.Data.authors nutzbar). - mehr Pill-Optik (Buttons, Suche, Chips), schwarze Topbar-Navigation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import content from './routes/content.js';
|
||||
import preview from './routes/preview.js';
|
||||
import publish from './routes/publish.js';
|
||||
import upload from './routes/upload.js';
|
||||
import profile from './routes/profile.js';
|
||||
import { requireAuth } from './auth.js';
|
||||
|
||||
const SITE_DIR = process.env.SITE_DIR || '/site';
|
||||
@@ -22,6 +23,7 @@ app.route('/api/content', content);
|
||||
app.route('/api/preview', preview);
|
||||
app.route('/api/publish', publish);
|
||||
app.route('/api/upload', upload);
|
||||
app.route('/api/profile', profile);
|
||||
|
||||
// --- Admin-SPA (im Container mitgebaut, unter /admin serviert) ---
|
||||
app.get('/admin', (c) => c.redirect('/admin/'));
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Hono } from 'hono';
|
||||
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
// Profile als Hugo-Data-Datei: data/authors.json (Map E-Mail → Profil).
|
||||
// So kann das Theme die Autor:innen via site.Data.authors rendern.
|
||||
const SITE_DIR = process.env.SITE_DIR || '/site';
|
||||
const FILE = path.join(SITE_DIR, 'data', 'authors.json');
|
||||
|
||||
async function readAll() {
|
||||
try { return JSON.parse(await readFile(FILE, 'utf8')); } catch { return {}; }
|
||||
}
|
||||
|
||||
const profile = new Hono();
|
||||
|
||||
profile.get('/', async (c) => {
|
||||
const email = c.get('user')?.email || 'default';
|
||||
const all = await readAll();
|
||||
return c.json({ email, name: '', bio: '', avatar: '', ...(all[email] || {}) });
|
||||
});
|
||||
|
||||
profile.put('/', async (c) => {
|
||||
const email = c.get('user')?.email || 'default';
|
||||
const { name, bio, avatar } = await c.req.json();
|
||||
const all = await readAll();
|
||||
all[email] = { name: name || '', bio: bio || '', avatar: avatar || '' };
|
||||
await mkdir(path.dirname(FILE), { recursive: true });
|
||||
await writeFile(FILE, JSON.stringify(all, null, 2) + '\n', 'utf8');
|
||||
return c.json({ ok: true });
|
||||
});
|
||||
|
||||
export default profile;
|
||||
Reference in New Issue
Block a user