make navbar a component

This commit is contained in:
Evan Jarrett
2025-10-29 17:25:39 -05:00
parent 55afa99efa
commit 9af56daa34
8 changed files with 57 additions and 52 deletions
+1
View File
@@ -251,6 +251,7 @@ func autoDetectBaseURL(httpAddr string) string {
// Auto-detect from HTTP addr
if httpAddr[0] == ':' {
// Just a port, assume localhost
// Use "127.0.0.1" per RFC 8252 (OAuth servers reject "localhost")
return fmt.Sprintf("http://127.0.0.1%s", httpAddr)
}
@@ -0,0 +1,5 @@
{{ define "nav-brand" }}
<div class="nav-brand">
<a href="/"><span class="at-protocol">at://</span>Container Registry</a>
</div>
{{ end }}
@@ -0,0 +1,7 @@
{{ define "nav-search" }}
<div class="nav-search">
<form action="/search" method="get">
<input type="text" name="q" placeholder="Search images..." value="{{ .Query }}" />
</form>
</div>
{{ end }}
@@ -0,0 +1,3 @@
{{ define "nav-theme-toggle" }}
<button id="theme-toggle" onclick="toggleTheme()" class="btn-link theme-toggle-btn" aria-label="Toggle theme"></button>
{{ end }}
@@ -0,0 +1,27 @@
{{ define "nav-user" }}
{{ if .User }}
<div class="user-dropdown">
<button class="user-menu-btn" id="user-menu-btn" aria-expanded="false" aria-haspopup="true">
{{ if .User.Avatar }}
<img src="{{ .User.Avatar }}" alt="{{ .User.Handle }}" class="user-avatar">
{{ else }}
<div class="user-avatar-placeholder">{{ firstChar .User.Handle }}</div>
{{ end }}
<span class="user-handle">@{{ .User.Handle }}</span>
<svg class="dropdown-arrow" width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
<path d="M6 9L1 4h10z"/>
</svg>
</button>
<div class="dropdown-menu" id="user-dropdown-menu" hidden>
<a href="/u/{{ .User.Handle }}" class="dropdown-item">Your Repositories</a>
<a href="/settings" class="dropdown-item">Settings</a>
<hr class="dropdown-divider">
<form action="/auth/logout" method="POST">
<button type="submit" class="dropdown-item logout-btn">Logout</button>
</form>
</div>
</div>
{{ else }}
<a href="/auth/oauth/login?return_to=/" class="btn-primary">Login</a>
{{ end }}
{{ end }}
+13 -36
View File
@@ -1,42 +1,19 @@
{{ define "nav" }}
<nav class="navbar">
<div class="nav-brand">
<a href="/"><span class="at-protocol">at://</span>Container Registry</a>
</div>
<div class="nav-search">
<form action="/search" method="get">
<input type="text" name="q" placeholder="Search images..." value="{{ .Query }}" />
</form>
</div>
{{ template "nav-brand" }}
{{ template "nav-search" . }}
<div class="nav-links">
<button id="theme-toggle" onclick="toggleTheme()" class="btn-link theme-toggle-btn" aria-label="Toggle theme"></button>
{{ if .User }}
<div class="user-dropdown">
<button class="user-menu-btn" id="user-menu-btn" aria-expanded="false" aria-haspopup="true">
{{ if .User.Avatar }}
<img src="{{ .User.Avatar }}" alt="{{ .User.Handle }}" class="user-avatar">
{{ else }}
<div class="user-avatar-placeholder">{{ firstChar .User.Handle }}</div>
{{ end }}
<span class="user-handle">@{{ .User.Handle }}</span>
<svg class="dropdown-arrow" width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
<path d="M6 9L1 4h10z"/>
</svg>
</button>
<div class="dropdown-menu" id="user-dropdown-menu" hidden>
<a href="/u/{{ .User.Handle }}" class="dropdown-item">Your Repositories</a>
<a href="/settings" class="dropdown-item">Settings</a>
<hr class="dropdown-divider">
<form action="/auth/logout" method="POST">
<button type="submit" class="dropdown-item logout-btn">Logout</button>
</form>
</div>
</div>
{{ else }}
<a href="/auth/oauth/login?return_to=/" class="btn-primary">Login</a>
{{ end }}
{{ template "nav-theme-toggle" }}
{{ template "nav-user" . }}
</div>
</nav>
{{ end }}
{{ define "nav-simple" }}
<nav class="navbar">
{{ template "nav-brand" }}
<div class="nav-links">
{{ template "nav-theme-toggle" }}
</div>
</nav>
{{ end }}
+1 -5
View File
@@ -6,11 +6,7 @@
{{ template "head" . }}
</head>
<body>
<nav class="navbar">
<div class="nav-brand">
<a href="/">ATCR</a>
</div>
</nav>
{{ template "nav-simple" . }}
<main class="container">
<div class="login-page">
-11
View File
@@ -62,17 +62,6 @@ func NewAppWithScopes(baseURL string, store oauth.ClientAuthStore, scopes []stri
} else {
config = oauth.NewLocalhostConfig(redirectURI, scopes)
// Append client_name to localhost client ID query string
if clientName != "" {
u, err := url.Parse(config.ClientID)
if err == nil {
q := u.Query()
q.Set("client_name", clientName)
u.RawQuery = q.Encode()
config.ClientID = u.String()
}
}
slog.Info("Using public OAuth client (localhost development)")
}