feat: show login button when logged out instead of logout button

- Added onLogin prop to Bookmarks, BookmarkList, and SidebarHeader
- SidebarHeader now conditionally renders login or logout button
- Login button uses faRightToBracket icon
- Logout button uses faRightFromBracket icon
- Clicking login button navigates to /login route
- Created BookmarksRoute wrapper to handle navigation
- Better UX for anonymous users browsing articles
This commit is contained in:
Gigi
2025-10-05 13:12:32 +01:00
parent 0bc89889e0
commit 1552dd85d9
4 changed files with 42 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react'
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { BrowserRouter, Routes, Route, Navigate, useNavigate } from 'react-router-dom'
import { EventStoreProvider, AccountsProvider } from 'applesauce-react'
import { EventStore } from 'applesauce-core'
import { AccountManager } from 'applesauce-accounts'
@@ -12,6 +12,18 @@ import Bookmarks from './components/Bookmarks'
const DEFAULT_ARTICLE = import.meta.env.VITE_DEFAULT_ARTICLE_NADDR ||
'naddr1qvzqqqr4gupzqmjxss3dld622uu8q25gywum9qtg4w4cv4064jmg20xsac2aam5nqqxnzd3cxqmrzv3exgmr2wfesgsmew'
function BookmarksRoute({ relayPool }: { relayPool: RelayPool | null }) {
const navigate = useNavigate()
return (
<Bookmarks
relayPool={relayPool}
onLogout={() => {}}
onLogin={() => navigate('/login')}
/>
)
}
function App() {
const [eventStore, setEventStore] = useState<EventStore | null>(null)
const [accountManager, setAccountManager] = useState<AccountManager | null>(null)
@@ -71,12 +83,7 @@ function App() {
<Routes>
<Route
path="/a/:naddr"
element={
<Bookmarks
relayPool={relayPool}
onLogout={() => {}}
/>
}
element={<BookmarksRoute relayPool={relayPool} />}
/>
<Route path="/" element={<Navigate to={`/a/${DEFAULT_ARTICLE}`} replace />} />
<Route path="/login" element={<Login onLogin={() => {}} />} />

View File

@@ -13,18 +13,20 @@ interface BookmarkListProps {
isCollapsed: boolean
onToggleCollapse: () => void
onLogout: () => void
onLogin?: () => void
viewMode: ViewMode
onViewModeChange: (mode: ViewMode) => void
selectedUrl?: string
onOpenSettings: () => void
}
export const BookmarkList: React.FC<BookmarkListProps> = ({
bookmarks,
export const BookmarkList: React.FC<BookmarkListProps> = ({
bookmarks,
onSelectUrl,
isCollapsed,
onToggleCollapse,
onLogout,
onLogin,
viewMode,
onViewModeChange,
selectedUrl,
@@ -57,6 +59,7 @@ export const BookmarkList: React.FC<BookmarkListProps> = ({
<SidebarHeader
onToggleCollapse={onToggleCollapse}
onLogout={onLogout}
onLogin={onLogin}
viewMode={viewMode}
onViewModeChange={onViewModeChange}
onOpenSettings={onOpenSettings}

View File

@@ -22,9 +22,10 @@ export type ViewMode = 'compact' | 'cards' | 'large'
interface BookmarksProps {
relayPool: RelayPool | null
onLogout: () => void
onLogin?: () => void
}
const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout, onLogin }) => {
const { naddr } = useParams<{ naddr?: string }>()
const [bookmarks, setBookmarks] = useState<Bookmark[]>([])
const [highlights, setHighlights] = useState<Highlight[]>([])
@@ -144,6 +145,7 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
isCollapsed={isCollapsed}
onToggleCollapse={() => setIsCollapsed(!isCollapsed)}
onLogout={onLogout}
onLogin={onLogin}
viewMode={viewMode}
onViewModeChange={setViewMode}
selectedUrl={selectedUrl}

View File

@@ -1,6 +1,6 @@
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronRight, faRightFromBracket, faUser, faList, faThLarge, faImage, faGear } from '@fortawesome/free-solid-svg-icons'
import { faChevronRight, faRightFromBracket, faRightToBracket, faUser, faList, faThLarge, faImage, faGear } from '@fortawesome/free-solid-svg-icons'
import { Hooks } from 'applesauce-react'
import { useEventModel } from 'applesauce-react/hooks'
import { Models } from 'applesauce-core'
@@ -10,12 +10,13 @@ import { ViewMode } from './Bookmarks'
interface SidebarHeaderProps {
onToggleCollapse: () => void
onLogout: () => void
onLogin?: () => void
viewMode: ViewMode
onViewModeChange: (mode: ViewMode) => void
onOpenSettings: () => void
}
const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogout, viewMode, onViewModeChange, onOpenSettings }) => {
const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogout, onLogin, viewMode, onViewModeChange, onOpenSettings }) => {
const activeAccount = Hooks.useActiveAccount()
const profile = useEventModel(Models.ProfileModel, activeAccount ? [activeAccount.pubkey] : null)
@@ -58,13 +59,23 @@ const SidebarHeader: React.FC<SidebarHeaderProps> = ({ onToggleCollapse, onLogou
ariaLabel="Settings"
variant="ghost"
/>
<IconButton
icon={faRightFromBracket}
onClick={onLogout}
title="Logout"
ariaLabel="Logout"
variant="ghost"
/>
{activeAccount ? (
<IconButton
icon={faRightFromBracket}
onClick={onLogout}
title="Logout"
ariaLabel="Logout"
variant="ghost"
/>
) : onLogin ? (
<IconButton
icon={faRightToBracket}
onClick={onLogin}
title="Login"
ariaLabel="Login"
variant="ghost"
/>
) : null}
</div>
<div className="view-mode-controls">
<IconButton