Fix sidebar footer overflow from the change-password link
All checks were successful
CI / backend (push) Successful in 1m23s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s

Adding the Change Password action turned the user menu into a
full-width-button row that overflowed the fixed sidebar. The footer is
now an identity row (avatar + truncating name) above a compact
icon-button actions row (Password / Logout), both within bounds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-12 12:28:08 -04:00
parent 4b20c2eb56
commit 55b42fed00

View File

@@ -39,14 +39,22 @@
<div class="user-menu">
<template v-if="authStore.isAuthenticated">
<img v-if="authStore.avatarUrl" :src="authStore.avatarUrl" class="user-avatar"
:alt="authStore.displayName" @error="onAvatarError" />
<div class="user-ident">
<div class="username">{{ authStore.displayName }}</div>
<div v-if="authStore.displayName !== authStore.username" class="user-sso">{{ authStore.username }}</div>
<div class="user-identity">
<img v-if="authStore.avatarUrl" :src="authStore.avatarUrl" class="user-avatar"
:alt="authStore.displayName" @error="onAvatarError" />
<div class="user-ident">
<div class="username">{{ authStore.displayName }}</div>
<div v-if="authStore.displayName !== authStore.username" class="user-sso">{{ authStore.username }}</div>
</div>
</div>
<div class="user-actions">
<router-link to="/change-password" class="icon-btn" title="Change password">
<KeyRound :size="16" /> Password
</router-link>
<button class="icon-btn" @click="handleLogout" title="Log out">
<LogOut :size="16" /> Logout
</button>
</div>
<router-link to="/change-password" class="btn btn-secondary">Change password</router-link>
<button class="btn btn-secondary" @click="handleLogout">Logout</button>
</template>
<router-link v-else to="/login" class="btn btn-primary">Login</router-link>
</div>
@@ -92,7 +100,8 @@ import { useRouter, useRoute } from 'vue-router'
import ToastHost from '../components/ToastHost.vue'
import {
Sun, Moon, LayoutDashboard, Calendar, Map, Cog, Monitor,
Printer, Globe, Usb, AppWindow, BookOpen, BarChart3, Bell, Image, ShieldCheck, Ruler
Printer, Globe, Usb, AppWindow, BookOpen, BarChart3, Bell, Image, ShieldCheck, Ruler,
KeyRound, LogOut
} from 'lucide-vue-next'
import { useAuthStore } from '../stores/auth'
import { currentTheme, toggleTheme } from '../stores/theme'
@@ -238,8 +247,31 @@ function onAvatarError(event) {
</script>
<style scoped>
.user-menu { display: flex; align-items: center; gap: 0.6rem; }
.user-avatar { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid var(--border); }
.user-ident { display: flex; flex-direction: column; line-height: 1.1; }
.user-sso { font-size: 0.72rem; color: var(--text-light); }
/* Footer user block: identity row on top, compact icon actions below, all
kept inside the fixed-width sidebar (no full-width buttons overflowing). */
.user-menu { display: flex; flex-direction: column; gap: 0.6rem; }
.user-identity { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.user-avatar { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; border: 1px solid var(--border); flex-shrink: 0; }
.user-ident { display: flex; flex-direction: column; line-height: 1.1; min-width: 0; }
.user-ident .username { margin-bottom: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-sso { font-size: 0.72rem; color: var(--text-light); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-actions { display: flex; gap: 0.5rem; }
.icon-btn {
flex: 1 1 0;
min-width: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 0.35rem;
padding: 0.4rem 0.5rem;
background: rgba(255,255,255,0.08);
border: 1px solid rgba(255,255,255,0.15);
border-radius: 6px;
color: rgba(255,255,255,0.8);
font-size: 12px;
cursor: pointer;
text-decoration: none;
}
.icon-btn:hover { background: rgba(255,255,255,0.16); color: #fff; }
</style>