feat(router): add routes for consolidated user management
Add DELETE /api/auth/users/:id, PUT /api/auth/users/:id/password, and PUT /api/auth/users/:id routes. Remove individual profile update routes in favor of consolidated endpoints.
This commit is contained in:
+97
-14
@@ -53,7 +53,8 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
e.GET("/login", func(c echo.Context) error {
|
||||
var buf bytes.Buffer
|
||||
sessionExpired := c.QueryParam("session") == "expired"
|
||||
err := templates.Login(sessionExpired).Render(c.Request().Context(), &buf)
|
||||
deleted := c.QueryParam("deleted") == "true"
|
||||
err := templates.Login(sessionExpired, deleted).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -361,6 +362,21 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
})
|
||||
|
||||
// Profile page (all users)
|
||||
frontendProtected.GET("/profile", func(c echo.Context) error {
|
||||
user, err := getTemplateUserWithTheme(c, cfg)
|
||||
if err != nil {
|
||||
return renderErrorPage(c, "Error loading user", "user_load_error")
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = templates.Profile(user).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// ADMIN FRONTEND ROUTES
|
||||
// ============================================================================
|
||||
@@ -392,19 +408,6 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
}))
|
||||
|
||||
frontendProtected.GET("/admin/profile", handlers.AdminMiddleware(func(c echo.Context) error {
|
||||
user, err := getTemplateUserWithTheme(c, cfg)
|
||||
if err != nil {
|
||||
return renderErrorPage(c, "Error loading user", "user_load_error")
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
err = templates.AdminProfile(user).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
}))
|
||||
|
||||
frontendProtected.GET("/admin/library", handlers.AdminMiddleware(func(c echo.Context) error {
|
||||
user, err := getTemplateUserWithTheme(c, cfg)
|
||||
if err != nil {
|
||||
@@ -418,6 +421,86 @@ func registerFrontendRoutes(cfg *Config) {
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
}))
|
||||
|
||||
// Admin users page
|
||||
frontendProtected.GET("/admin/users", handlers.AdminMiddleware(func(c echo.Context) error {
|
||||
user, err := getTemplateUserWithTheme(c, cfg)
|
||||
if err != nil {
|
||||
return renderErrorPage(c, "Error loading user", "user_load_error")
|
||||
}
|
||||
|
||||
// Fetch all users
|
||||
users, err := cfg.Queries.ListUsers(c.Request().Context())
|
||||
if err != nil {
|
||||
return renderErrorPage(c, "Error loading users", "users_load_error")
|
||||
}
|
||||
|
||||
// Count admins for UI protection
|
||||
adminCount := 0
|
||||
for _, u := range users {
|
||||
if u.Role == "admin" {
|
||||
adminCount++
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to template users
|
||||
templateUsers := make([]templates.User, len(users))
|
||||
for i, u := range users {
|
||||
templateUsers[i] = templates.User{
|
||||
ID: uuid.UUID(u.ID.Bytes).String(),
|
||||
Username: u.Username,
|
||||
Email: u.Email,
|
||||
Role: u.Role,
|
||||
Theme: getText(u.Theme),
|
||||
FirstName: getText(u.FirstName),
|
||||
LastName: getText(u.LastName),
|
||||
CreatedAt: u.CreatedAt.Time,
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = templates.AdminUsers(templateUsers, adminCount, user.ID).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
}))
|
||||
|
||||
// Admin: Get profile modal for editing user
|
||||
frontendProtected.GET("/admin/users/:id/profile-modal", handlers.AdminMiddleware(func(c echo.Context) error {
|
||||
// Get target user ID from URL
|
||||
targetUserID := c.Param("id")
|
||||
parsedUUID, err := uuid.Parse(targetUserID)
|
||||
if err != nil {
|
||||
return c.HTML(http.StatusBadRequest, "<div>Invalid user ID</div>")
|
||||
}
|
||||
|
||||
// Fetch target user
|
||||
targetUser, err := cfg.Queries.GetUser(c.Request().Context(), uuidToPGType(parsedUUID))
|
||||
if err != nil {
|
||||
return c.HTML(http.StatusNotFound, "<div>User not found</div>")
|
||||
}
|
||||
|
||||
// Convert to template user
|
||||
templateUser := templates.User{
|
||||
ID: uuid.UUID(targetUser.ID.Bytes).String(),
|
||||
Username: targetUser.Username,
|
||||
Email: targetUser.Email,
|
||||
Role: targetUser.Role,
|
||||
Theme: getText(targetUser.Theme),
|
||||
FirstName: getText(targetUser.FirstName),
|
||||
LastName: getText(targetUser.LastName),
|
||||
CreatedAt: targetUser.CreatedAt.Time,
|
||||
}
|
||||
|
||||
// Render modal
|
||||
var buf bytes.Buffer
|
||||
err = templates.ProfileModal(templateUser).Render(c.Request().Context(), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.HTML(http.StatusOK, buf.String())
|
||||
}))
|
||||
|
||||
// ============================================================================
|
||||
// LEGACY API ROUTES (for backward compatibility)
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user