💄 Polish layouts
This commit is contained in:
@@ -1,72 +1,89 @@
|
||||
import { Box, Group, Indicator, Header as MantineHeader, createStyles } from '@mantine/core';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import {
|
||||
Box,
|
||||
Center,
|
||||
Flex,
|
||||
Group,
|
||||
Header,
|
||||
Text,
|
||||
UnstyledButton,
|
||||
useMantineTheme,
|
||||
} from '@mantine/core';
|
||||
import { useMediaQuery } from '@mantine/hooks';
|
||||
import { IconAlertTriangle } from '@tabler/icons-react';
|
||||
import Link from 'next/link';
|
||||
import { useScreenLargerThan } from '~/hooks/useScreenLargerThan';
|
||||
|
||||
import { REPO_URL } from '../../../../data/constants';
|
||||
import DockerMenuButton from '../../../modules/Docker/DockerModule';
|
||||
import { usePackageAttributesStore } from '../../../tools/client/zustands/usePackageAttributesStore';
|
||||
import { Logo } from '../Logo';
|
||||
import { useCardStyles } from '../useCardStyles';
|
||||
import { ToggleEditModeAction } from './Actions/ToggleEditMode/ToggleEditMode';
|
||||
import { Search } from './Search';
|
||||
import { SettingsMenu } from './SettingsMenu';
|
||||
import { AvatarMenu } from './AvatarMenu';
|
||||
import { Search } from './search';
|
||||
|
||||
export const HeaderHeight = 64;
|
||||
type MainHeaderProps = {
|
||||
logoHref?: string;
|
||||
showExperimental?: boolean;
|
||||
headerActions?: React.ReactNode;
|
||||
leftIcon?: React.ReactNode;
|
||||
};
|
||||
|
||||
export function Header(props: any) {
|
||||
const { classes } = useStyles();
|
||||
const { classes: cardClasses, cx } = useCardStyles(false);
|
||||
const { attributes } = usePackageAttributesStore();
|
||||
const { data: sessionData } = useSession();
|
||||
|
||||
const { data } = useQuery({
|
||||
queryKey: ['github/latest'],
|
||||
cacheTime: 1000 * 60 * 60 * 24,
|
||||
staleTime: 1000 * 60 * 60 * 5,
|
||||
queryFn: () =>
|
||||
fetch(`https://api.github.com/repos/${REPO_URL}/releases/latest`).then((res) => res.json()),
|
||||
});
|
||||
const newVersionAvailable =
|
||||
data?.tag_name > `v${attributes.packageVersion}` ? data?.tag_name : undefined;
|
||||
export const MainHeader = ({
|
||||
showExperimental = false,
|
||||
logoHref = '/',
|
||||
headerActions,
|
||||
leftIcon,
|
||||
}: MainHeaderProps) => {
|
||||
const { breakpoints } = useMantineTheme();
|
||||
const isSmallerThanMd = useMediaQuery(`(max-width: ${breakpoints.sm})`);
|
||||
const experimentalHeaderNoteHeight = isSmallerThanMd ? 50 : 30;
|
||||
const headerBaseHeight = isSmallerThanMd ? 60 + 46 : 60;
|
||||
const headerHeight = showExperimental
|
||||
? headerBaseHeight + experimentalHeaderNoteHeight
|
||||
: headerBaseHeight;
|
||||
|
||||
return (
|
||||
<MantineHeader height="auto" className={cx(cardClasses.card, 'dashboard-header')}>
|
||||
<Group p="xs" noWrap grow>
|
||||
<Box className={cx(classes.hide, 'dashboard-header-logo-root')}>
|
||||
<Logo />
|
||||
</Box>
|
||||
<Group
|
||||
className="dashboard-header-group-right"
|
||||
position="right"
|
||||
style={{ maxWidth: 'none' }}
|
||||
noWrap
|
||||
>
|
||||
<Search />
|
||||
{sessionData?.user?.isAdmin && (
|
||||
<>
|
||||
<ToggleEditModeAction />
|
||||
<DockerMenuButton />
|
||||
</>
|
||||
)}
|
||||
<Indicator
|
||||
size={15}
|
||||
color="blue"
|
||||
withBorder
|
||||
processing
|
||||
disabled={newVersionAvailable === undefined}
|
||||
>
|
||||
<SettingsMenu newVersionAvailable={newVersionAvailable} />
|
||||
</Indicator>
|
||||
<Header height={headerHeight} pb="sm" pt={0}>
|
||||
<ExperimentalHeaderNote visible={showExperimental} height={experimentalHeaderNoteHeight} />
|
||||
<Group spacing="xl" mt="xs" px="md" position="apart" noWrap>
|
||||
<Group noWrap style={{ flex: 1 }}>
|
||||
{leftIcon}
|
||||
<UnstyledButton component={Link} href={logoHref}>
|
||||
<Logo />
|
||||
</UnstyledButton>
|
||||
</Group>
|
||||
|
||||
{!isSmallerThanMd && <Search />}
|
||||
|
||||
<Group noWrap style={{ flex: 1 }} position="right">
|
||||
<Group noWrap spacing={8}>
|
||||
{headerActions}
|
||||
</Group>
|
||||
<AvatarMenu />
|
||||
</Group>
|
||||
</Group>
|
||||
</MantineHeader>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
hide: {
|
||||
[theme.fn.smallerThan('xs')]: {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
}));
|
||||
{isSmallerThanMd && (
|
||||
<Center mt="xs" px="md">
|
||||
<Search isMobile />
|
||||
</Center>
|
||||
)}
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
|
||||
type ExperimentalHeaderNoteProps = {
|
||||
height?: 30 | 50;
|
||||
visible?: boolean;
|
||||
};
|
||||
const ExperimentalHeaderNote = ({ visible = false, height = 30 }: ExperimentalHeaderNoteProps) => {
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<Box bg="red" h={height} p={3} px={6}>
|
||||
<Flex h="100%" align="center" columnGap={7}>
|
||||
<IconAlertTriangle color="white" size="1rem" style={{ minWidth: '1rem' }} />
|
||||
<Text color="white" lineClamp={height === 30 ? 1 : 2}>
|
||||
This is an experimental feature of Homarr. Please report any issues to the official Homarr
|
||||
team.
|
||||
</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user