package templates import "fmt" templ AdminSettings(user User, systemConfig map[string]string, scanSettings ScanSettingsData, liveGroups []SettingGroup, restartGroups []SettingGroup, errorMessage string) { System Settings - Bookhoard @Header(user, "/admin/settings")
@Icon("gear", "h-5 w-5")

System Settings

Configure your Bookhoard instance

if errorMessage != "" {
@Icon("alert", "h-5 w-5 shrink-0 mt-0.5") { errorMessage }
}
@Icon("globe", "h-5 w-5 shrink-0")

Base URL

The public URL of your Bookhoard instance (e.g., https://books.example.com). Used for device sync, OPDS, and API endpoints.

@Icon("clock", "h-5 w-5 shrink-0")

System Defaults

Default timezone for users who haven't set their own.

@Icon("external", "h-5 w-5 shrink-0")

URL Paths

OPDS: { systemConfig["base_url"] }/opds

API: { systemConfig["base_url"] }/api

Device Sync: { systemConfig["base_url"] }/api/sync

@ScanSettingsSection(scanSettings) @TunableSettingsSection(liveGroups, false) @TunableSettingsSection(restartGroups, true)
} templ ScanSettingsSection(scanSettings ScanSettingsData) {
@Icon("refresh", "h-5 w-5 shrink-0")

Scanning

Watch libraries for file changes on startup

How often to poll libraries for changes (1–3600 seconds). Default: 60.

} // TunableSettingsSection renders the editable tunables for a given bucket // (live vs restart-required). Within the card, settings are clustered into // labeled sub-sections by Group (e.g. "Password Quality", "Device Rate Limits"). templ TunableSettingsSection(groups []SettingGroup, restartRequired bool) {
if restartRequired { @Icon("alert", "h-5 w-5 shrink-0")

Tunable Settings — Restart Required

} else { @Icon("settings", "h-5 w-5 shrink-0")

Tunable Settings — Live

}
if restartRequired {

Changes are saved immediately but only take effect after the server restarts.

} else {

Changes apply immediately — no restart needed.

} for _, g := range groups {

{ g.Name }

for _, e := range g.Entries { @TunableSettingRow(e) }
}
} // TunableSettingRow renders a single editable setting as an inline HTMX form. templ TunableSettingRow(e SettingEntry) {
if !e.IsDefault {

{ e.Key } — modified from default

} else {

{ e.Key }

}
if e.Type == "bool" { } else if e.Type == "int" { } else { }
}