frontend: add admin settings page for base URL configuration

Phase 2: Create admin UI for system configuration

- Add new /admin/settings route in frontend.go (protected by AdminMiddleware)
- Create admin_settings.templ with HTMX-powered form for base URL
- Add Settings link to admin sidebar navigation
- Admin settings form submits via HTMX to PUT /api/system/config
- Success message displays after save with updated form

The settings page allows admins to configure the base URL used for
device sync URLs, OPDS endpoints, and API access.
This commit is contained in:
2026-03-11 16:41:45 -04:00
parent 5451e82b2d
commit c1b664dbe5
4 changed files with 247 additions and 2 deletions
+74
View File
@@ -0,0 +1,74 @@
package templates
templ AdminSettings(user User, systemConfig map[string]string, errorMessage string) {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>System Settings - Bookhoard</title>
<script src="/static/htmx.min.js"></script>
<script src="/static/main.js"></script>
<link href="/static/style.css" rel="stylesheet"/>
</head>
<body class="theme-{ user.Theme }" x-data="adminSettings">
@Header(user, "/admin/settings")
<div class="flex min-h-screen" style="background-color: var(--bg-primary)">
@AdminSidebar(user, "/admin/settings")
<main class="flex-1 p-8">
<div class="max-w-4xl">
<div class="mb-8">
<div class="flex items-center justify-between mb-4">
<a href="/admin" class="btn-secondary px-4 py-2 rounded-lg font-medium">
Back to Dashboard
</a>
</div>
<h1 class="text-3xl font-bold mb-2" style="color: var(--text-primary)">System Settings</h1>
<p style="color: var(--text-secondary)">Configure your Bookhoard instance</p>
</div>
if errorMessage != "" {
<div class="mb-6 p-4 rounded-lg border" style="background-color: var(--bg-secondary); border-color: var(--error); color: var(--error);">
{ errorMessage }
</div>
}
<form id="settings-form" hx-put="/api/system/config" hx-target="#settings-form" hx-swap="outerHTML">
<div class="card p-6 rounded-lg border" style="background-color: var(--bg-secondary); border-color: var(--border);">
<h3 class="text-xl font-semibold mb-6" style="color: var(--text-primary)">Base URL</h3>
<div>
<label class="block text-sm font-medium mb-2" style="color: var(--text-primary)">Base URL</label>
<input
type="url"
name="base_url"
value={ systemConfig["base_url"] }
placeholder="https://books.example.com"
class="w-full px-4 py-2 rounded-lg border"
style="background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);"
required
/>
<p class="text-sm mt-1" style="color: var(--text-secondary)">The public URL of your Bookhoard instance (e.g., https://books.example.com). Used for device sync, OPDS, and API endpoints.</p>
</div>
<div class="mt-6 flex justify-end">
<button type="submit" class="btn-primary px-6 py-2 rounded-lg font-medium">
Save Settings
</button>
</div>
</div>
</form>
<div class="mt-8 card p-6 rounded-lg border" style="background-color: var(--bg-secondary); border-color: var(--border);">
<h3 class="text-xl font-semibold mb-4" style="color: var(--text-primary)">URL Paths</h3>
<div class="space-y-2 text-sm" style="color: var(--text-secondary);">
<p><strong>OPDS:</strong> { systemConfig["base_url"] }/opds</p>
<p><strong>API:</strong> { systemConfig["base_url"] }/api</p>
<p><strong>Device Sync:</strong> { systemConfig["base_url"] }/api/sync</p>
</div>
</div>
</div>
</main>
</div>
</body>
</html>
}