Add a profile dropdown menu

This commit is contained in:
Ben Visness 2024-07-02 22:58:33 -05:00
parent a646dddec0
commit dffd1c94b5
9 changed files with 58 additions and 53 deletions

View File

@ -8298,7 +8298,7 @@ header .header-nav > .root-item > a {
display: block;
padding: var(--spacing-3);
}
header .header-nav .submenu {
header .submenu {
display: flex;
flex-direction: column;
position: absolute;
@ -8309,16 +8309,16 @@ header .header-nav .submenu {
border-width: 1px;
border-top-width: 0;
}
header .header-nav .submenu > a {
header .submenu > a {
padding: var(--spacing-2) var(--spacing-3);
display: block;
white-space: nowrap;
z-index: 1;
}
header .header-nav .root-item:not(:hover):not(.clicked) > .submenu {
header .root-item:not(:hover):not(.clicked) > .submenu {
display: none;
}
header .header-nav .root-item.clicked .svgicon {
header .root-item.clicked .svgicon {
transform: rotate(180deg);
}
header:not(.clicked) .root-item:not(:hover) > .submenu,

View File

@ -67,7 +67,7 @@ func TestLoginWithDiscord(t *testing.T) {
}
func TestLogoutAction(t *testing.T) {
AssertRegexMatch(t, BuildLogoutAction(""), RegexLogoutAction, nil)
AssertRegexMatch(t, BuildLogoutAction(""), RegexLogout, nil)
}
func TestRegister(t *testing.T) {

View File

@ -219,7 +219,7 @@ func BuildLoginWithDiscord(redirectTo string) string {
return Url("/login-with-discord", []Q{{Name: "redirect", Value: redirectTo}})
}
var RegexLogoutAction = regexp.MustCompile("^/logout$")
var RegexLogout = regexp.MustCompile("^/logout$")
func BuildLogoutAction(redir string) string {
defer CatchPanic()

View File

@ -144,6 +144,7 @@ header {
display: block;
padding: var(--spacing-3);
}
}
.submenu {
display: flex;
@ -173,7 +174,6 @@ header {
transform: rotate(180deg);
}
}
}
&:not(.clicked) .root-item:not(:hover),
&.clicked .root-item:not(.clicked) {

View File

@ -39,6 +39,7 @@
</div>
</div>
</div>
<div class="root-item f6">
<a class="db {{ if .User }}pv2 ph3{{ else }}pa3{{ end }} lh-solid flex f6 {{ if not .User }}bl{{ end }}" href="{{ or .Header.UserProfileUrl .LoginPageUrl }}">
{{ with .User }}
<img class="avatar avatar-user" src="{{ .AvatarUrl }}">
@ -46,6 +47,14 @@
Log In
{{ end }}
</a>
{{ if .User }}
<div class="submenu right-0" id="profile-submenu">
<a href="{{ .Header.UserProfileUrl }}">Profile</a>
<a href="{{ .Header.UserSettingsUrl }}">Settings</a>
<a href="{{ .Header.LogoutUrl }}">Log Out</a>
</div>
{{ end }}
</div>
</header>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {

View File

@ -9,7 +9,7 @@
<a class="dib pv2 pl2" href="{{ .Header.UserProfileUrl }}">{{ .User.Username }}</a>
<a class="dib pv2 pr2" href="{{ .Header.UserSettingsUrl }}">(settings)</a>
</div>
<a class="pa2" href="{{ .Header.LogoutActionUrl }}"><span class="icon-logout"></span> Log Out</a>
<a class="pa2" href="{{ .Header.LogoutUrl }}"><span class="icon-logout"></span> Log Out</a>
{{ else }}
<a class="pa2" id="register-link" href="{{ .Header.RegisterUrl }}">Register</a>
<a class="pa2" id="login-link" href="{{ .LoginPageUrl }}">Log in</a>

View File

@ -43,11 +43,9 @@ type Header struct {
AdminUrl string
UserProfileUrl string
UserSettingsUrl string
LoginActionUrl string
LogoutActionUrl string
LogoutUrl string
ForgotPasswordUrl string
RegisterUrl string
LoginWithDiscordUrl string
HMNHomepageUrl string
ProjectIndexUrl string

View File

@ -66,11 +66,9 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
Header: templates.Header{
AdminUrl: hmnurl.BuildAdminApprovalQueue(), // TODO(asaf): Replace with general-purpose admin page
UserSettingsUrl: hmnurl.BuildUserSettings(""),
LoginActionUrl: hmnurl.BuildLoginAction(c.FullUrl()),
LogoutActionUrl: hmnurl.BuildLogoutAction(c.FullUrl()),
LogoutUrl: hmnurl.BuildLogoutAction(c.FullUrl()),
ForgotPasswordUrl: hmnurl.BuildRequestPasswordReset(),
RegisterUrl: hmnurl.BuildRegister(""),
LoginWithDiscordUrl: hmnurl.BuildLoginWithDiscord(c.FullUrl()),
HMNHomepageUrl: hmnurl.BuildHomepage(),
ProjectIndexUrl: hmnurl.BuildProjectIndex(),

View File

@ -137,7 +137,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
hmnOnly.GET(hmnurl.RegexOldHome, Index)
hmnOnly.POST(hmnurl.RegexLoginAction, securityTimerMiddleware(time.Millisecond*100, Login))
hmnOnly.GET(hmnurl.RegexLogoutAction, Logout)
hmnOnly.GET(hmnurl.RegexLogout, Logout)
hmnOnly.GET(hmnurl.RegexLoginPage, LoginPage)
hmnOnly.GET(hmnurl.RegexLoginWithDiscord, LoginWithDiscord)