DEVELOPMENT ENVIRONMENT

~liljamo/felu

712c650d76f4607e50f58721b0a7fc050971cb75 — Jonni Liljamo 11 months ago 0ef60cd
feat: first partial, for showing all users in the admin view
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))
		}
	}
}