Files
DefectingCat.github.io/components/NavBar.tsx
DefectingCat 9460f7569c Add algoliasearch
* add menu item
* add pages
* add build search script

Add custom algolia component
* fix image in post width

Delete useless file

Modify post data to algolia script
2021-11-29 23:10:33 +08:00

242 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { FC, MouseEvent, useRef } from 'react';
import {
Box,
Image,
Text,
Heading,
Flex,
Icon,
useDisclosure,
Collapse,
useMediaQuery,
useColorMode,
Button,
} from '@chakra-ui/react';
import UseAnimations from 'react-useanimations';
import menu3 from 'react-useanimations/lib/menu3';
import {
FiHome,
FiArchive,
FiUser,
FiSun,
FiMoon,
FiSearch,
} from 'react-icons/fi';
import useGetColors from '../lib/hooks/useGetColors';
import { useRouter } from 'next/router';
import Search from './search';
const menu = [
{
id: 0,
name: '首页',
path: '/',
icon: FiHome,
},
{
id: 1,
name: '归档',
path: '/archive',
icon: FiArchive,
},
// {
// id: 2,
// name: '闲言',
// path: '/message',
// icon: FiMessageSquare,
// },
// {
// id: 3,
// name: '密语',
// path: '/pgp',
// icon: FiLock,
// },
{
id: 4,
name: '关于',
path: '/about',
icon: FiUser,
},
{
id: 5,
name: '搜索',
icon: FiSearch,
},
];
interface MenuListProps {
boxBg: string;
handleMenuClick: (
// eslint-disable-next-line no-unused-vars
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
// eslint-disable-next-line no-unused-vars
path?: string
) => void;
}
const MenuList: FC<MenuListProps> = ({ boxBg, handleMenuClick }) => {
return (
<Flex
as="nav"
mt={['1.5rem', null]}
flexFlow={['column']}
py={['1rem', null, 'unset']}
px={['2rem', '4rem', 'unset']}
bg={[boxBg, null, 'unset']}
shadow={['card', null, 'unset']}
>
{menu.map((item) => {
return (
<Flex
onClick={(e) => handleMenuClick(e, item?.path)}
href={item.path}
key={item.id}
as="a"
alignItems="center"
justifyContent={['unset', null, 'space-between']}
fontSize={['18', null, '22']}
my={['0.5rem', null, '0.5rem']}
cursor="pointer"
>
<Icon as={item.icon} mr={['2.5rem', null, 'unset']} />
<Text>{item.name}</Text>
</Flex>
);
})}
</Flex>
);
};
const NavBar: FC = () => {
const router = useRouter();
const [isLargerThan768] = useMediaQuery('(min-width: 768px)');
// Menu toggle
const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: false });
// Modal toggle
const {
isOpen: isModalOpen,
onOpen: onModalOpen,
onClose: onModalClose,
} = useDisclosure();
const { colorMode, toggleColorMode } = useColorMode();
const { boxBg, bioColor, textColor, headingColor } = useGetColors();
const iconRef = useRef<HTMLDivElement>(null);
// Switch pages
const handleMenuClick = (
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
path?: string
) => {
e.preventDefault();
if (path) {
!isLargerThan768 &&
// Click the animate icon.
(iconRef.current?.children[0] as HTMLDivElement).click();
router.push(path);
} else {
onModalOpen();
}
};
return (
<>
<Box
color={textColor}
w={[null, null, '8rem']}
p={['3rem 1rem 1rem 1rem', null, 'unset']}
position={'relative'}
flex={[1, 1, 'unset']}
>
<Box position={'relative'} boxSize="8rem">
{/* avatar */}
<Image
borderRadius="full"
src="/images/img/avatar.svg"
boxSize="8rem"
boxShadow={'card'}
objectFit={'cover'}
alt="Avatar"
/>
{/* emoji on avatar */}
<Flex
boxShadow={'card'}
position={'absolute'}
bottom={0}
right={0}
rounded={'full'}
bg={boxBg}
h="40px"
w="40px"
justify="center"
alignItems={'center'}
>
</Flex>
</Box>
<Flex
justifyContent="space-between"
alignItems="center"
mt="0.8rem"
mb="0.5rem"
>
<Heading color={headingColor} size={'lg'}>
</Heading>
<Button
background="transparent"
fontSize={['18', null, '22']}
onClick={toggleColorMode}
aria-label="Switch color mode"
>
{colorMode === 'light' ? <Icon as={FiSun} /> : <Icon as={FiMoon} />}
</Button>
</Flex>
<Text color={bioColor}>.</Text>
{/* Menu */}
<Box mx={['-2rem', '-4rem', 'unset']}>
{/* Mobile menu */}
<Box
as={Collapse}
in={isOpen}
animateOpacity
display={[null, null, 'none']}
>
<MenuList boxBg={boxBg} handleMenuClick={handleMenuClick} />
</Box>
{/* Desktop menu */}
<Box display={['none', 'none', 'block']}>
<MenuList boxBg={boxBg} handleMenuClick={handleMenuClick} />
</Box>
</Box>
{/* Mobile menu icon */}
<Box
display={[null, null, 'none']}
position={'absolute'}
top={'1.5rem'}
right={'1rem'}
ref={iconRef}
>
<UseAnimations
reverse={isOpen}
size={40}
animation={menu3}
speed={2}
onClick={onToggle}
/>
</Box>
</Box>
<Search isModalOpen={isModalOpen} onModalClose={onModalClose} />
</>
);
};
export default NavBar;