Frontend update

This commit is contained in:
2026-06-26 21:51:27 -05:00
parent eef79e2403
commit 6dba6a017c
48 changed files with 5004 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
import { useCallback, useState } from 'react'
import { Loading, ErrorState } from '../../../components/PageState.jsx'
import { useAsync } from '../../../lib/useAsync.js'
import { shortDate } from '../../../lib/format.js'
import { api } from '../../../api/client.js'
import WikiEditor from './WikiEditor.jsx'
export default function WikiAdmin() {
const [tick, setTick] = useState(0)
const reload = useCallback(() => setTick((t) => t + 1), [])
const { loading, error, data } = useAsync(() => api.admin.listWiki(), [tick])
const [editing, setEditing] = useState(null) // null | 'new' | slug
const pages = data || []
return (
<section>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 18, flexWrap: 'wrap', gap: 12 }}>
<p className="sans muted" style={{ margin: 0, fontSize: '0.9rem' }}>
{pages.length} page{pages.length === 1 ? '' : 's'} · edit content and structure
</p>
<button onClick={() => setEditing('new')} className="btn btn-primary btn-sq">
+ New page
</button>
</div>
{loading && <Loading />}
{error && <ErrorState message="Could not load wiki pages." />}
{!loading && !error && (
<div className="panel-flat">
<table className="adm-table">
<thead>
<tr>
<th className="adm-th">Page</th>
<th className="adm-th">Slug</th>
<th className="adm-th">Updated</th>
<th className="adm-th" />
</tr>
</thead>
<tbody>
{pages.map((w) => (
<tr key={w.slug}>
<td className="adm-td" style={{ color: 'var(--head)' }}>
{w.title}
</td>
<td className="adm-td" style={{ fontFamily: 'ui-monospace,Menlo,monospace', color: 'var(--accent)' }}>
{w.slug}
</td>
<td className="adm-td dim">{shortDate(w.updated_at)}</td>
<td className="adm-td" style={{ textAlign: 'right' }}>
<span className="link-accent" onClick={() => setEditing(w.slug)}>
Edit
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
{editing && (
<WikiEditor
slug={editing === 'new' ? null : editing}
onClose={() => setEditing(null)}
onSaved={() => {
setEditing(null)
reload()
}}
/>
)}
</section>
)
}