From b6ac3cbb991e6ce54831fe5da002240e4c243cfd Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Thu, 19 Feb 2026 15:44:23 -0800 Subject: [PATCH] feat: user menu --- .../app/components/header/header.component.ts | 114 ++++++++++++++++-- 1 file changed, 103 insertions(+), 11 deletions(-) diff --git a/apps/frontend/src/app/components/header/header.component.ts b/apps/frontend/src/app/components/header/header.component.ts index 7dad4e8..0741dd8 100644 --- a/apps/frontend/src/app/components/header/header.component.ts +++ b/apps/frontend/src/app/components/header/header.component.ts @@ -35,17 +35,30 @@ import { ApiService } from '../../services/api.service';
@if (authService.user(); as user) { - Welcome, {{ user.username }}! - @if (!user.isAdmin) { - My Suggestions - } - My Likes - @if (user.isAdmin) { - Users - Audit - Suggestions - } - +
+ @if (user.avatar) { + + } + @if (showDropdown()) { + + } +
} @else { } @@ -122,6 +135,75 @@ import { ApiService } from '../../services/api.service'; color: var(--witch-lavender); } + .user-menu { + position: relative; + } + + .user-avatar { + width: 40px; + height: 40px; + border-radius: 50%; + border: 2px solid var(--witch-lavender); + transition: all 0.3s; + cursor: pointer; + } + + .user-avatar:hover { + border-color: var(--witch-moon); + transform: scale(1.1); + } + + .dropdown-menu { + position: absolute; + top: 50px; + right: 0; + background-color: var(--witch-purple); + border: 2px solid var(--witch-lavender); + border-radius: 8px; + padding: 0.5rem 0; + min-width: 180px; + box-shadow: 0 4px 12px var(--witch-shadow); + z-index: 1000; + animation: fadeIn 0.2s ease-in; + } + + @keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .dropdown-item { + display: block; + width: 100%; + padding: 0.75rem 1rem; + color: var(--witch-lavender); + text-decoration: none; + background: none; + border: none; + text-align: left; + font-size: 0.9rem; + cursor: pointer; + transition: all 0.2s; + } + + .dropdown-item:hover { + background-color: var(--witch-plum); + color: var(--witch-moon); + } + + .logout-btn { + border-top: 1px solid var(--witch-lavender); + margin-top: 0.5rem; + padding-top: 0.75rem; + font-weight: 500; + } + .admin-badge { background-color: var(--witch-rose); color: var(--witch-moon); @@ -190,6 +272,7 @@ export class HeaderComponent implements OnInit { authService = inject(AuthService); private apiService = inject(ApiService); version = signal(null); + showDropdown = signal(false); ngOnInit() { this.apiService.get<{ version: string }>('/version').subscribe({ @@ -198,11 +281,20 @@ export class HeaderComponent implements OnInit { }); } + toggleDropdown() { + this.showDropdown.update(v => !v); + } + + closeDropdown() { + this.showDropdown.set(false); + } + login() { this.authService.login(); } logout() { + this.closeDropdown(); this.authService.logout().subscribe(); } } \ No newline at end of file