diff --git a/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/ProfileContent.tsx b/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/ProfileContent.tsx index f3bce2ef1..c2736f208 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/ProfileContent.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/ProfileContent.tsx @@ -26,6 +26,7 @@ function AvatarDisplay({ url, fallback }: { url?: string; fallback: string }) { height={64} className="h-16 w-16 rounded-xl object-cover" onError={() => setErrorUrl(url)} + unoptimized /> ); } diff --git a/surfsense_web/app/dashboard/[search_space_id]/user-settings/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/user-settings/page.tsx index 019684a95..53f1182eb 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/user-settings/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/user-settings/page.tsx @@ -2,6 +2,8 @@ import { UserKey, User } from "lucide-react"; import { useTranslations } from "next-intl"; +import { useRouter, useSearchParams } from "next/navigation"; +import { useCallback } from "react"; import { Tabs, TabsContent, @@ -11,13 +13,32 @@ import { import { ApiKeyContent } from "./components/ApiKeyContent"; import { ProfileContent } from "./components/ProfileContent"; +const VALID_TABS = ["profile", "api-key"] as const; +const DEFAULT_TAB = "profile"; + export default function UserSettingsPage() { const t = useTranslations("userSettings"); + const router = useRouter(); + const searchParams = useSearchParams(); + + const tabParam = searchParams.get("tab") ?? ""; + const activeTab = VALID_TABS.includes(tabParam as (typeof VALID_TABS)[number]) + ? tabParam + : DEFAULT_TAB; + + const handleTabChange = useCallback( + (value: string) => { + const params = new URLSearchParams(searchParams.toString()); + params.set("tab", value); + router.replace(`?${params.toString()}`, { scroll: false }); + }, + [router, searchParams] + ); return (
- + diff --git a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx index b0ff496f6..90ddbdf74 100644 --- a/surfsense_web/components/layout/providers/LayoutDataProvider.tsx +++ b/surfsense_web/components/layout/providers/LayoutDataProvider.tsx @@ -304,7 +304,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid }, []); const handleUserSettings = useCallback(() => { - router.push(`/dashboard/${searchSpaceId}/user-settings`); + router.push(`/dashboard/${searchSpaceId}/user-settings?tab=profile`); }, [router, searchSpaceId]); const handleSearchSpaceSettings = useCallback( diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx index 25e19a9a7..a314690c1 100644 --- a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx +++ b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx @@ -1,6 +1,7 @@ "use client"; import { Check, ChevronUp, Languages, Laptop, LogOut, Moon, Settings, Sun } from "lucide-react"; +import Image from "next/image"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { @@ -16,7 +17,6 @@ import { DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Spinner } from "@/components/ui/spinner"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { useLocaleContext } from "@/contexts/LocaleContext"; import { cn } from "@/lib/utils"; import type { User } from "../../types/layout.types"; @@ -100,11 +100,14 @@ function UserAvatar({ }) { if (avatarUrl) { return ( - User avatar ); } @@ -156,26 +159,21 @@ export function SidebarUserProfile({ if (isCollapsed) { return (
- - - - - - - - {displayName} - + + + +