more work on the Web Interface
parent
d14f7aaf90
commit
a4b26485ba
|
@ -0,0 +1,46 @@
|
||||||
|
root = "."
|
||||||
|
testdata_dir = "testdata"
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
args_bin = []
|
||||||
|
bin = "./tmp/main"
|
||||||
|
cmd = "go build -o ./tmp/main ."
|
||||||
|
delay = 1000
|
||||||
|
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
|
||||||
|
exclude_file = []
|
||||||
|
exclude_regex = ["_test.go", "_templ.go"]
|
||||||
|
exclude_unchanged = false
|
||||||
|
follow_symlink = false
|
||||||
|
full_bin = ""
|
||||||
|
include_dir = []
|
||||||
|
include_ext = ["go", "tpl", "templ", "html"]
|
||||||
|
include_file = []
|
||||||
|
kill_delay = "0s"
|
||||||
|
log = "build-errors.log"
|
||||||
|
poll = false
|
||||||
|
poll_interval = 0
|
||||||
|
post_cmd = ["rm tmp/main"]
|
||||||
|
pre_cmd = ["templ generate"]
|
||||||
|
rerun = false
|
||||||
|
rerun_delay = 500
|
||||||
|
send_interrupt = false
|
||||||
|
stop_on_error = false
|
||||||
|
|
||||||
|
[color]
|
||||||
|
app = ""
|
||||||
|
build = "yellow"
|
||||||
|
main = "magenta"
|
||||||
|
runner = "green"
|
||||||
|
watcher = "cyan"
|
||||||
|
|
||||||
|
[log]
|
||||||
|
main_only = false
|
||||||
|
time = false
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
clean_on_exit = false
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
clear_on_rebuild = false
|
||||||
|
keep_scroll = true
|
|
@ -4,3 +4,4 @@
|
||||||
.null-ls_*
|
.null-ls_*
|
||||||
a.out
|
a.out
|
||||||
*.sqlite
|
*.sqlite
|
||||||
|
tmp/
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
FROM golang:alpine AS builder
|
FROM golang:alpine AS builder
|
||||||
RUN apk update && apk add --no-cache git
|
RUN apk update && apk add --no-cache git
|
||||||
|
RUN go install github.com/a-h/templ/cmd/templ@latest
|
||||||
|
|
||||||
WORKDIR $GOPATH/src/goipam
|
WORKDIR $GOPATH/src/goipam
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN rm web/templates/*_templ.go
|
||||||
|
RUN templ generate
|
||||||
RUN go get -d -v
|
RUN go get -d -v
|
||||||
RUN go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/goipam
|
RUN go build -a -installsuffix cgo -ldflags="-w -s" -o /go/bin/goipam
|
||||||
|
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -3,8 +3,7 @@ release: deps templ
|
||||||
GIN_MODE=release go build -v -x -buildvcs=true .
|
GIN_MODE=release go build -v -x -buildvcs=true .
|
||||||
|
|
||||||
dev: templ
|
dev: templ
|
||||||
go build .
|
air
|
||||||
./webframework -p=false
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f webframework
|
rm -f webframework
|
||||||
|
@ -12,6 +11,7 @@ clean:
|
||||||
rm -f db.sqlite
|
rm -f db.sqlite
|
||||||
|
|
||||||
templ:
|
templ:
|
||||||
|
rm -f web/templates/*_templ.go
|
||||||
templ fmt .
|
templ fmt .
|
||||||
templ generate
|
templ generate
|
||||||
|
|
||||||
|
|
26
config.go
26
config.go
|
@ -1,9 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
@ -23,9 +26,28 @@ func readConfig() {
|
||||||
viper.SetDefault("web.host", "0.0.0.0")
|
viper.SetDefault("web.host", "0.0.0.0")
|
||||||
viper.SetDefault("web.port", 8080)
|
viper.SetDefault("web.port", 8080)
|
||||||
viper.SetDefault("web.prod", true)
|
viper.SetDefault("web.prod", true)
|
||||||
|
// Database Config
|
||||||
|
viper.SetDefault("db.type", "sqlite")
|
||||||
|
viper.SetDefault("db.host", "localhost")
|
||||||
|
viper.SetDefault("db.user", "dbuser")
|
||||||
|
viper.SetDefault("db.path", "./db.sqlite")
|
||||||
|
viper.SetDefault("db.password", "dbpw")
|
||||||
|
viper.SetDefault("db.port", 5432)
|
||||||
|
viper.SetDefault("db.sslmode", "disable")
|
||||||
|
|
||||||
|
viper.AutomaticEnv()
|
||||||
err = viper.ReadInConfig()
|
err = viper.ReadInConfig()
|
||||||
if err != nil {
|
|
||||||
log.Fatal("err")
|
// If a config file is found, read it in.
|
||||||
|
if err == nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
|
||||||
|
} else {
|
||||||
|
log.Println(err)
|
||||||
|
errString := err.Error()
|
||||||
|
if strings.Contains(errString, "Not Found") {
|
||||||
|
log.Println("could not find config file, creating...")
|
||||||
|
viper.WriteConfigAs(path.Join(executableDir, "goipam.yaml"))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (address *Address) Save() error {
|
||||||
|
if err := conn.Save(address).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (address *Address) Delete() error {
|
||||||
|
if err := conn.Delete(address).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func CountAddresss() int {
|
||||||
|
var count int64
|
||||||
|
err := conn.Model(&Address{}).Count(&count)
|
||||||
|
if err != nil {
|
||||||
|
count = 0
|
||||||
|
log.Println("Error counting addresss: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(count)
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var conn *gorm.DB
|
var conn *gorm.DB
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (device *Device) Save() error {
|
||||||
|
if err := conn.Save(device).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (device *Device) Delete() error {
|
||||||
|
if err := conn.Delete(device).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func CountDevices() int {
|
||||||
|
var count int64
|
||||||
|
err := conn.Model(&Device{}).Count(&count)
|
||||||
|
if err != nil {
|
||||||
|
count = 0
|
||||||
|
log.Println("Error counting devices: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(count)
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
func (location *Location) Save() error {
|
||||||
|
if err := conn.Save(location).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (location *Location) Delete() error {
|
||||||
|
if err := conn.Delete(location).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func CountLocations() int {
|
||||||
|
var count int64
|
||||||
|
err := conn.Model(&Location{}).Count(&count)
|
||||||
|
if err != nil {
|
||||||
|
count = 0
|
||||||
|
log.Println("Error counting locations: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(count)
|
||||||
|
}
|
40
db/models.go
40
db/models.go
|
@ -1,7 +1,9 @@
|
||||||
// Define all Database Models here
|
// Define all Database Models here
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import "gorm.io/gorm"
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
@ -19,3 +21,39 @@ type Group struct {
|
||||||
DisplayName string
|
DisplayName string
|
||||||
Users []User `gorm:"many2many:user_groups"`
|
Users []User `gorm:"many2many:user_groups"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Subnet struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string `grom:"unique;index"`
|
||||||
|
DisplayName string
|
||||||
|
VLAN int
|
||||||
|
IPv4Net string
|
||||||
|
IPv6Net string
|
||||||
|
LocationID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
Comment string
|
||||||
|
Subnets []Subnet
|
||||||
|
}
|
||||||
|
|
||||||
|
type Address struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
Comment string
|
||||||
|
IPv4Address string
|
||||||
|
IPv6Address string
|
||||||
|
MACAddress string
|
||||||
|
DNSName string
|
||||||
|
DeviceID uint
|
||||||
|
SubnetID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
Comment string
|
||||||
|
Addresses []Address
|
||||||
|
}
|
||||||
|
|
10
db/setup.go
10
db/setup.go
|
@ -3,6 +3,7 @@ package db
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"git.jmbit.de/jmb/goipam/utils"
|
"git.jmbit.de/jmb/goipam/utils"
|
||||||
|
@ -13,11 +14,18 @@ func SetupDB() {
|
||||||
ConnectDB()
|
ConnectDB()
|
||||||
var users []User
|
var users []User
|
||||||
var count int64
|
var count int64
|
||||||
|
var err error
|
||||||
|
var adminPW string
|
||||||
conn.Find(&users).Count(&count)
|
conn.Find(&users).Count(&count)
|
||||||
if count >= 1 {
|
if count >= 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
adminPW, err := utils.RandomString(32)
|
if viper.GetString("web.adminpw") != "" {
|
||||||
|
adminPW = viper.GetString("web.adminpw")
|
||||||
|
|
||||||
|
} else {
|
||||||
|
adminPW, err = utils.RandomString(32)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Could not generate admin PW: %v", err)
|
log.Fatalf("Could not generate admin PW: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (subnet *Subnet) Save() error {
|
||||||
|
if err := conn.Save(subnet).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (subnet *Subnet) Delete() error {
|
||||||
|
if err := conn.Delete(subnet).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
func CountSubnets() int {
|
||||||
|
var count int64
|
||||||
|
err := conn.Model(&Subnet{}).Count(&count)
|
||||||
|
if err != nil {
|
||||||
|
count = 0
|
||||||
|
log.Println("Error counting subnets: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(count)
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
db:
|
||||||
|
host: localhost
|
||||||
|
password: dbpw
|
||||||
|
path: ./db.sqlite
|
||||||
|
port: 5432
|
||||||
|
sslmode: disable
|
||||||
|
type: sqlite
|
||||||
|
user: dbuser
|
||||||
|
web:
|
||||||
|
host: 0.0.0.0
|
||||||
|
port: 8080
|
||||||
|
prod: true
|
17
main.go
17
main.go
|
@ -1,5 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func main {
|
import (
|
||||||
readC
|
"log"
|
||||||
|
|
||||||
|
"git.jmbit.de/jmb/goipam/db"
|
||||||
|
"git.jmbit.de/jmb/goipam/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
readConfig()
|
||||||
|
db.SetupDB()
|
||||||
|
db.ConnectDB()
|
||||||
|
err := web.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ func AuthMiddleware(requiredLevel int) gin.HandlerFunc {
|
||||||
metaContent := utils.GenMetaContent(c)
|
metaContent := utils.GenMetaContent(c)
|
||||||
metaContent.ErrorTitle = "Not Authorized"
|
metaContent.ErrorTitle = "Not Authorized"
|
||||||
metaContent.ErrorText = "You are not authorized to do this Action"
|
metaContent.ErrorText = "You are not authorized to do this Action"
|
||||||
c.HTML(http.StatusUnauthorized, "", templates.Index(metaContent))
|
c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login", nil))
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,13 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.jmbit.de/jmb/goipam/db"
|
|
||||||
"git.jmbit.de/jmb/goipam/web/static"
|
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"git.jmbit.de/jmb/goipam/db"
|
||||||
|
"git.jmbit.de/jmb/goipam/web/static"
|
||||||
|
"git.jmbit.de/jmb/goipam/web/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run() error {
|
func Run() error {
|
||||||
|
@ -38,6 +40,7 @@ func setupRouter() *gin.Engine {
|
||||||
}
|
}
|
||||||
router := gin.New()
|
router := gin.New()
|
||||||
router.Use(gin.Recovery())
|
router.Use(gin.Recovery())
|
||||||
|
router.Use(urlLog())
|
||||||
router.Use(sessions.Sessions("session", db.CreateStore()))
|
router.Use(sessions.Sessions("session", db.CreateStore()))
|
||||||
err := router.SetTrustedProxies(viper.GetStringSlice("web.trustedProxies"))
|
err := router.SetTrustedProxies(viper.GetStringSlice("web.trustedProxies"))
|
||||||
router.HTMLRender = &TemplRender{}
|
router.HTMLRender = &TemplRender{}
|
||||||
|
@ -50,6 +53,7 @@ func setupRouter() *gin.Engine {
|
||||||
} else {
|
} else {
|
||||||
router.StaticFS("/static", http.FS(static.StaticFS))
|
router.StaticFS("/static", http.FS(static.StaticFS))
|
||||||
}
|
}
|
||||||
|
router = ui.GroupWeb(router)
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
// NavBar Hamburger Script
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
// columns takes components and arranges them in columns
|
// columns takes components and arranges them in columns
|
||||||
|
|
||||||
templ columns(columns ...templ.Component) {
|
templ columns(columns ...templ.Component) {
|
||||||
<div class="columns is-centered">
|
<div class="columns is-centered">
|
||||||
for _, column := range columns {
|
for _, column := range columns {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package templates
|
|
||||||
|
|
||||||
templ loginForm() {
|
|
||||||
<form id="loginForm" method="post" name="login" action="/login.html" method="POST" hx-post="/login.html">
|
|
||||||
<label>Username </label>
|
|
||||||
<input type="text" placeholder="username" name="username" required class="input"/>
|
|
||||||
<label>Password </label>
|
|
||||||
<input type="password" name="password" required class="input"/>
|
|
||||||
<button class="button is-primary" type="submit" hx-trigger="click">Login</button>
|
|
||||||
</form>
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// Code generated by templ - DO NOT EDIT.
|
|
||||||
|
|
||||||
// templ: version: v0.2.543
|
|
||||||
package templates
|
|
||||||
|
|
||||||
//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"
|
|
||||||
|
|
||||||
func loginForm() templ.Component {
|
|
||||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
ctx = templ.InitializeContext(ctx)
|
|
||||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
|
||||||
if templ_7745c5c3_Var1 == nil {
|
|
||||||
templ_7745c5c3_Var1 = templ.NopComponent
|
|
||||||
}
|
|
||||||
ctx = templ.ClearChildren(ctx)
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"loginForm\" method=\"post\" name=\"login\" action=\"/login.html\" method=\"POST\" hx-post=\"/login.html\"><label>Username </label> <input type=\"text\" placeholder=\"username\" name=\"username\" required class=\"input\"> <label>Password </label> <input type=\"password\" name=\"password\" required class=\"input\"> <button class=\"button is-primary\" type=\"submit\" hx-trigger=\"click\">Login</button></form>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
templ Index(metaContent utils.MetaContent, counters IndexCounts, err error) {
|
||||||
|
@wrapBase(metaContent, "GoIPAM", err) {
|
||||||
|
<div class="section is-centered">
|
||||||
|
<div class="container">
|
||||||
|
@indexStats(counters)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ indexStats(counters IndexCounts) {
|
||||||
|
<div class="level mt-5 box">
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Subnets</p>
|
||||||
|
<p class="title">{ fmt.Sprint(counters.SubnetCount) }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Addresses</p>
|
||||||
|
<p class="title">{ fmt.Sprint(counters.AddressCount) }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Devices</p>
|
||||||
|
<p class="title">{ fmt.Sprint(counters.DeviceCount) }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Locations</p>
|
||||||
|
<p class="title">{ fmt.Sprint(counters.LocationCount) }</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.543
|
||||||
|
package templates
|
||||||
|
|
||||||
|
//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 "fmt"
|
||||||
|
|
||||||
|
func Index(metaContent utils.MetaContent, counters IndexCounts, err error) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-centered\"><div class=\"container\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = indexStats(counters).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = wrapBase(metaContent, "GoIPAM", err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func indexStats(counters IndexCounts) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var3 == nil {
|
||||||
|
templ_7745c5c3_Var3 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"level mt-5 box\"><div class=\"level-item has-text-centered\"><div><p class=\"heading\">Subnets</p><p class=\"title\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var4 string
|
||||||
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(counters.SubnetCount))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 19, Col: 55}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div><div class=\"level-item has-text-centered\"><div><p class=\"heading\">Addresses</p><p class=\"title\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(counters.AddressCount))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 25, Col: 56}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div><div class=\"level-item has-text-centered\"><div><p class=\"heading\">Devices</p><p class=\"title\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var6 string
|
||||||
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(counters.DeviceCount))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 31, Col: 55}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div><div class=\"level-item has-text-centered\"><div><p class=\"heading\">Locations</p><p class=\"title\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var7 string
|
||||||
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(counters.LocationCount))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 37, Col: 57}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p></div></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
templ Login(metaContent utils.MetaContent, title string, err error) {
|
||||||
|
@wrapBase(metaContent, title, err) {
|
||||||
|
<div class="section is-medium">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column">
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="title">Login</h2>
|
||||||
|
<p>Please login to GoIPAM to proceed</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
@loginForm()
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ loginForm() {
|
||||||
|
<form id="loginForm" name="login" action="/login.html" method="POST">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Username </label>
|
||||||
|
<input class="input" type="text" placeholder="username" name="username" required class="input"/>
|
||||||
|
<label class="label">Password </label>
|
||||||
|
<input class="input" type="password" name="password" placeholder="************" required class="input"/>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-primary" type="submit">Login</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.543
|
||||||
|
package templates
|
||||||
|
|
||||||
|
//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"
|
||||||
|
|
||||||
|
func Login(metaContent utils.MetaContent, title string, err error) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-medium\"><div class=\"columns is-centered\"><div class=\"column\"><div class=\"container\"><h2 class=\"title\">Login</h2><p>Please login to GoIPAM to proceed</p></div></div><div class=\"column\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = loginForm().Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = wrapBase(metaContent, title, err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func loginForm() templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var3 == nil {
|
||||||
|
templ_7745c5c3_Var3 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form id=\"loginForm\" name=\"login\" action=\"/login.html\" method=\"POST\"><div class=\"field\"><label class=\"label\">Username </label> <input class=\"input\" type=\"text\" placeholder=\"username\" name=\"username\" required class=\"input\"> <label class=\"label\">Password </label> <input class=\"input\" type=\"password\" name=\"password\" placeholder=\"************\" required class=\"input\"></div><div class=\"field\"><div class=\"control\"><button class=\"button is-primary\" type=\"submit\">Login</button></div></div></form>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ templ footer(timestamp string) {
|
||||||
<footer class="footer is-fixed-bottom">
|
<footer class="footer is-fixed-bottom">
|
||||||
<div class="content has-text-centered">
|
<div class="content has-text-centered">
|
||||||
<p>
|
<p>
|
||||||
<strong>Webframework</strong> by <a href="https://www.jmbit.de">Johannes Bülow</a> © { timestamp } .
|
<strong>GoIPAM</strong> by <a href="https://www.jmbit.de">Johannes Bülow</a> © { timestamp } .
|
||||||
The source code is licensed <a href="https://opensource.org/license/gpl-2-0/">GPLv2</a>.
|
The source code is licensed <a href="https://opensource.org/license/gpl-2-0/">GPLv2</a>.
|
||||||
Using <a href="https://bulma.io/">Bulma</a>, <a href="https://htmx.org/">HTMX</a>, <a href="https://templ.guide/">Templ</a>, <a href="https://gin-gonic.com/">Gin</a> and <a href="https://gorm.io/">GORM</a>.
|
Using <a href="https://bulma.io/">Bulma</a>, <a href="https://htmx.org/">HTMX</a>, <a href="https://templ.guide/">Templ</a>, <a href="https://gin-gonic.com/">Gin</a> and <a href="https://gorm.io/">GORM</a>.
|
||||||
</p>
|
</p>
|
||||||
|
@ -25,10 +25,10 @@ templ footer(timestamp string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
templ navbar(loggedIn bool) {
|
templ navbar(loggedIn bool) {
|
||||||
<nav id="navbarTop" class="navbar is-transparent is-fixed-top" role="navigation" aria-label="main navigation">
|
<nav id="navbarTop" class="navbar is-transparent is-fixed-top pb-3" role="navigation" aria-label="main navigation">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a class="navbar-item material-icons" href="/">
|
<a class="navbar-item has-text-centered" href="/">
|
||||||
web build
|
<p class="title">GoIPAM</p>
|
||||||
</a>
|
</a>
|
||||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarTop">
|
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarTop">
|
||||||
<span aria-hidden="true"></span>
|
<span aria-hidden="true"></span>
|
||||||
|
@ -56,11 +56,11 @@ templ navbar(loggedIn bool) {
|
||||||
|
|
||||||
templ loginButton(loggedIn bool) {
|
templ loginButton(loggedIn bool) {
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
<a class="navbar-link" href="/profile.html">
|
<a class="navbar-link" href="/profile/">
|
||||||
Profile
|
Profile
|
||||||
</a>
|
</a>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="button is-light" href="/login.html">
|
<a class="button is-light" href="/logout.html">
|
||||||
Log out
|
Log out
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,7 +73,7 @@ templ loginButton(loggedIn bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templ errorMessage(title string, content string) {
|
templ ErrorMessage(title string, content string) {
|
||||||
<article class="message container">
|
<article class="message container">
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<p>{ title }</p>
|
<p>{ title }</p>
|
||||||
|
@ -84,3 +84,23 @@ templ errorMessage(title string, content string) {
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wrapBase handles the basics of HTML
|
||||||
|
templ wrapBase(metaContent utils.MetaContent, title string, err error) {
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
@head(title)
|
||||||
|
<body class="has-navbar-fixed-top">
|
||||||
|
@navbar(metaContent.IsLoggedIn)
|
||||||
|
if err != nil {
|
||||||
|
@ErrorMessage("Error", err.Error())
|
||||||
|
}
|
||||||
|
{ children... }
|
||||||
|
@footer(metaContent.Timestamp)
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ Empty() {
|
||||||
|
<div id="empty"></div>
|
||||||
|
}
|
||||||
|
|
|
@ -60,14 +60,14 @@ func footer(timestamp string) templ.Component {
|
||||||
templ_7745c5c3_Var3 = templ.NopComponent
|
templ_7745c5c3_Var3 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<footer class=\"footer is-fixed-bottom\"><div class=\"content has-text-centered\"><p><strong>Webframework</strong> by <a href=\"https://www.jmbit.de\">Johannes Bülow</a> © ")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<footer class=\"footer is-fixed-bottom\"><div class=\"content has-text-centered\"><p><strong>GoIPAM</strong> by <a href=\"https://www.jmbit.de\">Johannes Bülow</a> © ")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var4 string
|
var templ_7745c5c3_Var4 string
|
||||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(timestamp)
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(timestamp)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/mainComponents.templ`, Line: 16, Col: 106}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/mainComponents.templ`, Line: 16, Col: 100}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
|
@ -97,7 +97,7 @@ func navbar(loggedIn bool) templ.Component {
|
||||||
templ_7745c5c3_Var5 = templ.NopComponent
|
templ_7745c5c3_Var5 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<nav id=\"navbarTop\" class=\"navbar is-transparent is-fixed-top\" role=\"navigation\" aria-label=\"main navigation\"><div class=\"navbar-brand\"><a class=\"navbar-item material-icons\" href=\"/\">web build</a> <a role=\"button\" class=\"navbar-burger\" aria-label=\"menu\" aria-expanded=\"false\" data-target=\"navbarTop\"><span aria-hidden=\"true\"></span> <span aria-hidden=\"true\"></span> <span aria-hidden=\"true\"></span></a></div><div id=\"navbar\" class=\"navbar-menu\"><div class=\"navbar-start\"><a class=\"navbar-item\" href=\"/index.html\">Home</a> <a class=\"navbar-item\">Page</a></div><div class=\"navbar-end\"><div class=\"navbar-item\">")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<nav id=\"navbarTop\" class=\"navbar is-transparent is-fixed-top pb-3\" role=\"navigation\" aria-label=\"main navigation\"><div class=\"navbar-brand\"><a class=\"navbar-item has-text-centered\" href=\"/\"><p class=\"title\">GoIPAM</p></a> <a role=\"button\" class=\"navbar-burger\" aria-label=\"menu\" aria-expanded=\"false\" data-target=\"navbarTop\"><span aria-hidden=\"true\"></span> <span aria-hidden=\"true\"></span> <span aria-hidden=\"true\"></span></a></div><div id=\"navbar\" class=\"navbar-menu\"><div class=\"navbar-start\"><a class=\"navbar-item\" href=\"/index.html\">Home</a> <a class=\"navbar-item\">Page</a></div><div class=\"navbar-end\"><div class=\"navbar-item\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ func loginButton(loggedIn bool) templ.Component {
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
if loggedIn {
|
if loggedIn {
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"navbar-link\" href=\"/profile.html\">Profile</a><div class=\"buttons\"><a class=\"button is-light\" href=\"/login.html\">Log out</a></div>")
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"navbar-link\" href=\"/profile/\">Profile</a><div class=\"buttons\"><a class=\"button is-light\" href=\"/logout.html\">Log out</a></div>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ func loginButton(loggedIn bool) templ.Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorMessage(title string, content string) templ.Component {
|
func ErrorMessage(title string, content string) templ.Component {
|
||||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
if !templ_7745c5c3_IsBuffer {
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
@ -196,3 +196,82 @@ func errorMessage(title string, content string) templ.Component {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wrapBase handles the basics of HTML
|
||||||
|
func wrapBase(metaContent utils.MetaContent, title string, err error) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var10 == nil {
|
||||||
|
templ_7745c5c3_Var10 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = head(title).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<body class=\"has-navbar-fixed-top\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = navbar(metaContent.IsLoggedIn).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
templ_7745c5c3_Err = ErrorMessage("Error", err.Error()).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templ_7745c5c3_Var10.Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = footer(metaContent.Timestamp).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Empty() templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var11 == nil {
|
||||||
|
templ_7745c5c3_Var11 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div id=\"empty\"></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import "git.jmbit.de/jmb/goipam/db"
|
||||||
|
import "git.jmbit.de/jmb/goipam/utils"
|
||||||
|
|
||||||
|
templ ProfilePage(metaContent utils.MetaContent, title string, user *db.User, err error) {
|
||||||
|
@wrapBase(metaContent, title, err) {
|
||||||
|
@profileMain(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ profileMain(user *db.User) {
|
||||||
|
<div class="section is-medium">
|
||||||
|
<div class="container">
|
||||||
|
@ProfileStatic(user)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ ProfileStatic(user *db.User) {
|
||||||
|
<div hx-target="this" hx-swap="outerHTML">
|
||||||
|
<div class="field"><label>Username</label>: { user.Name }</div>
|
||||||
|
<div class="field"><label>Display Name</label>: { user.DisplayName }</div>
|
||||||
|
<div class="field"><label>Email</label>: { user.Email }</div>
|
||||||
|
<button hx-get="/profile/edit.html" class="button button-primary">
|
||||||
|
Click To Edit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ ProfileForm(user *db.User) {
|
||||||
|
<form hx-post="/profile/edit" hx-swap="outerHTML">
|
||||||
|
<div>
|
||||||
|
<label>Username</label>
|
||||||
|
<input type="text" name="username" value={ user.Name }/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Display Name</label>
|
||||||
|
<input type="text" name="displayname" value={ user.DisplayName }/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Email Address</label>
|
||||||
|
<input type="email" name="email" value={ user.Email }/>
|
||||||
|
</div>
|
||||||
|
<button class="button button-primary">Submit</button>
|
||||||
|
<button class="button button-primary" hx-get="/profile/static.html">Cancel</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ PasswordForm(result string) {
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
|
// templ: version: v0.2.543
|
||||||
|
package templates
|
||||||
|
|
||||||
|
//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.jmbit.de/jmb/goipam/db"
|
||||||
|
import "git.jmbit.de/jmb/goipam/utils"
|
||||||
|
|
||||||
|
func ProfilePage(metaContent utils.MetaContent, title string, user *db.User, err error) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var1 == nil {
|
||||||
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = profileMain(user).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
templ_7745c5c3_Err = wrapBase(metaContent, title, err).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func profileMain(user *db.User) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var3 == nil {
|
||||||
|
templ_7745c5c3_Var3 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"section is-medium\"><div class=\"container\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = ProfileStatic(user).Render(ctx, templ_7745c5c3_Buffer)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProfileStatic(user *db.User) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var4 == nil {
|
||||||
|
templ_7745c5c3_Var4 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div hx-target=\"this\" hx-swap=\"outerHTML\"><div class=\"field\"><label>Username</label>: ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var5 string
|
||||||
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/profile.templ`, Line: 22, Col: 57}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label>Display Name</label>: ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var6 string
|
||||||
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(user.DisplayName)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/profile.templ`, Line: 23, Col: 68}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"field\"><label>Email</label>: ")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var7 string
|
||||||
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/profile.templ`, Line: 24, Col: 55}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><button hx-get=\"/profile/edit.html\" class=\"button button-primary\">Click To Edit</button></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProfileForm(user *db.User) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var8 == nil {
|
||||||
|
templ_7745c5c3_Var8 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form hx-post=\"/profile/edit\" hx-swap=\"outerHTML\"><div><label>Username</label> <input type=\"text\" name=\"username\" value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(user.Name))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div><div class=\"form-group\"><label>Display Name</label> <input type=\"text\" name=\"displayname\" value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(user.DisplayName))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div><div class=\"form-group\"><label>Email Address</label> <input type=\"email\" name=\"email\" value=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(user.Email))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></div><button class=\"button button-primary\">Submit</button> <button class=\"button button-primary\" hx-get=\"/profile/static.html\">Cancel</button></form>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func PasswordForm(result string) templ.Component {
|
||||||
|
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||||
|
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||||
|
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||||
|
}
|
||||||
|
ctx = templ.InitializeContext(ctx)
|
||||||
|
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
|
||||||
|
if templ_7745c5c3_Var9 == nil {
|
||||||
|
templ_7745c5c3_Var9 = templ.NopComponent
|
||||||
|
}
|
||||||
|
ctx = templ.ClearChildren(ctx)
|
||||||
|
if !templ_7745c5c3_IsBuffer {
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||||
|
}
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package templates
|
||||||
|
|
||||||
|
type IndexCounts struct {
|
||||||
|
SubnetCount int
|
||||||
|
AddressCount int
|
||||||
|
DeviceCount int
|
||||||
|
LocationCount int
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
package templates
|
|
||||||
|
|
||||||
import "git.jmbit.de/jmb/goipam/utils"
|
|
||||||
|
|
||||||
// wrapBase handles the basics of HTML
|
|
||||||
|
|
||||||
templ wrapBase(metaContent utils.MetaContent, title string) {
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
@head(title)
|
|
||||||
<body class="has-navbar-fixed-top">
|
|
||||||
@navbar(metaContent.IsLoggedIn)
|
|
||||||
{ children... }
|
|
||||||
@footer(metaContent.Timestamp)
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
}
|
|
||||||
|
|
||||||
templ Login(metaContent utils.MetaContent, title string) {
|
|
||||||
@wrapBase(metaContent, title) {
|
|
||||||
@loginForm()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templ Index(metaContent utils.MetaContent) {
|
|
||||||
@wrapBase(metaContent, "goipam") {
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="title">Placeholder Title</h2>
|
|
||||||
<p>Placeholder Text. This goipam thingy was made using Go, Gin, Gorm, Templ and HTMX. It's put together into this mess to prevent me from having write a bunch of boilerplate code everytime I start a new Project </p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
// Code generated by templ - DO NOT EDIT.
|
|
||||||
|
|
||||||
// templ: version: v0.2.543
|
|
||||||
package templates
|
|
||||||
|
|
||||||
//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.jmbit.de/jmb/goipam/utils"
|
|
||||||
|
|
||||||
// wrapBase handles the basics of HTML
|
|
||||||
func wrapBase(metaContent utils.MetaContent, title string) templ.Component {
|
|
||||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
ctx = templ.InitializeContext(ctx)
|
|
||||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
|
||||||
if templ_7745c5c3_Var1 == nil {
|
|
||||||
templ_7745c5c3_Var1 = templ.NopComponent
|
|
||||||
}
|
|
||||||
ctx = templ.ClearChildren(ctx)
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype HTML><html>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = head(title).Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<body class=\"has-navbar-fixed-top\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = navbar(metaContent.IsLoggedIn).Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = footer(metaContent.Timestamp).Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Login(metaContent utils.MetaContent, title string) templ.Component {
|
|
||||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
ctx = templ.InitializeContext(ctx)
|
|
||||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
|
||||||
if templ_7745c5c3_Var2 == nil {
|
|
||||||
templ_7745c5c3_Var2 = templ.NopComponent
|
|
||||||
}
|
|
||||||
ctx = templ.ClearChildren(ctx)
|
|
||||||
templ_7745c5c3_Var3 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = loginForm().Render(ctx, templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
templ_7745c5c3_Err = wrapBase(metaContent, title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Index(metaContent utils.MetaContent) templ.Component {
|
|
||||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
ctx = templ.InitializeContext(ctx)
|
|
||||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
|
||||||
if templ_7745c5c3_Var4 == nil {
|
|
||||||
templ_7745c5c3_Var4 = templ.NopComponent
|
|
||||||
}
|
|
||||||
ctx = templ.ClearChildren(ctx)
|
|
||||||
templ_7745c5c3_Var5 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
|
||||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
|
||||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"columns is-centered\"><div class=\"column\"><div class=\"container\"><h2 class=\"title\">Placeholder Title</h2><p>Placeholder Text. This goipam thingy was made using Go, Gin, Gorm, Templ and HTMX. It's put together into this mess to prevent me from having write a bunch of boilerplate code everytime I start a new Project </p></div></div></div>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
templ_7745c5c3_Err = wrapBase(metaContent, "goipam").Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if !templ_7745c5c3_IsBuffer {
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
|
||||||
}
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -5,10 +5,18 @@ import (
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"git.jmbit.de/jmb/goipam/db"
|
||||||
"git.jmbit.de/jmb/goipam/utils"
|
"git.jmbit.de/jmb/goipam/utils"
|
||||||
"git.jmbit.de/jmb/goipam/web/templates"
|
"git.jmbit.de/jmb/goipam/web/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func index(c *gin.Context) {
|
func index(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "", templates.Index(utils.GenMetaContent(c)))
|
counters := templates.IndexCounts{
|
||||||
|
AddressCount: db.CountAddresss(),
|
||||||
|
SubnetCount: db.CountSubnets(),
|
||||||
|
DeviceCount: db.CountDevices(),
|
||||||
|
LocationCount: db.CountLocations(),
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusOK, "", templates.Index(utils.GenMetaContent(c), counters, nil))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,14 @@ import (
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"git.jmbit.de/jmb/goipam/db"
|
||||||
"git.jmbit.de/jmb/goipam/utils"
|
"git.jmbit.de/jmb/goipam/utils"
|
||||||
"git.jmbit.de/jmb/goipam/web/auth"
|
"git.jmbit.de/jmb/goipam/web/auth"
|
||||||
"git.jmbit.de/jmb/goipam/web/templates"
|
"git.jmbit.de/jmb/goipam/web/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getLogin(c *gin.Context) {
|
func getLogin(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "", templates.Login(utils.GenMetaContent(c), "Login"))
|
c.HTML(http.StatusOK, "", templates.Login(utils.GenMetaContent(c), "Login", nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func postLogin(c *gin.Context) {
|
func postLogin(c *gin.Context) {
|
||||||
|
@ -25,12 +26,31 @@ func postLogin(c *gin.Context) {
|
||||||
metaContent := utils.GenMetaContent(c)
|
metaContent := utils.GenMetaContent(c)
|
||||||
metaContent.ErrorTitle = "Error"
|
metaContent.ErrorTitle = "Error"
|
||||||
metaContent.ErrorText = err.Error()
|
metaContent.ErrorText = err.Error()
|
||||||
c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login"))
|
c.HTML(http.StatusUnauthorized, "", templates.Login(metaContent, "Login", err))
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
user, err := db.GetUserByName(username)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Could not retrieve User Object for User with name %s", username)
|
||||||
|
}
|
||||||
session.Set("username", username)
|
session.Set("username", username)
|
||||||
|
session.Set("isLoggedIn", true)
|
||||||
|
session.Set("isAdmin", user.Admin)
|
||||||
|
err = session.Save()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("[ERRO] Could not save Session")
|
||||||
|
}
|
||||||
c.Redirect(http.StatusTemporaryRedirect, "/")
|
c.Redirect(http.StatusTemporaryRedirect, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLogout(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
username := session.Get("username")
|
||||||
|
session.Clear()
|
||||||
|
log.Printf("[INFO] Logged out %s", username)
|
||||||
|
|
||||||
|
c.Redirect(http.StatusTemporaryRedirect, "/login.html")
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,38 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"git.jmbit.de/jmb/goipam/db"
|
||||||
|
"git.jmbit.de/jmb/goipam/utils"
|
||||||
|
"git.jmbit.de/jmb/goipam/web/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getProfile(c *gin.Context) {
|
func getProfile(c *gin.Context) {
|
||||||
c.HTML(http.StatusOK, "profile", gin.H{
|
session := sessions.Default(c)
|
||||||
"title": "Profile",
|
sessionUserName := session.Get("username")
|
||||||
})
|
var user db.User
|
||||||
|
if username, ok := sessionUserName.(string); ok {
|
||||||
|
|
||||||
|
user, err := db.GetUserByName(username)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(
|
||||||
|
http.StatusInternalServerError,
|
||||||
|
"",
|
||||||
|
templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(
|
||||||
|
http.StatusOK,
|
||||||
|
"",
|
||||||
|
templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
c.HTML(http.StatusNotFound, "", templates.ProfilePage(utils.GenMetaContent(c), "User Profile", &user, nil))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ func GroupWeb(router *gin.Engine) *gin.Engine {
|
||||||
router.POST("/", index)
|
router.POST("/", index)
|
||||||
router.GET("/login.html", getLogin)
|
router.GET("/login.html", getLogin)
|
||||||
router.POST("/login.html", postLogin)
|
router.POST("/login.html", postLogin)
|
||||||
|
router.GET("/profile/", getProfile)
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue