forked from mirrors/thatmattlove-hyperglass
94 lines
2.9 KiB
TypeScript
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>
|
|
);
|
|
};
|