153 lines
4.4 KiB
JavaScript
153 lines
4.4 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { Group, Box, Collapse, ThemeIcon, UnstyledButton, createStyles } from '@mantine/core';
|
|
import { useMediaQuery } from '@mantine/hooks';
|
|
import { BiChevronLeft, BiChevronRight } from 'react-icons/bi';
|
|
import { useAtom } from 'jotai';
|
|
import { activePageAtom, menuOpenedAtom, roomFilterAtom } from '../../state/main';
|
|
import { Link } from 'react-router-dom';
|
|
|
|
|
|
const useStyles = createStyles((theme) => ({
|
|
control: {
|
|
fontWeight: 500,
|
|
display: 'block',
|
|
width: '100%',
|
|
padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
|
|
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.black,
|
|
fontSize: theme.fontSizes.sm,
|
|
|
|
'&:hover': {
|
|
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[7] : theme.colors.gray[0],
|
|
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
|
|
},
|
|
},
|
|
|
|
link: {
|
|
fontWeight: 500,
|
|
display: 'block',
|
|
textDecoration: 'none',
|
|
padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
|
|
paddingLeft: 31,
|
|
marginLeft: 30,
|
|
fontSize: theme.fontSizes.sm,
|
|
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.gray[7],
|
|
borderLeft: `1px solid ${
|
|
theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3]
|
|
}`,
|
|
|
|
'&:hover': {
|
|
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[7] : theme.colors.gray[1],
|
|
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
|
|
},
|
|
},
|
|
|
|
activeLink: {
|
|
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[7] : theme.colors.gray[3],
|
|
},
|
|
|
|
chevron: {
|
|
transition: 'transform 200ms ease',
|
|
},
|
|
}));
|
|
|
|
|
|
export function LinksGroup(props) {
|
|
const { icon: Icon, label, initiallyOpened, links, link } = props
|
|
|
|
const isMobile = useMediaQuery('(max-width: 768px)')
|
|
const hasLinks = Array.isArray(links);
|
|
const hasLink = (typeof link === "object")
|
|
const [opened, setOpened] = useState(initiallyOpened || false);
|
|
// Navigation State
|
|
const [activePage, setActivePage] = useAtom(activePageAtom)
|
|
const [roomFilter, setRoomFilter] = useAtom(roomFilterAtom)
|
|
const [menuOpened, setMenuOpened] = useAtom(menuOpenedAtom)
|
|
|
|
|
|
const { classes, theme, cx } = useStyles();
|
|
|
|
const ChevronIcon = theme.dir === 'ltr' ? BiChevronRight : BiChevronLeft;
|
|
|
|
const navigate = (location) => {
|
|
// event.preventDefault()
|
|
if (location === "rooms") {
|
|
setRoomFilter({})
|
|
}
|
|
console.log("navigate to: ", location)
|
|
if (isMobile && menuOpened) {
|
|
setMenuOpened(false)
|
|
}
|
|
setActivePage(location)
|
|
}
|
|
|
|
|
|
|
|
const items = (hasLinks ? links : []).map((link) => (
|
|
<>
|
|
<Link
|
|
component={Link}
|
|
className={activePage === link.label.toLowerCase() ? cx(classes.link, classes.activeLink) : classes.link}
|
|
to={link.link}
|
|
key={link.label}
|
|
onClick={() => {navigate(link.label.toLowerCase())}}
|
|
>
|
|
{link.label}
|
|
</Link>
|
|
</>
|
|
));
|
|
|
|
const buttonContents = () => {
|
|
return (
|
|
<Group position="apart" spacing={0}>
|
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
|
<ThemeIcon variant="light" size={30}>
|
|
<Icon size={18} />
|
|
</ThemeIcon>
|
|
<Box ml="md">{label}</Box>
|
|
</Box>
|
|
{hasLinks && (
|
|
<ChevronIcon
|
|
className={classes.chevron}
|
|
size={14}
|
|
style={{
|
|
transform: opened ? `rotate(${theme.dir === 'rtl' ? -90 : 90}deg)` : 'none',
|
|
}}
|
|
/>
|
|
)}
|
|
</Group>
|
|
)
|
|
}
|
|
|
|
const myButton = () => {
|
|
if (hasLink) {
|
|
return (
|
|
<UnstyledButton
|
|
onClick={hasLinks ? () => setOpened((o) => !o) : () => navigate(link.label.toLowerCase())}
|
|
className={activePage === link.label.toLowerCase() ? cx(classes.control, classes.activeLink) : classes.control}
|
|
component={Link}
|
|
to={link.link}
|
|
key={link.label}
|
|
>
|
|
{buttonContents()}
|
|
</UnstyledButton>
|
|
)
|
|
} else {
|
|
return (
|
|
<UnstyledButton
|
|
onClick={() => setOpened((o) => !o)}
|
|
className={classes.control}
|
|
>
|
|
{buttonContents()}
|
|
</UnstyledButton>
|
|
)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{myButton()}
|
|
{hasLinks ? <Collapse in={opened}>{items}</Collapse> : null}
|
|
</>
|
|
|
|
)
|
|
} |