From e60c5399af0d71fd83fcaec8c3ce80001f0121ee Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Tue, 28 Apr 2026 19:29:14 +0530 Subject: [PATCH] feat(icon-rail): integrate user profile component and enhance layout with user settings options --- .../layout/ui/icon-rail/IconRail.tsx | 24 ++++++++++++-- .../layout/ui/shell/LayoutShell.tsx | 6 ++++ .../components/layout/ui/sidebar/Sidebar.tsx | 20 +++++++----- .../layout/ui/sidebar/SidebarUserProfile.tsx | 32 +++++++++++++------ 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx b/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx index 062e8dcb7..756d6ffaf 100644 --- a/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx +++ b/surfsense_web/components/layout/ui/icon-rail/IconRail.tsx @@ -6,6 +6,8 @@ import { ScrollArea } from "@/components/ui/scroll-area"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import type { SearchSpace } from "../../types/layout.types"; +import type { User } from "../../types/layout.types"; +import { SidebarUserProfile } from "../sidebar/SidebarUserProfile"; import { SearchSpaceAvatar } from "./SearchSpaceAvatar"; interface IconRailProps { @@ -15,6 +17,11 @@ interface IconRailProps { onSearchSpaceDelete?: (searchSpace: SearchSpace) => void; onSearchSpaceSettings?: (searchSpace: SearchSpace) => void; onAddSearchSpace: () => void; + user: User; + onUserSettings?: () => void; + onLogout?: () => void; + theme?: string; + setTheme?: (theme: "light" | "dark" | "system") => void; className?: string; } @@ -25,11 +32,16 @@ export function IconRail({ onSearchSpaceDelete, onSearchSpaceSettings, onAddSearchSpace, + user, + onUserSettings, + onLogout, + theme, + setTheme, className, }: IconRailProps) { return ( -
- +
+
{searchSpaces.map((searchSpace) => (
+
); } diff --git a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx index d41dd9e6d..4ef216bae 100644 --- a/surfsense_web/components/layout/ui/shell/LayoutShell.tsx +++ b/surfsense_web/components/layout/ui/shell/LayoutShell.tsx @@ -387,6 +387,11 @@ export function LayoutShell({ onSearchSpaceDelete={onSearchSpaceDelete} onSearchSpaceSettings={onSearchSpaceSettings} onAddSearchSpace={onAddSearchSpace} + user={user} + onUserSettings={onUserSettings} + onLogout={onLogout} + theme={theme} + setTheme={setTheme} />
@@ -423,6 +428,7 @@ export function LayoutShell({ pageUsage={pageUsage} theme={theme} setTheme={setTheme} + renderUserProfile={false} className={cn( "flex shrink-0 transition-[border-radius] duration-200", anySlideOutOpen ? "rounded-l-xl delay-0" : "rounded-xl delay-150" diff --git a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx index adad52792..f00fcee81 100644 --- a/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/Sidebar.tsx @@ -62,6 +62,7 @@ interface SidebarProps { disableTooltips?: boolean; sidebarWidth?: number; isResizing?: boolean; + renderUserProfile?: boolean; } export function Sidebar({ @@ -95,6 +96,7 @@ export function Sidebar({ disableTooltips = false, sidebarWidth = SIDEBAR_MIN_WIDTH, isResizing = false, + renderUserProfile = true, }: SidebarProps) { const t = useTranslations("sidebar"); const [openDropdownChatId, setOpenDropdownChatId] = useState(null); @@ -275,14 +277,16 @@ export function Sidebar({ - + {renderUserProfile && ( + + )} ); diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx index acece2d5c..ffd00ed14 100644 --- a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx +++ b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx @@ -113,19 +113,23 @@ function UserAvatar({ avatarUrl, initials, bgColor, + size = "sm", }: { avatarUrl?: string; initials: string; bgColor: string; + size?: "sm" | "md"; }) { + const sizeClass = size === "md" ? "h-9 w-9" : "h-8 w-8"; + if (avatarUrl) { return ( User avatar @@ -134,7 +138,10 @@ function UserAvatar({ return (
{initials} @@ -181,24 +188,29 @@ export function SidebarUserProfile({ // Collapsed view - just show avatar with dropdown if (isCollapsed) { return ( -
+
- +