import {ReactElement, ReactNode} from 'react'; import clsx from 'clsx'; import {useAuth} from '@common/auth/use-auth'; import {NotificationDialogTrigger} from '@common/notifications/dialog/notification-dialog-trigger'; import {Menu, MenuTrigger} from '@common/ui/navigation/menu/menu-trigger'; import {useCustomMenu} from '@common/menus/use-custom-menu'; import {createSvgIconFromTree} from '@common/icons/create-svg-icon'; import {Trans} from '@common/i18n/trans'; import {IconButton} from '@common/ui/buttons/icon-button'; import {Item} from '@common/ui/forms/listbox/item'; import {useNavigate} from '@common/utils/hooks/use-navigate'; import {useIsDarkMode} from '@common/ui/themes/use-is-dark-mode'; import {CustomMenu} from '@common/menus/custom-menu'; import {useSettings} from '@common/core/settings/use-settings'; import {ButtonColor} from '@common/ui/buttons/get-shared-button-style'; import {MenuIcon} from '@common/icons/material/Menu'; import {MenuItemConfig} from '@common/core/settings/settings'; import { NavbarAuthUser, NavbarAuthUserProps, } from '@common/ui/navigation/navbar/navbar-auth-user'; import {NavbarAuthButtons} from '@common/ui/navigation/navbar/navbar-auth-buttons'; import {useDarkThemeVariables} from '@common/ui/themes/use-dark-theme-variables'; import {Logo} from '@common/ui/navigation/navbar/logo'; type NavbarColor = 'primary' | 'bg' | 'bg-alt' | 'transparent' | string; export interface NavbarProps { hideLogo?: boolean | null; toggleButton?: ReactElement; children?: ReactNode; className?: string; color?: NavbarColor; bgOpacity?: number | string; darkModeColor?: NavbarColor; logoColor?: 'dark' | 'light'; textColor?: string; primaryButtonColor?: ButtonColor; border?: string; size?: 'xs' | 'sm' | 'md'; rightChildren?: ReactNode; menuPosition?: string; authMenuItems?: NavbarAuthUserProps['items']; alwaysDarkMode?: boolean; wrapInContainer?: boolean; } export function Navbar(props: NavbarProps) { let { hideLogo, toggleButton, children, className, border, size = 'md', color = 'primary', textColor, darkModeColor = 'bg-alt', rightChildren, menuPosition, logoColor, primaryButtonColor, authMenuItems, alwaysDarkMode = false, wrapInContainer = false, } = props; const isDarkMode = useIsDarkMode() || alwaysDarkMode; const {notifications} = useSettings(); const {isLoggedIn} = useAuth(); const darkThemeVars = useDarkThemeVariables(); const showNotifButton = isLoggedIn && notifications?.integrated; if (isDarkMode) { color = darkModeColor; } return (
{!hideLogo && ( )} {toggleButton} {children}
{rightChildren} {showNotifButton && } {isLoggedIn ? ( ) : ( )}
); } interface DesktopMenuProps { position: NavbarProps['menuPosition']; } function DesktopMenu({position}: DesktopMenuProps) { return ( clsx( 'opacity-90 hover:underline hover:opacity-100', isActive && 'opacity-100', ) } menu={position} /> ); } interface MobileMenuProps { position: NavbarProps['menuPosition']; } function MobileMenu({position}: MobileMenuProps) { const navigate = useNavigate(); const menu = useCustomMenu(position); if (!menu?.items.length) { return null; } const handleItemClick = (item: MenuItemConfig) => { if (item.type === 'route') { navigate(item.action); } else { window.open(item.action, item.target)?.focus(); } }; return ( {menu.items.map(item => { const Icon = item.icon && createSvgIconFromTree(item.icon); return ( handleItemClick(item)} key={item.id} startIcon={Icon && } > ); })} ); } function getColorStyle(color: string, textColor?: string): string { switch (color) { case 'primary': return `bg-primary ${textColor || 'text-on-primary'} border-b-primary`; case 'bg': return `bg ${textColor || 'text-main'} border-b`; case 'bg-alt': return `bg-alt ${textColor || 'text-main'} border-b`; case 'transparent': return `bg-transparent ${textColor || 'text-white'}`; default: return `${color} ${textColor}`; } }