diff --git a/kontor-gin/Containerfile b/kontor-gin/Containerfile
index c90b9fe..e64f5b7 100644
--- a/kontor-gin/Containerfile
+++ b/kontor-gin/Containerfile
@@ -10,7 +10,7 @@ RUN go mod download
# Copy the source code
COPY . .
# Build the Go application (strip debug info for smaller size)
-RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go
+RUN go build -trimpath -ldflags="-s -w" -o kontor-gin cmd/kontor-gin/main.go
# ---------- Stage 2: Final ----------
FROM alpine:latest
@@ -19,7 +19,9 @@ WORKDIR /app
# Install runtime dependencies you actually need
RUN apk add --no-cache ca-certificates tzdata curl
# Copy the binary and set ownership
-COPY --from=builder /app/kontor /app/kontor
+COPY --from=builder /app/kontor-gin /app/kontor-gin
+COPY --from=builder /app/templates /app/templates
+COPY --from=builder /app/assets /app/assets
ENV DB_HOST=postgres DB_USER=kontor DB_PASSWORD=kontor DB_NAME=kontor DB_PORT=5432 GIN_MODE=release
# Set the entrypoint command
-ENTRYPOINT ["/app/kontor"]
+ENTRYPOINT ["/app/kontor-gin"]
diff --git a/kontor-gin/cmd/kontor-gin/main.go b/kontor-gin/cmd/kontor-gin/main.go
new file mode 100644
index 0000000..c2afa42
--- /dev/null
+++ b/kontor-gin/cmd/kontor-gin/main.go
@@ -0,0 +1,88 @@
+package main
+
+import (
+ // "kontor-api-gin/pkg/handler"
+
+ "kontor-api-gin/pkg/globals"
+ "kontor-api-gin/pkg/middleware"
+ "kontor-api-gin/pkg/routes"
+ "kontor-api-gin/pkg/schema"
+ "log"
+ "log/slog"
+ "os"
+
+ "github.com/gin-contrib/sessions"
+ "github.com/gin-contrib/sessions/cookie"
+ gin_slog "github.com/gin-contrib/slog"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ slog.Info("Kontor started")
+
+ // Set Gin mode based on environment
+ // Production mode disables debug output
+ if os.Getenv("GIN_MODE") == "release" {
+ gin.SetMode(gin.ReleaseMode)
+ }
+
+ // Connect to database
+ schema.Connect()
+
+ // Run migrations
+ schema.RunMigrations()
+
+ // Create Gin router with default middleware
+ // Default includes Logger and Recovery middleware
+ // router := gin.Default()
+ // Create a new router without default mmiddleware
+ router := gin.New()
+ // Add recovery middleware
+ router.Use(gin.Recovery())
+ router.Use(gin_slog.SetLogger(
+ gin_slog.WithSkipPath([]string{"/health", "/public/style/main.css"}),
+ gin_slog.WithDefaultLevel(slog.LevelInfo),
+ gin_slog.WithClientErrorLevel(slog.LevelInfo),
+ gin_slog.WithServerErrorLevel(slog.LevelInfo),
+ ))
+
+ router.LoadHTMLGlob("templates/**/*.html")
+ router.Static("/public", "./assets")
+
+ router.Use(sessions.Sessions("session", cookie.NewStore(globals.Secret)))
+
+ // Setup api routes
+ api := routes.SetupApiRoutes(router)
+ api.Use(middleware.CorsMiddleware)
+ routes.SetupMediaRoutes(api)
+ routes.SetupComicRoutes(api)
+
+ // Setup public Webapp routes
+ routes.PublicRoutes(router)
+
+ // Setup protected Webapp routes
+ protected := router.Group("/auth")
+ protected.Use(middleware.AuthRequired)
+ routes.ProtectedRoutes(router)
+
+ comics := router.Group("/comics")
+ comics.Use(middleware.AuthRequired)
+ routes.ComicRoutes(router)
+
+ media := router.Group("/media")
+ media.Use(middleware.AuthRequired)
+ routes.MediaRoutes(router)
+
+ // Start server
+ port := os.Getenv("PORT")
+ if port == "" {
+ port = "8550"
+ }
+
+ slog.Info("Server starting", "port", port)
+ if err := router.Run(":" + port); err != nil {
+ log.Fatal("Failed to start server:", err)
+ }
+
+ slog.Info("Kontor finished")
+}
diff --git a/kontor-gin/cmd/kontor/main.go b/kontor-gin/cmd/kontor/main.go
index 4b07ef2..43ba1b4 100644
--- a/kontor-gin/cmd/kontor/main.go
+++ b/kontor-gin/cmd/kontor/main.go
@@ -49,7 +49,7 @@ func main() {
gin_slog.WithServerErrorLevel(slog.LevelInfo),
))
- templ := template.Must(template.New("").ParseFS(templates.TemplateFiles, "html/*.tmpl"))
+ templ := template.Must(template.New("").ParseFS(templates.TemplateFiles, "layouts/*.html", "pages/*.html"))
router.SetHTMLTemplate(templ)
router.StaticFS("/public", http.FS(assets.StaticFiles))
diff --git a/kontor-gin/pkg/controllers/auth.go b/kontor-gin/pkg/controllers/auth.go
index 76e1445..dd70a8e 100644
--- a/kontor-gin/pkg/controllers/auth.go
+++ b/kontor-gin/pkg/controllers/auth.go
@@ -15,9 +15,9 @@ func LoginGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
logger := slog.Get(c)
- logger.Info("LoginGetHandler", "user", user)
+ logger.Info("LoginGetHandler", globals.UserKey, user)
if user != nil {
- c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
+ c.HTML(http.StatusBadRequest, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -26,7 +26,7 @@ func LoginGetHandler(c *gin.Context) {
})
return
}
- c.HTML(http.StatusOK, "login.tmpl", gin.H{
+ c.HTML(http.StatusOK, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -41,7 +41,7 @@ func LoginPostHandler(c *gin.Context) {
logger := slog.Get(c)
logger.Info("LoginPostHandler", "user", user)
if user != nil {
- c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
+ c.HTML(http.StatusBadRequest, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -54,7 +54,7 @@ func LoginPostHandler(c *gin.Context) {
password := c.PostForm("password")
if helpers.EmptyUserPass(username, password) {
- c.HTML(http.StatusBadRequest, "login.tmpl", gin.H{
+ c.HTML(http.StatusBadRequest, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -63,7 +63,7 @@ func LoginPostHandler(c *gin.Context) {
}
if !helpers.CheckUserPass(username, password) {
- c.HTML(http.StatusUnauthorized, "login.tmpl", gin.H{
+ c.HTML(http.StatusUnauthorized, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -73,7 +73,7 @@ func LoginPostHandler(c *gin.Context) {
session.Set(globals.UserKey, username)
if err := session.Save(); err != nil {
- c.HTML(http.StatusInternalServerError, "login.tmpl", gin.H{
+ c.HTML(http.StatusInternalServerError, "login.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"login": globals.LoginUrl,
@@ -90,7 +90,7 @@ func LogoutGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
logger := slog.Get(c)
- logger.Info("LogoutGetHandler", "user", user)
+ logger.Info("LogoutGetHandler", globals.UserKey, user)
if user == nil {
logger.Info("Invalid session token")
return
diff --git a/kontor-gin/pkg/controllers/handlers.go b/kontor-gin/pkg/controllers/handlers.go
index 7cfddd2..1d1c8b9 100644
--- a/kontor-gin/pkg/controllers/handlers.go
+++ b/kontor-gin/pkg/controllers/handlers.go
@@ -13,11 +13,12 @@ func IndexGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
logger := slog.Get(c)
- logger.Info("IndexGetHandler", "user", user)
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ logger.Info("IndexGetHandler", globals.UserKey, user)
+ c.HTML(http.StatusOK, "home.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "This is an index page...",
+ "login": globals.LoginUrl,
"logout": globals.LogoutUrl,
"user": user,
})
diff --git a/kontor-gin/pkg/controllers/media.go b/kontor-gin/pkg/controllers/media.go
index 24863bc..0806658 100644
--- a/kontor-gin/pkg/controllers/media.go
+++ b/kontor-gin/pkg/controllers/media.go
@@ -30,25 +30,24 @@ func ListMediaLoFis(c *gin.Context) {
result := schema.DB.Find(&lofis)
log.Printf("found %d MediaLoFis", result.RowsAffected)
c.JSON(http.StatusOK, lofis)
- // c.JSON(http.StatusOK, gin.H{
- // "message": "All MediaLoFis",
- // "lofis": lofis,
- // })
}
func ListMediaActorsGetHandler(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
+ logger := slog.Get(c)
var actors []schema.MediaActor
result := schema.DB.Find(&actors)
- log.Printf("found %d MediaActors", result.RowsAffected)
- c.HTML(http.StatusOK, "media_actor.tmpl", gin.H{
+ logger.Info("ListMediaActorsGetHandler", "count", result.RowsAffected)
+ c.HTML(http.StatusOK, "mediaactors.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Media Actors...",
"actors": actors,
+ "login": globals.LoginUrl,
+ "logout": globals.LogoutUrl,
"user": user,
})
}
@@ -61,12 +60,14 @@ func ListMediaFilesGetHandler(c *gin.Context) {
var files []schema.MediaFile
result := schema.DB.Find(&files)
- logger.Info("found MediaFiles", "count", result.RowsAffected)
- c.HTML(http.StatusOK, "media_files.tmpl", gin.H{
+ logger.Info("ListMediaFilesGetHandler", "count", result.RowsAffected)
+ c.HTML(http.StatusOK, "mediafiles.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Media Files...",
"files": files,
+ "login": globals.LoginUrl,
+ "logout": globals.LogoutUrl,
"user": user,
})
@@ -80,14 +81,14 @@ func ListMediaLoFisGetHandler(c *gin.Context) {
var lofis []schema.MediaLoFi
result := schema.DB.Find(&lofis)
- logger.Info("found MediaActors", "count", result.RowsAffected)
- c.HTML(http.StatusOK, "media_lofi.tmpl", gin.H{
+ logger.Info("ListMediaLoFisGetHandler", "count", result.RowsAffected)
+ c.HTML(http.StatusOK, "media_lofi.html", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"content": "Media LoFis...",
"lofis": lofis,
+ "login": globals.LoginUrl,
"logout": globals.LogoutUrl,
"user": user,
})
-
}
diff --git a/kontor-gin/pkg/globals/globals.go b/kontor-gin/pkg/globals/globals.go
index 3716acb..3fa65fb 100644
--- a/kontor-gin/pkg/globals/globals.go
+++ b/kontor-gin/pkg/globals/globals.go
@@ -6,6 +6,6 @@ const UserKey = "user"
const Version = "0.4.0"
-const LoginUrl = "/login"
+const LoginUrl = "/auth/login"
-const LogoutUrl = "/exit"
+const LogoutUrl = "/auth/logout"
diff --git a/kontor-gin/pkg/routes/webapp.go b/kontor-gin/pkg/routes/webapp.go
index c291058..40127f7 100644
--- a/kontor-gin/pkg/routes/webapp.go
+++ b/kontor-gin/pkg/routes/webapp.go
@@ -3,21 +3,32 @@ package routes
import (
"kontor-api-gin/pkg/controllers"
"kontor-api-gin/pkg/globals"
+ "kontor-api-gin/pkg/middleware"
"github.com/gin-gonic/gin"
)
-func PublicRoutes(g *gin.RouterGroup) {
+func PublicRoutes(g *gin.Engine) {
g.GET("/health", controllers.HealthGetHandler)
g.GET(globals.LoginUrl, controllers.LoginGetHandler)
g.POST(globals.LoginUrl, controllers.LoginPostHandler)
- g.GET("/comic/comics", controllers.ListComicsGetHandler)
- g.GET("", controllers.IndexGetHandler)
+ g.GET("/", controllers.IndexGetHandler)
}
-func ProtectedRoutes(g *gin.RouterGroup) {
- g.GET(globals.LogoutUrl, controllers.LogoutGetHandler)
- g.GET("/media/actors", controllers.ListMediaActorsGetHandler)
- // g.GET("/media/files", controllers.ListMediaFilesGetHandler)
- g.GET("/media/lofis", controllers.ListMediaLoFisGetHandler)
+func ComicRoutes(g *gin.Engine) {
+ g.GET("/comic/comics", controllers.ListComicsGetHandler)
+}
+
+func MediaRoutes(g *gin.Engine) {
+ media := g.Group("/media")
+ media.Use(middleware.AuthRequired)
+ media.GET("/actors", controllers.ListMediaActorsGetHandler)
+ media.GET("/files", controllers.ListMediaFilesGetHandler)
+ media.GET("/lofis", controllers.ListMediaLoFisGetHandler)
+}
+
+func ProtectedRoutes(g *gin.Engine) {
+ auth := g.Group("/auth")
+ auth.Use(middleware.AuthRequired)
+ auth.GET("/logout", controllers.LogoutGetHandler)
}
diff --git a/kontor-gin/templates/html/comic_comics.tmpl b/kontor-gin/templates/html/comic_comics.tmpl
deleted file mode 100644
index efca0a7..0000000
--- a/kontor-gin/templates/html/comic_comics.tmpl
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
- {{ .content }}
-
-
-
-
-
- | Title |
- Publisher |
- Completed |
- Actions |
-
-
- {{ range .comics }}
-
- | {{.Title}} |
- {{ if .Publisher }}
- {{.Publisher.Name}} |
- {{ else }}
- Publisher not set |
- {{ end }}
-
- {{ if .Completed }}
-
- {{ else }}
-
- {{ end }}
- |
- Edit |
- Delete |
-
- {{ end }}
-
-
-
-
-
- {{ template "footer.tmpl" . }}
-
-
diff --git a/kontor-gin/templates/html/footer.tmpl b/kontor-gin/templates/html/footer.tmpl
deleted file mode 100644
index be72ca1..0000000
--- a/kontor-gin/templates/html/footer.tmpl
+++ /dev/null
@@ -1,3 +0,0 @@
-{{ define "footer.tmpl" }}
-
-{{end}}
diff --git a/kontor-gin/templates/html/header.tmpl b/kontor-gin/templates/html/header.tmpl
deleted file mode 100644
index acbbd6b..0000000
--- a/kontor-gin/templates/html/header.tmpl
+++ /dev/null
@@ -1,14 +0,0 @@
-{{ define "header.tmpl" }}
-
-
-
-
-
- {{ .title }}
-
-{{ end }}
diff --git a/kontor-gin/templates/html/index.tmpl b/kontor-gin/templates/html/index.tmpl
deleted file mode 100644
index a3e7487..0000000
--- a/kontor-gin/templates/html/index.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
- {{ .title }}
-
- {{ template "footer.tmpl" . }}
-
-
diff --git a/kontor-gin/templates/html/media_actor.tmpl b/kontor-gin/templates/html/media_actor.tmpl
deleted file mode 100644
index 6663d53..0000000
--- a/kontor-gin/templates/html/media_actor.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
- {{ .content }}
-
- {{ template "footer.tmpl" . }}
-
-
diff --git a/kontor-gin/templates/html/media_files.tmpl b/kontor-gin/templates/html/media_files.tmpl
deleted file mode 100644
index 6663d53..0000000
--- a/kontor-gin/templates/html/media_files.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
- {{ .content }}
-
- {{ template "footer.tmpl" . }}
-
-
diff --git a/kontor-gin/templates/html/media_lofi.tmpl b/kontor-gin/templates/html/media_lofi.tmpl
deleted file mode 100644
index 6663d53..0000000
--- a/kontor-gin/templates/html/media_lofi.tmpl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
- {{ .content }}
-
- {{ template "footer.tmpl" . }}
-
-
diff --git a/kontor-gin/templates/layouts/main.html b/kontor-gin/templates/layouts/main.html
new file mode 100644
index 0000000..2235cf5
--- /dev/null
+++ b/kontor-gin/templates/layouts/main.html
@@ -0,0 +1,24 @@
+{{ define "main" }}
+
+
+
+
+
+
+
+ {{ .title }}
+
+
+
+
+ {{ template "navbar" . }}
+ {{ template "content" . }}
+
+
+
+{{ end }}
diff --git a/kontor-gin/templates/html/navbar.tmpl b/kontor-gin/templates/layouts/navbar.html
similarity index 60%
rename from kontor-gin/templates/html/navbar.tmpl
rename to kontor-gin/templates/layouts/navbar.html
index e61d977..a6c2c73 100644
--- a/kontor-gin/templates/html/navbar.tmpl
+++ b/kontor-gin/templates/layouts/navbar.html
@@ -1,13 +1,13 @@
-{{ define "navbar.tmpl" }}
+{{ define "navbar" }}
{{ end }}
diff --git a/kontor-gin/templates/pages/comics.html b/kontor-gin/templates/pages/comics.html
new file mode 100644
index 0000000..28829b8
--- /dev/null
+++ b/kontor-gin/templates/pages/comics.html
@@ -0,0 +1,52 @@
+{{ define "comics.html" }}
+{{ template "main" . }}
+{{ end }}
+
+{{ define "content" }}
+
+
+
+
+
+ | Title |
+ Publisher |
+ Completed |
+ Actions |
+
+
+ {{ range .comics }}
+
+ | {{.Title}} |
+ {{ if .Publisher }}
+ {{.Publisher.Name}} |
+ {{ else }}
+ Publisher not set |
+ {{ end }}
+
+ {{ if .Completed }}
+
+ {{ else }}
+
+ {{ end }}
+ |
+ Edit |
+ Delete |
+
+ {{ end }}
+
+
+
+
+{{ end }}
diff --git a/kontor-gin/templates/pages/home.html b/kontor-gin/templates/pages/home.html
new file mode 100644
index 0000000..e27dd85
--- /dev/null
+++ b/kontor-gin/templates/pages/home.html
@@ -0,0 +1,7 @@
+{{ define "home.html" }}
+{{ template "main" . }}
+{{ end }}
+
+{{ define "content" }}
+{{ .content }}
+{{ end }}
diff --git a/kontor-gin/templates/pages/lofi.html b/kontor-gin/templates/pages/lofi.html
new file mode 100644
index 0000000..b0dc02c
--- /dev/null
+++ b/kontor-gin/templates/pages/lofi.html
@@ -0,0 +1,52 @@
+{{ define "media_lofi.html" }}
+{{ template "main" . }}
+{{ end }}
+
+{{ define "content" }}
+
+
+
+
+
+ | Title |
+ Publisher |
+ Completed |
+ Actions |
+
+
+ {{ range .comics }}
+
+ | {{.Title}} |
+ {{ if .WebLink }}
+ {{.Title}} |
+ {{ else }}
+ WebLink not set |
+ {{ end }}
+
+ {{ if .Review }}
+
+ {{ else }}
+
+ {{ end }}
+ |
+ Edit |
+ Delete |
+
+ {{ end }}
+
+
+
+
+{{ end }}
diff --git a/kontor-gin/templates/html/login.tmpl b/kontor-gin/templates/pages/login.html
similarity index 84%
rename from kontor-gin/templates/html/login.tmpl
rename to kontor-gin/templates/pages/login.html
index 92f6948..b596105 100644
--- a/kontor-gin/templates/html/login.tmpl
+++ b/kontor-gin/templates/pages/login.html
@@ -1,11 +1,8 @@
-
-
-{{ template "header.tmpl" . }}
-
-
-
- {{ template "navbar.tmpl" . }}
+{{ define "login.html" }}
+{{ template "main" . }}
+{{ end }}
+{{ define "content" }}
-
- {{ template "footer.tmpl" . }}
-
-
+{{ end }}
diff --git a/kontor-gin/templates/pages/mediaactors.html b/kontor-gin/templates/pages/mediaactors.html
new file mode 100644
index 0000000..e27dd85
--- /dev/null
+++ b/kontor-gin/templates/pages/mediaactors.html
@@ -0,0 +1,7 @@
+{{ define "home.html" }}
+{{ template "main" . }}
+{{ end }}
+
+{{ define "content" }}
+{{ .content }}
+{{ end }}
diff --git a/kontor-gin/templates/pages/mediafiles.html b/kontor-gin/templates/pages/mediafiles.html
new file mode 100644
index 0000000..9b6a5e3
--- /dev/null
+++ b/kontor-gin/templates/pages/mediafiles.html
@@ -0,0 +1,7 @@
+{{ define "mediafiles.html" }}
+{{ template "main" . }}
+{{ end }}
+
+{{ define "content" }}
+{{ .content }}
+{{ end }}