From 8eef93357360b4a840dbc24f2a6d6816dd2d8304 Mon Sep 17 00:00:00 2001 From: "Christoph K." Date: Thu, 9 Apr 2026 22:28:02 +0200 Subject: [PATCH] menu added --- backend/internal/api/journal.go | 2 +- backend/internal/api/static/style.css | 7 ++++++ backend/internal/api/templates/base.html | 10 ++++++++ backend/internal/api/templates/days.html | 7 ------ backend/internal/api/templates/public.html | 4 --- backend/internal/api/webui.go | 29 ++++++++++++++-------- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/backend/internal/api/journal.go b/backend/internal/api/journal.go index d869651..e46a137 100644 --- a/backend/internal/api/journal.go +++ b/backend/internal/api/journal.go @@ -44,7 +44,7 @@ func (h *JournalHandler) HandleGetEditEntry(w http.ResponseWriter, r *http.Reque http.Error(w, "Eintrag nicht gefunden", http.StatusNotFound) return } - render(w, "edit_entry.html", map[string]any{"Entry": entry}) + render(w, r, "edit_entry.html", map[string]any{"Entry": entry}) } // HandleUpdateEntry handles POST /entries/{id} (multipart/form-data). diff --git a/backend/internal/api/static/style.css b/backend/internal/api/static/style.css index f6a7333..2e4fa41 100644 --- a/backend/internal/api/static/style.css +++ b/backend/internal/api/static/style.css @@ -13,6 +13,13 @@ --pico-primary-underline: rgba(0,0,0,.5); } +/* Site nav */ +.site-nav { display: flex; gap: 1.5rem; align-items: baseline; padding: .7rem 0; margin-bottom: 1.5rem; border-bottom: 1px solid var(--pico-muted-border-color); } +.site-nav a { font-size: .85rem; text-decoration: none; } +.site-nav a:hover { text-decoration: underline; } +.nav-btn { background: none; border: none; color: var(--pico-primary); padding: 0; cursor: pointer; font-family: inherit; font-size: .85rem; margin: 0; } +.site-nav form { margin: 0; padding: 0; } + h1 { font-size: 1.4rem; font-weight: normal; letter-spacing: .05em; } h2 { font-size: 1rem; font-weight: normal; letter-spacing: .05em; } diff --git a/backend/internal/api/templates/base.html b/backend/internal/api/templates/base.html index 13aab4a..82e8e68 100644 --- a/backend/internal/api/templates/base.html +++ b/backend/internal/api/templates/base.html @@ -8,6 +8,16 @@ + {{block "content" .}}{{end}} {{block "scripts" .}}{{end}} diff --git a/backend/internal/api/templates/days.html b/backend/internal/api/templates/days.html index 0720b3f..47486e3 100644 --- a/backend/internal/api/templates/days.html +++ b/backend/internal/api/templates/days.html @@ -2,13 +2,6 @@ {{define "content"}}
-
diff --git a/backend/internal/api/templates/public.html b/backend/internal/api/templates/public.html index 98ef08d..cee98d4 100644 --- a/backend/internal/api/templates/public.html +++ b/backend/internal/api/templates/public.html @@ -2,10 +2,6 @@ {{define "content"}}
-
{{template "feed_items" .}}
diff --git a/backend/internal/api/webui.go b/backend/internal/api/webui.go index 0cb877b..8668160 100644 --- a/backend/internal/api/webui.go +++ b/backend/internal/api/webui.go @@ -56,7 +56,16 @@ func NewWebUI(a *auth.Store, tp *db.TrackpointStore, st *db.StopStore, j *db.Jou return &WebUI{authStore: a, tpStore: tp, stopStore: st, journalStore: j, userStore: u} } -func render(w http.ResponseWriter, page string, data any) { +func injectNav(r *http.Request, data map[string]any) { + user := userFromContext(r.Context()) + if user.UserID != "" { + data["LoggedIn"] = true + data["IsAdmin"] = user.IsAdmin + } +} + +func render(w http.ResponseWriter, r *http.Request, page string, data map[string]any) { + injectNav(r, data) t, err := tmpls.Clone() if err == nil { _, err = t.ParseFS(assets, "templates/"+page) @@ -120,7 +129,7 @@ func renderAdmin(w http.ResponseWriter, page string, data any) { // --- Auth --- func (ui *WebUI) HandleGetLogin(w http.ResponseWriter, r *http.Request) { - render(w, "login.html", map[string]any{"Error": "", "Username": ""}) + render(w, r, "login.html", map[string]any{"Error": "", "Username": ""}) } func (ui *WebUI) HandlePostLogin(w http.ResponseWriter, r *http.Request) { @@ -137,7 +146,7 @@ func (ui *WebUI) HandlePostLogin(w http.ResponseWriter, r *http.Request) { if errors.Is(err, auth.ErrInvalidCredentials) { msg = "Ungültige Zugangsdaten." } - render(w, "login.html", map[string]any{"Error": msg, "Username": username}) + render(w, r, "login.html", map[string]any{"Error": msg, "Username": username}) return } @@ -171,7 +180,7 @@ func (ui *WebUI) HandleLogout(w http.ResponseWriter, r *http.Request) { // --- Register --- func (ui *WebUI) HandleGetRegister(w http.ResponseWriter, r *http.Request) { - render(w, "register.html", map[string]any{"Error": "", "Username": ""}) + render(w, r, "register.html", map[string]any{"Error": "", "Username": ""}) } func (ui *WebUI) HandlePostRegister(w http.ResponseWriter, r *http.Request) { @@ -184,11 +193,11 @@ func (ui *WebUI) HandlePostRegister(w http.ResponseWriter, r *http.Request) { confirm := r.FormValue("confirm") if username == "" || password == "" { - render(w, "register.html", map[string]any{"Error": "Benutzername und Passwort sind Pflichtfelder.", "Username": username}) + render(w, r, "register.html", map[string]any{"Error": "Benutzername und Passwort sind Pflichtfelder.", "Username": username}) return } if password != confirm { - render(w, "register.html", map[string]any{"Error": "Passwörter stimmen nicht überein.", "Username": username}) + render(w, r, "register.html", map[string]any{"Error": "Passwörter stimmen nicht überein.", "Username": username}) return } @@ -197,7 +206,7 @@ func (ui *WebUI) HandlePostRegister(w http.ResponseWriter, r *http.Request) { if errors.Is(err, auth.ErrUsernameTaken) { msg = "Benutzername bereits vergeben." } - render(w, "register.html", map[string]any{"Error": msg, "Username": username}) + render(w, r, "register.html", map[string]any{"Error": msg, "Username": username}) return } http.Redirect(w, r, "/login", http.StatusSeeOther) @@ -211,7 +220,7 @@ func (ui *WebUI) HandleFeed(w http.ResponseWriter, r *http.Request) { http.Error(w, "Fehler beim Laden", http.StatusInternalServerError) return } - render(w, "public.html", map[string]any{ + render(w, r, "public.html", map[string]any{ "Entries": entries, "Offset": 20, "HasMore": len(entries) == 20, @@ -260,7 +269,7 @@ func (ui *WebUI) HandleDaysList(w http.ResponseWriter, r *http.Request) { http.Error(w, "Fehler beim Laden", http.StatusInternalServerError) return } - render(w, "days.html", map[string]any{"Days": days, "IsAdmin": user.IsAdmin}) + render(w, r, "days.html", map[string]any{"Days": days}) } func (ui *WebUI) HandleDayDetail(w http.ResponseWriter, r *http.Request) { @@ -288,7 +297,7 @@ func (ui *WebUI) HandleDayDetail(w http.ResponseWriter, r *http.Request) { return } - render(w, "day.html", map[string]any{ + render(w, r, "day.html", map[string]any{ "Date": date, "Points": points, "Stops": stops,