NextWks/src/core/admin/ui.go

117 lines
3.5 KiB
Go

package admin
import (
"net/http"
"git.lohmar.co.uk/lexton-it/NextWks/core/admin/templates"
)
// RegisterUIRoutes mounts the admin UI (Templ-rendered) routes.
func (h *Handler) RegisterUIRoutes(mux *http.ServeMux, authMiddleware func(http.Handler) http.Handler) {
// Admin dashboard page
mux.Handle("GET /admin", authMiddleware(http.HandlerFunc(h.adminDashboard)))
mux.Handle("GET /admin/", authMiddleware(http.HandlerFunc(h.adminDashboard)))
mux.Handle("GET /admin/users", authMiddleware(http.HandlerFunc(h.adminUsers)))
mux.Handle("GET /admin/users/create-form", authMiddleware(http.HandlerFunc(h.createUserForm)))
mux.Handle("GET /admin/users/cancel-form", authMiddleware(http.HandlerFunc(h.cancelForm)))
}
func (h *Handler) adminDashboard(w http.ResponseWriter, r *http.Request) {
// Count users for the dashboard
count, _ := h.store.Count()
component := templates.Dashboard(count)
component.Render(r.Context(), w)
}
func (h *Handler) adminUsers(w http.ResponseWriter, r *http.Request) {
component := templates.UserDashboard()
component.Render(r.Context(), w)
}
func (h *Handler) createUserForm(w http.ResponseWriter, r *http.Request) {
component := templates.CreateUserForm()
component.Render(r.Context(), w)
}
func (h *Handler) cancelForm(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(""))
}
// UserToRow converts a User model to a template UserRow.
func UserToRow(u User) templates.UserRow {
return templates.UserRow{
Username: u.Username,
DisplayName: u.DisplayName,
Email: u.Email,
Groups: u.Groups,
Disabled: u.Disabled,
}
}
// userRowsHandler returns user rows for HTMX partial updates.
func (h *Handler) userRowsHandler(w http.ResponseWriter, r *http.Request) {
users, err := h.store.List()
if err != nil {
http.Error(w, "failed to load users", http.StatusInternalServerError)
return
}
rows := make([]templates.UserRow, 0, len(users))
for _, u := range users {
rows = append(rows, UserToRow(u))
}
component := templates.UserRows(rows)
component.Render(r.Context(), w)
}
// createUsersHandler processes the form submission via HTMX.
func (h *Handler) createUsersHandler(w http.ResponseWriter, r *http.Request) {
// Parse form data
if err := r.ParseForm(); err != nil {
http.Error(w, "invalid form data", http.StatusBadRequest)
return
}
username := r.FormValue("username")
displayName := r.FormValue("display_name")
email := r.FormValue("email")
groups := r.FormValue("groups")
req := CreateUserRequest{
Users: []CreateUserInput{
{
Username: username,
DisplayName: displayName,
Email: email,
Groups: groups,
},
},
}
results := h.store.Create(req)
// Sync to Authelia YAML
h.syncWriter.Sync()
// Convert to template results
resultRows := make([]templates.CreateUserResultRow, 0, len(results))
for _, r := range results {
resultRows = append(resultRows, templates.CreateUserResultRow{
Username: r.Username,
GeneratedPassword: r.GeneratedPassword,
Error: r.Error,
})
}
component := templates.CreateUserSuccess(resultRows)
component.Render(r.Context(), w)
}
// RegisterHTMXRoutes mounts the HTMX partial-update endpoints.
func (h *Handler) RegisterHTMXRoutes(mux *http.ServeMux, authMiddleware func(http.Handler) http.Handler) {
// HTMX returns HTML fragments, not full pages
mux.Handle("GET /admin/users/list", authMiddleware(http.HandlerFunc(h.userRowsHandler)))
mux.Handle("POST /admin/users/create", authMiddleware(http.HandlerFunc(h.createUsersHandler)))
}