lookingglass/hyperglass/ui/components/footer/footer.tsx
2024-11-15 18:39:27 +00:00

94 lines
2.9 KiB
TypeScript

import { Box, Container, Flex, Grid, GridItem } from '@chakra-ui/react';
import { useMemo } from 'react';
import { useConfig } from '~/context';
import { DynamicIcon, Markdown } from '~/elements';
import { useMobile } from '~/hooks';
import { isLink, isMenu } from '~/types';
import { FooterButton } from './button';
import { FooterLink } from './link';
import type { ButtonProps, LinkProps } from '@chakra-ui/react';
import type { Link, Menu } from '~/types';
import { Logo } from './logo';
type MenuItems = (Link | Menu)[];
function buildItems(links: Link[], menus: Menu[]): [MenuItems, MenuItems] {
const leftLinks = links.filter(link => link.side === 'left');
const leftMenus = menus.filter(menu => menu.side === 'left');
const rightLinks = links.filter(link => link.side === 'right');
const rightMenus = menus.filter(menu => menu.side === 'right');
const left = [...leftLinks, ...leftMenus].sort((a, b) => (a.order > b.order ? 1 : -1));
const right = [...rightLinks, ...rightMenus].sort((a, b) => (a.order > b.order ? 1 : -1));
return [left, right];
}
const NavLink = (props: { item: ArrayElement<MenuItems> }) => {
const { item, side } = props;
if (isLink(item)) {
const icon: Partial<ButtonProps & LinkProps> = {};
if (item.showIcon) {
icon.rightIcon = <DynamicIcon icon={{ go: 'GoLinkExternal' }} />;
}
return <FooterLink key={item.title} href={item.url} title={item.title} {...icon} />;
}
if (isMenu(item)) {
return <FooterButton key={item.title} side={side} content={item.content} title={item.title} />;
}
};
export const Footer = (): JSX.Element => {
const { web } = useConfig();
const [left, right] = useMemo(() => buildItems(web.links, web.menus), [web.links, web.menus]);
return (
<Box
w="100%"
bg="#005e8a"
color="#ffffff"
fontSize=".945rem"
>
<Container maxW="8xl">
<Grid
px={6}
py={4}
w="100%"
zIndex={1}
as="footer"
whiteSpace="nowrap"
templateColumns="repeat(4, 1fr)"
gap={6}
>
<GridItem colSpan={{base: 4, md: 2}}>
<Flex
flex="1 0 auto"
key="credit"
side="left"
maxW="50%"
>
<Box w="50px" maxW="15vw" my="2" mr="4">
<Logo />
</Box>
<Markdown content={web.copyright} />
</Flex>
</GridItem>
<GridItem colSpan={{base: 4, md: 1}}>
<Flex flexDirection="column" alignItems="start">
{left.map(item => (
<NavLink key={item.title} item={item} />
))}
</Flex>
</GridItem>
<GridItem colSpan={{base: 4, md: 1}}>
{right.map(item => (
<NavLink key={item.title} item={item} />
))}
</GridItem>
</Grid>
</Container>
</Box>
);
};