// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors
// SPDX-License-Identifier: Apache-2.0
import { Group, AppShell as MantineAppShell, Menu, Text, UnstyledButton } from '@mantine/core';
import { formatHumanName } from '@medplum/core';
import type { HumanName } from '@medplum/fhirtypes';
import { useMedplumProfile } from '@medplum/react-hooks';
import { IconChevronDown } from '@tabler/icons-react';
import type { JSX, ReactNode } from 'react';
import { useState } from 'react';
import { ResourceAvatar } from '../ResourceAvatar/ResourceAvatar';
import classes from './Header.module.css';
import { HeaderDropdown } from './HeaderDropdown';
import { HeaderSearchInput } from './HeaderSearchInput';
export interface HeaderProps {
readonly pathname?: string;
readonly searchParams?: URLSearchParams;
readonly headerSearchDisabled?: boolean;
readonly logo: ReactNode;
readonly version?: string;
readonly navbarOpen?: boolean;
readonly navbarToggle: () => void;
readonly notifications?: ReactNode;
}
export function Header(props: HeaderProps): JSX.Element {
const profile = useMedplumProfile();
const [userMenuOpened, setUserMenuOpened] = useState(false);
return (
<MantineAppShell.Header p={8} style={{ zIndex: 101 }}>
<Group justify="space-between">
<Group gap="xs">
<UnstyledButton
className={classes.logoButton}
aria-expanded={props.navbarOpen}
aria-controls="navbar"
onClick={() => props.navbarToggle()}
>
{props.logo}
</UnstyledButton>
{!props.headerSearchDisabled && (
<HeaderSearchInput pathname={props.pathname} searchParams={props.searchParams} />
)}
</Group>
<Group gap="lg" pr="sm">
{props.notifications}
<Menu
width={260}
shadow="xl"
position="bottom-end"
transitionProps={{ transition: 'fade-down' }}
opened={userMenuOpened}
onClose={() => setUserMenuOpened(false)}
>
<Menu.Target>
<UnstyledButton
className={classes.user}
aria-label="User menu"
data-active={userMenuOpened || undefined}
onClick={() => setUserMenuOpened((o) => !o)}
>
<Group gap={7}>
<ResourceAvatar value={profile} radius="xl" size={24} />
<Text size="sm" className={classes.userName}>
{formatHumanName(profile?.name?.[0] as HumanName)}
</Text>
<IconChevronDown size={12} stroke={1.5} />
</Group>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>
<HeaderDropdown version={props.version} />
</Menu.Dropdown>
</Menu>
</Group>
</Group>
</MantineAppShell.Header>
);
}