A components/adminpartials.templ => components/adminpartials.templ +15 -0
@@ 0,0 1,15 @@
+package components
+
+import "git.src.quest/~skye/felu-ddns/db"
+
+templ AdminPartialsUsersList(users []db.User) {
+ <div class="flex flex-col">
+ for _, user := range users {
+ <div class="flex border p-2">
+ <div>
+ { user.Email }
+ </div>
+ </div>
+ }
+ </div>
+}
A components/adminpartials_templ.go => components/adminpartials_templ.go +55 -0
@@ 0,0 1,55 @@
+// Code generated by templ@(devel) DO NOT EDIT.
+
+package components
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import "context"
+import "io"
+import "bytes"
+
+import "git.src.quest/~skye/felu-ddns/db"
+
+func AdminPartialsUsersList(users []db.User) templ.Component {
+ return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
+ templBuffer, templIsBuffer := w.(*bytes.Buffer)
+ if !templIsBuffer {
+ templBuffer = templ.GetBuffer()
+ defer templ.ReleaseBuffer(templBuffer)
+ }
+ ctx = templ.InitializeContext(ctx)
+ var_1 := templ.GetChildren(ctx)
+ if var_1 == nil {
+ var_1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ _, err = templBuffer.WriteString("<div class=\"flex flex-col\">")
+ if err != nil {
+ return err
+ }
+ for _, user := range users {
+ _, err = templBuffer.WriteString("<div class=\"flex border p-2\"><div>")
+ if err != nil {
+ return err
+ }
+ var var_2 string = user.Email
+ _, err = templBuffer.WriteString(templ.EscapeString(var_2))
+ if err != nil {
+ return err
+ }
+ _, err = templBuffer.WriteString("</div></div>")
+ if err != nil {
+ return err
+ }
+ }
+ _, err = templBuffer.WriteString("</div>")
+ if err != nil {
+ return err
+ }
+ if !templIsBuffer {
+ _, err = templBuffer.WriteTo(w)
+ }
+ return err
+ })
+}
M components/manageadmin.templ => components/manageadmin.templ +2 -0
@@ 14,6 14,8 @@ templ ManageAdminUsers() {
<div>
list of users here, with also the ability to add new users
</div>
+ <div hx-get="/manage/admin/partials/users_list" hx-trigger="load" hx-target="this">
+ </div>
}
}
M components/manageadmin_templ.go => components/manageadmin_templ.go +1 -1
@@ 94,7 94,7 @@ func ManageAdminUsers() templ.Component {
if err != nil {
return err
}
- _, err = templBuffer.WriteString("</div>")
+ _, err = templBuffer.WriteString("</div> <div hx-get=\"/manage/admin/partials/users_list\" hx-trigger=\"load\" hx-target=\"this\"></div>")
if err != nil {
return err
}
M db/users.go => db/users.go +24 -0
@@ 92,3 92,27 @@ func FetchUserWithUlid(ulid string) (*User, error) {
return &user, nil
}
+
+func FetchAllUsers() ([]User, error) {
+ rows, err := DBConn.Query(`SELECT ulid, email, is_admin FROM users`)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ var users []User
+ for rows.Next() {
+ var user User
+ err = rows.Scan(&user.Ulid, &user.Email, &user.IsAdmin)
+ if err != nil {
+ return nil, err
+ }
+ users = append(users, user)
+ }
+ err = rows.Err()
+ if err != nil {
+ return nil, err
+ }
+
+ return users, nil
+}
M felu.go => felu.go +5 -9
@@ 93,15 93,11 @@ func setupFrontendRouter() *gin.Engine {
middlewares.AdminOnly(),
)
{
- manageAdmin.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "", components.ManageAdmin())
- })
- manageAdmin.GET("/users", func(c *gin.Context) {
- c.HTML(http.StatusOK, "", components.ManageAdminUsers())
- })
- manageAdmin.GET("/domains", func(c *gin.Context) {
- c.HTML(http.StatusOK, "", components.ManageAdminDomains())
- })
+ manageAdmin.GET("/", handlers.ManageAdmin())
+ manageAdmin.GET("/users", handlers.ManageAdminUsers())
+ manageAdmin.GET("/domains", handlers.ManageAdminDomains())
+
+ manageAdmin.GET("/partials/users_list", handlers.AdminPartialsUsersList())
}
return r
A handlers/admin.go => handlers/admin.go +32 -0
@@ 0,0 1,32 @@
+/*
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
+ * more information.
+ */
+package handlers
+
+import (
+ "net/http"
+
+ "git.src.quest/~skye/felu-ddns/components"
+ "github.com/gin-gonic/gin"
+)
+
+func ManageAdmin() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ c.HTML(http.StatusOK, "", components.ManageAdmin())
+ }
+}
+
+func ManageAdminUsers() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ c.HTML(http.StatusOK, "", components.ManageAdminUsers())
+ }
+}
+
+func ManageAdminDomains() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ c.HTML(http.StatusOK, "", components.ManageAdminDomains())
+ }
+}
A handlers/adminpartials.go => handlers/adminpartials.go +28 -0
@@ 0,0 1,28 @@
+/*
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for
+ * more information.
+ */
+package handlers
+
+import (
+ "net/http"
+
+ "git.src.quest/~skye/felu-ddns/components"
+ "git.src.quest/~skye/felu-ddns/db"
+ "github.com/gin-gonic/gin"
+)
+
+func AdminPartialsUsersList() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ users, err := db.FetchAllUsers()
+ if err != nil {
+ // TODO: Handle this better
+ c.String(http.StatusInternalServerError, "Something went wrong while fetching users")
+ c.Abort()
+ } else {
+ c.HTML(http.StatusOK, "", components.AdminPartialsUsersList(users))
+ }
+ }
+}