From c12f795026fcb942694671b334ae562cdb59a7cf Mon Sep 17 00:00:00 2001 From: Richard R Date: Thu, 28 May 2026 14:58:03 -0600 Subject: [PATCH] feat(ui): move app actions to sidebar and add sidebar user menu variant Shift app-level actions (settings and user menu) from the top bar to the bottom of the sidebar for improved navigation consistency. Introduce a new "sidebar" variant for the UserMenu component with tailored styling and behavior for sidebar placement. Update SettingsModal to support a customizable trigger label and styling for sidebar integration. Refactor FinderSidebar to accept an optional bottomSlot, enabling flexible placement of sidebar controls. --- src/components/HomeContent.tsx | 11 +- src/components/SettingsModal.tsx | 9 +- src/components/auth/UserMenu.tsx | 49 +++- src/components/doclist/DocumentList.tsx | 2 +- .../doclist/window/FinderSidebar.tsx | 239 +++++++++--------- 5 files changed, 188 insertions(+), 122 deletions(-) diff --git a/src/components/HomeContent.tsx b/src/components/HomeContent.tsx index 6cc2be8..8e9240f 100644 --- a/src/components/HomeContent.tsx +++ b/src/components/HomeContent.tsx @@ -15,10 +15,13 @@ const Brand = () => ( ); const AppActions = () => ( - <> - - - +
+ + +
); export function HomeContent() { diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx index 67b49ec..8b3c0e4 100644 --- a/src/components/SettingsModal.tsx +++ b/src/components/SettingsModal.tsx @@ -130,7 +130,13 @@ const SIDEBAR_SECTIONS: SidebarSection[] = [ type AdminSubTab = 'providers' | 'features'; -export function SettingsModal({ className = '' }: { className?: string }) { +export function SettingsModal({ + className = '', + triggerLabel, +}: { + className?: string; + triggerLabel?: string; +}) { const runtimeConfig = useRuntimeConfig(); const enableDestructiveDelete = runtimeConfig.enableDestructiveDeleteActions; const showAllProviderModels = runtimeConfig.showAllProviderModels; @@ -506,6 +512,7 @@ export function SettingsModal({ className = '' }: { className?: string }) { tabIndex={0} > + {triggerLabel && {triggerLabel}} diff --git a/src/components/auth/UserMenu.tsx b/src/components/auth/UserMenu.tsx index d350f79..529dac3 100644 --- a/src/components/auth/UserMenu.tsx +++ b/src/components/auth/UserMenu.tsx @@ -7,8 +7,17 @@ import { useFeatureFlag } from '@/contexts/RuntimeConfigContext'; import { useAuthSession } from '@/hooks/useAuthSession'; import { getAuthClient } from '@/lib/client/auth-client'; import { useRouter } from 'next/navigation'; +import { UserIcon } from '@/components/icons/Icons'; -export function UserMenu({ className = '' }: { className?: string }) { +type UserMenuVariant = 'toolbar' | 'sidebar'; + +export function UserMenu({ + className = '', + variant = 'toolbar', +}: { + className?: string; + variant?: UserMenuVariant; +}) { const { authEnabled, baseUrl } = useAuthConfig(); const enableUserSignups = useFeatureFlag('enableUserSignups'); const { data: session, isPending } = useAuthSession(); @@ -22,7 +31,27 @@ export function UserMenu({ className = '' }: { className?: string }) { router.push('/signin'); }; + const rowClass = + 'w-full inline-flex items-center gap-2 px-2 py-1 rounded-md text-[12px] border border-transparent transition-all duration-200 ease-out text-left hover:scale-[1.01] hover:border-accent hover:bg-offbase hover:text-accent'; + if (!session || session.user.isAnonymous) { + if (variant === 'sidebar') { + return ( +
+ + + Connect + + {enableUserSignups && ( + + + Create account + + )} +
+ ); + } + return (
@@ -41,6 +70,24 @@ export function UserMenu({ className = '' }: { className?: string }) { ); } + if (variant === 'sidebar') { + return ( + + ); + } + return (
diff --git a/src/components/doclist/DocumentList.tsx b/src/components/doclist/DocumentList.tsx index 2233e90..6e484e6 100644 --- a/src/components/doclist/DocumentList.tsx +++ b/src/components/doclist/DocumentList.tsx @@ -502,7 +502,6 @@ function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { isSidebarOpen={effectiveSidebarOpen} isNarrow={isNarrow} leftSlot={brand} - rightSlot={appActions} /> } sidebar={ @@ -521,6 +520,7 @@ function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { width={sidebarWidth} onWidthChange={setSidebarWidth} topSlot={} + bottomSlot={appActions} /> } statusBar={ diff --git a/src/components/doclist/window/FinderSidebar.tsx b/src/components/doclist/window/FinderSidebar.tsx index 358eded..d754336 100644 --- a/src/components/doclist/window/FinderSidebar.tsx +++ b/src/components/doclist/window/FinderSidebar.tsx @@ -22,6 +22,7 @@ interface FinderSidebarProps { width: number; onWidthChange: (px: number) => void; topSlot?: ReactNode; + bottomSlot?: ReactNode; } const MIN_WIDTH = 168; @@ -180,6 +181,7 @@ export function FinderSidebar({ width, onWidthChange, topSlot, + bottomSlot, }: FinderSidebarProps) { const startRef = useRef<{ x: number; w: number } | null>(null); @@ -201,124 +203,131 @@ export function FinderSidebar({ return (