refactor(ui): move user info and logout to sidebar header bar

- Create new SidebarHeader component as bar-shaped container
- Combine collapse button, user info, and logout button in one bar
- Position header bar at top of bookmark sidebar with matching width
- Remove fixed top-right positioning for user header
- Style as cohesive bar with background, border, and spacing
- Update all prop passing from App through Bookmarks to BookmarkList
- Remove old UserHeader component
This commit is contained in:
Gigi
2025-10-03 02:00:54 +02:00
parent 8014ee4ddd
commit 55c4fe9d4e
5 changed files with 51 additions and 45 deletions

View File

@@ -6,7 +6,6 @@ import { RelayPool } from 'applesauce-relay'
import { createAddressLoader } from 'applesauce-loaders/loaders'
import Login from './components/Login'
import Bookmarks from './components/Bookmarks'
import UserHeader from './components/UserHeader'
function App() {
const [eventStore, setEventStore] = useState<EventStore | null>(null)
@@ -64,13 +63,13 @@ function App() {
<EventStoreProvider eventStore={eventStore}>
<AccountsProvider manager={accountManager}>
<div className="app">
{isAuthenticated && (
<UserHeader onLogout={() => setIsAuthenticated(false)} />
)}
{!isAuthenticated ? (
<Login onLogin={() => setIsAuthenticated(true)} />
) : (
<Bookmarks relayPool={relayPool} />
<Bookmarks
relayPool={relayPool}
onLogout={() => setIsAuthenticated(false)}
/>
)}
</div>
</AccountsProvider>

View File

@@ -1,22 +1,25 @@
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons'
import { faChevronRight } from '@fortawesome/free-solid-svg-icons'
import { Bookmark } from '../types/bookmarks'
import { BookmarkItem } from './BookmarkItem'
import { formatDate, renderParsedContent } from '../utils/bookmarkUtils'
import SidebarHeader from './SidebarHeader'
interface BookmarkListProps {
bookmarks: Bookmark[]
onSelectUrl?: (url: string) => void
isCollapsed: boolean
onToggleCollapse: () => void
onLogout: () => void
}
export const BookmarkList: React.FC<BookmarkListProps> = ({
bookmarks,
onSelectUrl,
isCollapsed,
onToggleCollapse
onToggleCollapse,
onLogout
}) => {
if (isCollapsed) {
return (
@@ -35,16 +38,7 @@ export const BookmarkList: React.FC<BookmarkListProps> = ({
return (
<div className="bookmarks-container">
<div className="bookmarks-header">
<button
onClick={onToggleCollapse}
className="toggle-sidebar-btn"
title="Collapse bookmarks sidebar"
aria-label="Collapse bookmarks sidebar"
>
<FontAwesomeIcon icon={faChevronLeft} />
</button>
</div>
<SidebarHeader onToggleCollapse={onToggleCollapse} onLogout={onLogout} />
{bookmarks.length === 0 ? (
<div className="empty-state">

View File

@@ -9,9 +9,10 @@ import { fetchReadableContent, ReadableContent } from '../services/readerService
interface BookmarksProps {
relayPool: RelayPool | null
onLogout: () => void
}
const Bookmarks: React.FC<BookmarksProps> = ({ relayPool }) => {
const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
const [bookmarks, setBookmarks] = useState<Bookmark[]>([])
const [loading, setLoading] = useState(true)
const [selectedUrl, setSelectedUrl] = useState<string | undefined>(undefined)
@@ -83,6 +84,7 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool }) => {
onSelectUrl={handleSelectUrl}
isCollapsed={isCollapsed}
onToggleCollapse={() => setIsCollapsed(!isCollapsed)}
onLogout={onLogout}
/>
</div>
<div className="pane main">

View File

@@ -1,15 +1,17 @@
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronLeft, faRightFromBracket } from '@fortawesome/free-solid-svg-icons'
import { Hooks } from 'applesauce-react'
import { useEventModel } from 'applesauce-react/hooks'
import { Models } from 'applesauce-core'
import { faRightFromBracket } from '@fortawesome/free-solid-svg-icons'
import IconButton from './IconButton'
interface UserHeaderProps {
interface SidebarHeaderProps {
onToggleCollapse: () => void
onLogout: () => void
}
const UserHeader: React.FC<UserHeaderProps> = ({ onLogout }) => {
const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogout }) => {
const activeAccount = Hooks.useActiveAccount()
const profile = useEventModel(Models.ProfileModel, activeAccount ? [activeAccount.pubkey] : null)
@@ -30,7 +32,15 @@ const UserHeader: React.FC<UserHeaderProps> = ({ onLogout }) => {
}
return (
<div className="app-header">
<div className="sidebar-header-bar">
<button
onClick={onToggleCollapse}
className="toggle-sidebar-btn"
title="Collapse bookmarks sidebar"
aria-label="Collapse bookmarks sidebar"
>
<FontAwesomeIcon icon={faChevronLeft} />
</button>
<p className="user-info">Logged in as: {formatUserDisplay()}</p>
<IconButton
icon={faRightFromBracket}
@@ -43,5 +53,5 @@ const UserHeader: React.FC<UserHeaderProps> = ({ onLogout }) => {
)
}
export default UserHeader
export default SidebarHeader

View File

@@ -31,20 +31,6 @@ body {
position: relative;
}
.app-header {
position: fixed;
top: 1rem;
right: 2rem;
z-index: 1000;
display: flex;
align-items: center;
gap: 1rem;
}
.app-header .user-info {
margin: 0;
}
.app header {
margin-bottom: 2rem;
}
@@ -112,18 +98,32 @@ body {
text-align: left;
}
.bookmarks-header {
.sidebar-header-bar {
display: flex;
justify-content: flex-start;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
padding: 0.75rem 1rem;
background: #1a1a1a;
border: 1px solid #333;
border-radius: 8px;
margin-bottom: 1rem;
}
.toggle-sidebar-btn {
background: #2a2a2a;
.sidebar-header-bar .user-info {
flex: 1;
margin: 0;
font-size: 0.85rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.sidebar-header-bar .toggle-sidebar-btn {
background: transparent;
color: #ddd;
border: 1px solid #444;
padding: 0.5rem 0.75rem;
padding: 0.4rem;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
@@ -132,14 +132,15 @@ body {
justify-content: center;
min-width: 33px;
min-height: 33px;
flex-shrink: 0;
}
.toggle-sidebar-btn:hover {
background: #333;
.sidebar-header-bar .toggle-sidebar-btn:hover {
background: #2a2a2a;
color: #fff;
}
.toggle-sidebar-btn:active {
.sidebar-header-bar .toggle-sidebar-btn:active {
transform: translateY(1px);
}