diff --git a/package.json b/package.json index 44ec9f08..3328c5c7 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "@react-spring/web": "^10.0.1", "@svgr/cli": "^8.1.0", "@tanstack/react-query": "^5.85.5", - "@umami/react-zen": "^0.186.0", + "@umami/react-zen": "^0.187.0", "@umami/redis-client": "^0.29.0", "bcryptjs": "^3.0.2", "chalk": "^5.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f3fdc90..61707399 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,8 +45,8 @@ importers: specifier: ^5.85.5 version: 5.85.5(react@19.1.1) '@umami/react-zen': - specifier: ^0.186.0 - version: 0.186.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + specifier: ^0.187.0 + version: 0.187.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) '@umami/redis-client': specifier: ^0.29.0 version: 0.29.0 @@ -2738,8 +2738,8 @@ packages: '@prisma/client': ^6.1.0 '@prisma/extension-read-replicas': ^0.4.1 - '@umami/react-zen@0.186.0': - resolution: {integrity: sha512-s+x4cJK5UTHQ0l2TTUb3zX8P2U6bMw35NRjIqG+OJvljJf5NNdRo6WChZOvnh/08XxGI30jntFhUYdup255rFg==} + '@umami/react-zen@0.187.0': + resolution: {integrity: sha512-CiTGBqEvN/dcZ1Tq4R+mj9ynN1opZF81iukUzElChJ5XF/Ec9HhPR+KM2r8PXt+uWeVVe1aZtjyVOdwUR/ndXg==} '@umami/redis-client@0.29.0': resolution: {integrity: sha512-Jaqh++jskqDB7ny75pfC02OvKp1JTS4asGDsFrRL3qy8sxL3PAl9+/mybCJe4/6vWrXDJKqpgkSfUDJq2bFjyw==} @@ -10343,7 +10343,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@umami/react-zen@0.186.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1))': + '@umami/react-zen@0.187.0(@babel/core@7.28.3)(@types/react@19.1.12)(babel-plugin-react-compiler@19.1.0-rc.2)(immer@10.1.1)(use-sync-external-store@1.5.0(react@19.1.1))': dependencies: '@fontsource/jetbrains-mono': 5.2.8 '@internationalized/date': 3.9.0 diff --git a/src/app/Providers.tsx b/src/app/Providers.tsx index 77be5201..b8898e88 100644 --- a/src/app/Providers.tsx +++ b/src/app/Providers.tsx @@ -36,9 +36,21 @@ function MessagesProvider({ children }) { export function Providers({ children }) { const router = useRouter(); + function navigate(url: string) { + if (shouldUseNativeLink(url)) { + window.location.href = url; + } else { + router.push(url); + } + } + + function shouldUseNativeLink(url: string) { + return url.startsWith('http'); + } + return ( - + {children} diff --git a/src/components/input/NavButton.tsx b/src/components/input/NavButton.tsx index ebe1a19a..39bff58d 100644 --- a/src/components/input/NavButton.tsx +++ b/src/components/input/NavButton.tsx @@ -6,27 +6,48 @@ import { MenuTrigger, MenuSection, MenuSeparator, + SubmenuTrigger, Popover, Row, Column, Pressable, + IconLabel, } from '@umami/react-zen'; -import { useLoginQuery, useMessages, useNavigation } from '@/components/hooks'; -import { ChevronRight, User, Users } from '@/components/icons'; +import { useConfig, useLoginQuery, useMessages, useNavigation } from '@/components/hooks'; +import { + BookText, + ChevronRight, + ExternalLink, + LifeBuoy, + LockKeyhole, + LogOut, + Settings, + User, + Users, +} from '@/components/icons'; +import { DOCS_URL } from '@/lib/constants'; +import * as url from 'node:url'; export interface TeamsButtonProps { showText?: boolean; onAction?: (id: any) => void; } -export function NavButton({ showText = true, onAction }: TeamsButtonProps) { +export function NavButton({ showText = true }: TeamsButtonProps) { const { user } = useLoginQuery(); + const { cloudMode } = useConfig(); const { formatMessage, labels } = useMessages(); const { teamId } = useNavigation(); const team = user?.teams?.find(({ id }) => id === teamId); const selectedKeys = new Set([teamId || 'user']); const label = teamId ? team?.name : user.username; + const getUrl = (url: string) => { + return cloudMode ? `${process.env.cloudUrl}/${url}` : url; + }; + + const handleAction = async () => {}; + return ( @@ -58,31 +79,67 @@ export function NavButton({ showText = true, onAction }: TeamsButtonProps) { selectionMode="single" selectedKeys={selectedKeys} autoFocus="last" - onAction={onAction} + onAction={handleAction} > - - - - - - {user.username} - + + } label={user.username} /> - - {user?.teams?.map(({ id, name }) => ( - - - - - - {name} - + + + } label={formatMessage(labels.teams)} /> + + + + + + {user?.teams?.map(({ id, name }) => ( + + + + + + {name} + + + ))} + + + + + + } label={formatMessage(labels.settings)} /> + {cloudMode && ( + <> + } + label={formatMessage(labels.documentation)} + > + + + - ))} - + } + label={formatMessage(labels.support)} + /> + + )} + {user.isAdmin && ( + <> + + } label={formatMessage(labels.admin)} /> + + )} + + } label={formatMessage(labels.logout)} />