diff --git a/cmd/hspguard/api/api.go b/cmd/hspguard/api/api.go index 2d6eea9..c5f96d8 100644 --- a/cmd/hspguard/api/api.go +++ b/cmd/hspguard/api/api.go @@ -4,10 +4,13 @@ import ( "fmt" "log" "net/http" + "os" + "path/filepath" "gitea.local/admin/hspguard/internal/repository" "gitea.local/admin/hspguard/internal/user" "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" ) type APIServer struct { @@ -24,6 +27,11 @@ func NewAPIServer(addr string, db *repository.Queries) *APIServer { func (s *APIServer) Run() error { router := chi.NewRouter() + router.Use(middleware.Logger) + + workDir, _ := os.Getwd() + staticDir := http.Dir(filepath.Join(workDir, "static")) + FileServer(router, "/static", staticDir) router.Route("/api/v1", func(r chi.Router) { userHandler := user.NewUserHandler() diff --git a/cmd/hspguard/api/file_server.go b/cmd/hspguard/api/file_server.go new file mode 100644 index 0000000..7a0ca82 --- /dev/null +++ b/cmd/hspguard/api/file_server.go @@ -0,0 +1,28 @@ +package api + +import ( + "net/http" + "strings" + + "github.com/go-chi/chi/v5" +) + +func FileServer(r chi.Router, path string, root http.FileSystem) { + if strings.ContainsAny(path, "{}*") { + panic("FileServer does not permit any URL parameters.") + } + + if path != "/" && path[len(path)-1] != '/' { + r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP) + path += "/" + } + path += "*" + + r.Get(path, func(w http.ResponseWriter, r *http.Request) { + rctx := chi.RouteContext(r.Context()) + pathPrefix := strings.TrimSuffix(rctx.RoutePattern(), "/*") + fs := http.StripPrefix(pathPrefix, http.FileServer(root)) + fs.ServeHTTP(w, r) + }) +} + diff --git a/internal/user/routes.go b/internal/user/routes.go index e820ef1..a3f39f7 100644 --- a/internal/user/routes.go +++ b/internal/user/routes.go @@ -14,11 +14,11 @@ func NewUserHandler() *UserHandler { } func (h *UserHandler) RegisterRoutes(router chi.Router) { - router.Get("/login", h.handleLogin) - router.Get("/register", h.handleRegister) + router.Get("/login", h.loginPage) + router.Get("/register", h.registerPage) } -func (h *UserHandler) handleLogin(w http.ResponseWriter, r *http.Request) { +func (h *UserHandler) loginPage(w http.ResponseWriter, r *http.Request) { data := map[string]any{ "Title": "Login", } @@ -26,7 +26,7 @@ func (h *UserHandler) handleLogin(w http.ResponseWriter, r *http.Request) { web.RenderTemplate(w, "login", data) } -func (h *UserHandler) handleRegister(w http.ResponseWriter, r *http.Request) { +func (h *UserHandler) registerPage(w http.ResponseWriter, r *http.Request) { data := map[string]any{ "Title": "Register", } diff --git a/static/css/styles.css b/static/css/styles.css new file mode 100644 index 0000000..1d2d8e8 --- /dev/null +++ b/static/css/styles.css @@ -0,0 +1,80 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html, body { + height: 100%; + font-family: Inter, Arial, sans-serif; + background-color: #f2f2f2; +} + +.container { + display: flex; + flex-direction: column; + min-height: 100vh; + justify-content: center; + align-items: center; + padding: 2rem; + position: relative; + background: #ffffff; + background: linear-gradient(0deg,rgba(255, 255, 255, 1) 90%, rgba(30, 144, 255, 1) 100%); +} + +.modal-box { + background-color: white; + padding: 2rem; + border-radius: 8px; + border: 1px solid #ddd; + max-width: 400px; + width: 100%; + z-index: 1; +} + +.modal-title { + font-size: 28px; + font-weight: 600; + margin-bottom: 15px; +} + +.input-group { + display: flex; + flex-direction: row; + align-items: stretch; + border: 1px solid #ccc; + border-radius: 5px; + margin-bottom: 10px; +} + +.input-icon { + padding: 10px; +} + +.input-field { + flex: 1; + border: none; +} + +.icon-wrapper { + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 20px; +} + +.icon { + width: 64px; + height: 64px; +} + +.footer { + position: absolute; + bottom: 1rem; + text-align: center; + color: #999; + font-size: 0.9rem; +} + diff --git a/static/icon.png b/static/icon.png new file mode 100644 index 0000000..7c47441 Binary files /dev/null and b/static/icon.png differ diff --git a/templates/layout/base.html b/templates/layout/base.html index 1ecd403..fcf4b49 100644 --- a/templates/layout/base.html +++ b/templates/layout/base.html @@ -4,15 +4,18 @@ {{ .Title }} + -
-

{{ .Title }}

-
-
- {{ block "content" . }}{{ end }} -
- {{ template "footer" . }} + + + +
+
+ {{ block "content" . }}{{ end }} +
+ {{ template "footer" . }} +
{{ end }} diff --git a/templates/layout/footer.html b/templates/layout/footer.html index 6487e43..b0564a7 100644 --- a/templates/layout/footer.html +++ b/templates/layout/footer.html @@ -1,4 +1,4 @@ {{ define "footer" }} - + {{ end }} diff --git a/templates/pages/register.html b/templates/pages/register.html index d2c67b4..2dcedb3 100644 --- a/templates/pages/register.html +++ b/templates/pages/register.html @@ -1,21 +1,31 @@ {{ define "content" }} -
- - -
- -
- -
+
+ icon +
+

+ Create an account to enter homelab +

+
+
+
+ © +
+ +
+
+
+ @ +
+ +
+
+
+ P +
+ +
+ +
{{ end }}