refactor: make profile picture trigger dropdown menu

Remove separate three-dot button and make the profile picture itself trigger the dropdown menu. This provides a cleaner, more intuitive UX.
This commit is contained in:
Gigi
2025-10-23 16:49:54 +02:00
parent 59436b5b9e
commit 7d222e099f
2 changed files with 51 additions and 106 deletions

View File

@@ -1,7 +1,7 @@
import React, { useState, useRef, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronRight, faRightFromBracket, faUserCircle, faGear, faHome, faPersonHiking, faEllipsisVertical, faHighlighter, faBookmark, faPenToSquare, faLink } from '@fortawesome/free-solid-svg-icons'
import { faChevronRight, faRightFromBracket, faUserCircle, faGear, faHome, faPersonHiking, faHighlighter, faBookmark, faPenToSquare, faLink } from '@fortawesome/free-solid-svg-icons'
import { Hooks } from 'applesauce-react'
import { useEventModel } from 'applesauce-react/hooks'
import { Models } from 'applesauce-core'
@@ -62,11 +62,11 @@ const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogou
<>
<div className="sidebar-header-bar">
{activeAccount && (
<div className="profile-avatar-container">
<div className="profile-menu-wrapper" ref={menuRef}>
<button
className="profile-avatar-button"
title={getUserDisplayName()}
onClick={() => navigate('/my')}
onClick={() => setShowProfileMenu(!showProfileMenu)}
aria-label={`Profile: ${getUserDisplayName()}`}
>
{profileImage ? (
@@ -75,63 +75,53 @@ const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogou
<FontAwesomeIcon icon={faUserCircle} />
)}
</button>
<div className="profile-menu-wrapper" ref={menuRef}>
<button
className="profile-menu-trigger"
onClick={() => setShowProfileMenu(!showProfileMenu)}
aria-label="Profile menu"
title="Profile menu"
>
<FontAwesomeIcon icon={faEllipsisVertical} />
</button>
{showProfileMenu && (
<div className="profile-dropdown-menu">
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/highlights'))}
>
<FontAwesomeIcon icon={faHighlighter} />
<span>My Highlights</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/bookmarks'))}
>
<FontAwesomeIcon icon={faBookmark} />
<span>My Bookmarks</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/reads'))}
>
<FontAwesomeIcon icon={faBooks} />
<span>My Reads</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/links'))}
>
<FontAwesomeIcon icon={faLink} />
<span>My Links</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/writings'))}
>
<FontAwesomeIcon icon={faPenToSquare} />
<span>My Writings</span>
</button>
<div className="profile-menu-separator"></div>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(onLogout)}
>
<FontAwesomeIcon icon={faRightFromBracket} />
<span>Logout</span>
</button>
</div>
)}
</div>
{showProfileMenu && (
<div className="profile-dropdown-menu">
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/highlights'))}
>
<FontAwesomeIcon icon={faHighlighter} />
<span>My Highlights</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/bookmarks'))}
>
<FontAwesomeIcon icon={faBookmark} />
<span>My Bookmarks</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/reads'))}
>
<FontAwesomeIcon icon={faBooks} />
<span>My Reads</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/links'))}
>
<FontAwesomeIcon icon={faLink} />
<span>My Links</span>
</button>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(() => navigate('/my/writings'))}
>
<FontAwesomeIcon icon={faPenToSquare} />
<span>My Writings</span>
</button>
<div className="profile-menu-separator"></div>
<button
className="profile-menu-item"
onClick={() => handleMenuItemClick(onLogout)}
>
<FontAwesomeIcon icon={faRightFromBracket} />
<span>Logout</span>
</button>
</div>
)}
</div>
)}
<div className="sidebar-header-right">

View File

@@ -132,56 +132,11 @@
.profile-avatar-button img { width: 100%; height: 100%; object-fit: cover; }
.profile-avatar-button svg { font-size: 1rem; }
/* Profile menu container */
.profile-avatar-container {
display: flex;
align-items: center;
gap: 0.25rem;
position: relative;
}
/* Profile menu trigger button */
/* Profile menu wrapper */
.profile-menu-wrapper {
position: relative;
}
.profile-menu-trigger {
min-width: 33px;
min-height: 33px;
width: 33px;
height: 33px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 1px solid var(--color-border-subtle);
color: var(--color-text);
cursor: pointer;
transition: all 0.2s ease;
padding: 0;
box-sizing: border-box;
}
/* Mobile touch target improvements */
@media (max-width: 768px) {
.profile-menu-trigger {
min-width: var(--min-touch-target);
min-height: var(--min-touch-target);
width: var(--min-touch-target);
height: var(--min-touch-target);
}
}
.profile-menu-trigger:hover {
background: var(--color-bg-hover);
border-color: var(--color-border);
}
.profile-menu-trigger svg {
font-size: 0.875rem;
}
/* Dropdown menu */
.profile-dropdown-menu {
position: absolute;