2022-05-07 16:40:29 +00:00
|
|
|
import React, { ReactNode } from "react";
|
2022-01-19 16:50:25 +00:00
|
|
|
import {
|
2022-05-07 16:40:29 +00:00
|
|
|
IconButton,
|
|
|
|
Box,
|
|
|
|
CloseButton,
|
|
|
|
Flex,
|
|
|
|
Image,
|
|
|
|
HStack,
|
|
|
|
VStack,
|
|
|
|
Icon,
|
|
|
|
useColorModeValue,
|
|
|
|
Link,
|
|
|
|
Text,
|
|
|
|
BoxProps,
|
|
|
|
FlexProps,
|
|
|
|
Menu,
|
|
|
|
MenuButton,
|
|
|
|
MenuItem,
|
|
|
|
MenuList,
|
|
|
|
Accordion,
|
|
|
|
AccordionButton,
|
|
|
|
AccordionPanel,
|
|
|
|
AccordionItem,
|
|
|
|
AccordionIcon,
|
|
|
|
useMediaQuery,
|
|
|
|
} from "@chakra-ui/react";
|
2022-01-19 16:50:25 +00:00
|
|
|
import {
|
2022-05-07 16:40:29 +00:00
|
|
|
FiHome,
|
|
|
|
FiUser,
|
|
|
|
FiGlobe,
|
|
|
|
FiCode,
|
|
|
|
FiSettings,
|
|
|
|
FiMenu,
|
|
|
|
FiUsers,
|
|
|
|
FiChevronDown,
|
|
|
|
FiShieldOff,
|
|
|
|
} from "react-icons/fi";
|
|
|
|
import { BiCustomize } from "react-icons/bi";
|
|
|
|
import { FcDatabase } from "react-icons/fc";
|
|
|
|
import { AiOutlineKey } from "react-icons/ai";
|
|
|
|
import { SiOpenaccess, SiJsonwebtokens } from "react-icons/si";
|
|
|
|
import { MdSecurity } from "react-icons/md";
|
|
|
|
import { RiSkullLine } from "react-icons/ri";
|
|
|
|
import { RiDatabase2Line } from "react-icons/ri";
|
|
|
|
import { BsCheck2Circle } from "react-icons/bs";
|
|
|
|
import { HiOutlineMail, HiOutlineOfficeBuilding } from "react-icons/hi";
|
|
|
|
import { IconType } from "react-icons";
|
|
|
|
import { ReactText } from "react";
|
|
|
|
import { useMutation, useQuery } from "urql";
|
|
|
|
import { NavLink, useNavigate, useLocation } from "react-router-dom";
|
|
|
|
import { useAuthContext } from "../contexts/AuthContext";
|
|
|
|
import { AdminLogout } from "../graphql/mutation";
|
|
|
|
import { MetaQuery } from "../graphql/queries";
|
|
|
|
|
|
|
|
interface SubRoutes {
|
|
|
|
name: string;
|
|
|
|
icon: IconType;
|
|
|
|
route: string;
|
|
|
|
}
|
2022-01-19 16:50:25 +00:00
|
|
|
|
|
|
|
interface LinkItemProps {
|
2022-05-07 16:40:29 +00:00
|
|
|
name: string;
|
|
|
|
icon: IconType;
|
|
|
|
route: string;
|
|
|
|
subRoutes?: SubRoutes[];
|
2022-01-19 16:50:25 +00:00
|
|
|
}
|
|
|
|
const LinkItems: Array<LinkItemProps> = [
|
2022-05-07 16:40:29 +00:00
|
|
|
{
|
|
|
|
name: "Environment ",
|
|
|
|
icon: FiSettings,
|
|
|
|
route: "/",
|
|
|
|
subRoutes: [
|
|
|
|
{
|
|
|
|
name: "OAuth Config",
|
|
|
|
icon: AiOutlineKey,
|
|
|
|
route: "/oauth-setting",
|
|
|
|
},
|
|
|
|
|
|
|
|
{ name: "Roles", icon: FiUser, route: "/roles" },
|
|
|
|
{
|
|
|
|
name: "JWT Secrets",
|
|
|
|
icon: SiJsonwebtokens,
|
|
|
|
route: "/jwt-config",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Session Storage",
|
|
|
|
icon: RiDatabase2Line,
|
|
|
|
route: "/session-storage",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Email Configurations",
|
|
|
|
icon: HiOutlineMail,
|
|
|
|
route: "/email-config",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Domain White Listing",
|
|
|
|
icon: BsCheck2Circle,
|
|
|
|
route: "/whitelist-variables",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Organization Info",
|
|
|
|
icon: HiOutlineOfficeBuilding,
|
|
|
|
route: "/organization-info",
|
|
|
|
},
|
|
|
|
{ name: "Access Token", icon: SiOpenaccess, route: "/access-token" },
|
|
|
|
{
|
|
|
|
name: "UI Customization",
|
|
|
|
icon: BiCustomize,
|
|
|
|
route: "/ui-customization",
|
|
|
|
},
|
|
|
|
{ name: "Database", icon: RiDatabase2Line, route: "/db-cred" },
|
|
|
|
{
|
|
|
|
name: " Security",
|
|
|
|
icon: MdSecurity,
|
|
|
|
route: "/admin-secret",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{ name: "Users", icon: FiUsers, route: "/users" },
|
|
|
|
// { name: "AUsers", icon: FiUsers, route: "/usersa" },
|
2022-01-19 16:50:25 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
interface SidebarProps extends BoxProps {
|
2022-05-07 16:40:29 +00:00
|
|
|
onClose: () => void;
|
2022-01-19 16:50:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const Sidebar = ({ onClose, ...rest }: SidebarProps) => {
|
2022-05-07 16:40:29 +00:00
|
|
|
const { pathname } = useLocation();
|
|
|
|
const [{ fetching, data }] = useQuery({ query: MetaQuery });
|
|
|
|
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
|
|
|
return (
|
|
|
|
<Box
|
|
|
|
transition="3s ease"
|
|
|
|
bg={useColorModeValue("white", "gray.900")}
|
|
|
|
borderRight="1px"
|
|
|
|
borderRightColor={useColorModeValue("gray.200", "gray.700")}
|
|
|
|
w={{ base: "full", md: 60 }}
|
|
|
|
pos="fixed"
|
|
|
|
h="full"
|
|
|
|
{...rest}
|
|
|
|
>
|
|
|
|
<Flex h="20" alignItems="center" mx="18" justifyContent="space-between">
|
|
|
|
<Link to="/">
|
|
|
|
<Flex alignItems="center">
|
|
|
|
<Image
|
|
|
|
src="https://authorizer.dev/images/logo.png"
|
|
|
|
alt="logo"
|
|
|
|
height="36px"
|
|
|
|
/>
|
|
|
|
<Text fontSize="large" ml="2" letterSpacing="3">
|
|
|
|
AUTHORIZER
|
|
|
|
</Text>
|
|
|
|
</Flex>
|
|
|
|
</Link>
|
|
|
|
<CloseButton display={{ base: "flex", md: "none" }} onClick={onClose} />
|
|
|
|
</Flex>
|
2022-01-25 07:36:52 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
<Accordion defaultIndex={[0]} allowMultiple>
|
|
|
|
<AccordionItem textAlign="center" border="none" w="100%">
|
|
|
|
{LinkItems.map((link) =>
|
|
|
|
link?.subRoutes ? (
|
|
|
|
<Link key={link.name} to={link.route}>
|
|
|
|
<AccordionButton>
|
|
|
|
<Text fontSize="md">
|
|
|
|
<NavItem
|
|
|
|
icon={link.icon}
|
|
|
|
color={pathname === link.route ? "blue.500" : ""}
|
|
|
|
height={12}
|
|
|
|
ml={-1}
|
|
|
|
mb={isNotSmallerScreen ? -1 : -4}
|
|
|
|
w={isNotSmallerScreen ? "100%" : "310%"}
|
|
|
|
>
|
|
|
|
{link.name}
|
|
|
|
<Box display={{ base: "none", md: "flex" }} ml={12}>
|
|
|
|
<FiChevronDown />
|
|
|
|
</Box>
|
|
|
|
</NavItem>
|
|
|
|
</Text>
|
|
|
|
</AccordionButton>
|
|
|
|
<AccordionPanel>
|
|
|
|
{link.subRoutes?.map((sublink) => (
|
|
|
|
<NavLink
|
|
|
|
key={sublink.name}
|
|
|
|
to={sublink.route}
|
|
|
|
onClick={onClose}
|
|
|
|
>
|
|
|
|
{" "}
|
|
|
|
<Text fontSize="xs" ml={2}>
|
|
|
|
<NavItem
|
|
|
|
icon={sublink.icon}
|
|
|
|
color={pathname === sublink.route ? "blue.500" : ""}
|
|
|
|
height={8}
|
|
|
|
>
|
|
|
|
{sublink.name}
|
|
|
|
</NavItem>{" "}
|
|
|
|
</Text>
|
|
|
|
</NavLink>
|
|
|
|
))}
|
|
|
|
</AccordionPanel>
|
|
|
|
</Link>
|
|
|
|
) : (
|
|
|
|
<Link key={link.name} to={link.route}>
|
|
|
|
{" "}
|
|
|
|
<Text fontSize="md" w="100%" mt={-2}>
|
|
|
|
<NavItem
|
|
|
|
icon={link.icon}
|
|
|
|
color={pathname === link.route ? "blue.500" : ""}
|
|
|
|
height={12}
|
|
|
|
onClick={onClose}
|
|
|
|
>
|
|
|
|
{link.name}
|
|
|
|
</NavItem>{" "}
|
|
|
|
</Text>
|
|
|
|
</Link>
|
|
|
|
)
|
|
|
|
)}
|
|
|
|
<Link
|
|
|
|
href="/playground"
|
|
|
|
target="_blank"
|
|
|
|
style={{
|
|
|
|
textDecoration: "none",
|
|
|
|
}}
|
|
|
|
_focus={{ _boxShadow: "none" }}
|
|
|
|
>
|
|
|
|
<NavItem icon={FiCode}>API Playground</NavItem>
|
|
|
|
</Link>
|
|
|
|
</AccordionItem>
|
|
|
|
</Accordion>
|
2022-03-09 06:23:34 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
{data?.meta?.version && (
|
|
|
|
<Flex alignContent="center">
|
|
|
|
{" "}
|
|
|
|
<Text
|
|
|
|
color="gray.400"
|
|
|
|
fontSize="sm"
|
|
|
|
textAlign="center"
|
|
|
|
position="absolute"
|
|
|
|
bottom="5"
|
|
|
|
left="7"
|
|
|
|
>
|
|
|
|
Current Version: {data.meta.version}
|
|
|
|
</Text>
|
|
|
|
</Flex>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
);
|
2022-01-19 16:50:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
interface NavItemProps extends FlexProps {
|
2022-05-07 16:40:29 +00:00
|
|
|
icon: IconType;
|
|
|
|
children: ReactText;
|
2022-01-19 16:50:25 +00:00
|
|
|
}
|
|
|
|
export const NavItem = ({ icon, children, ...rest }: NavItemProps) => {
|
2022-05-07 16:40:29 +00:00
|
|
|
return (
|
|
|
|
<Flex
|
|
|
|
align="center"
|
|
|
|
p="3"
|
|
|
|
mx="3"
|
|
|
|
borderRadius="md"
|
|
|
|
role="group"
|
|
|
|
cursor="pointer"
|
|
|
|
_hover={{
|
|
|
|
bg: "blue.500",
|
|
|
|
color: "white",
|
|
|
|
}}
|
|
|
|
{...rest}
|
|
|
|
>
|
|
|
|
{icon && (
|
|
|
|
<Icon
|
|
|
|
mr="4"
|
|
|
|
fontSize="16"
|
|
|
|
_groupHover={{
|
|
|
|
color: "white",
|
|
|
|
}}
|
|
|
|
as={icon}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{children}
|
|
|
|
</Flex>
|
|
|
|
);
|
2022-01-19 16:50:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
interface MobileProps extends FlexProps {
|
2022-05-07 16:40:29 +00:00
|
|
|
onOpen: () => void;
|
2022-01-19 16:50:25 +00:00
|
|
|
}
|
|
|
|
export const MobileNav = ({ onOpen, ...rest }: MobileProps) => {
|
2022-05-07 16:40:29 +00:00
|
|
|
const [_, logout] = useMutation(AdminLogout);
|
|
|
|
const { setIsLoggedIn } = useAuthContext();
|
|
|
|
const navigate = useNavigate();
|
2022-01-19 16:50:25 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
const handleLogout = async () => {
|
|
|
|
await logout();
|
|
|
|
setIsLoggedIn(false);
|
|
|
|
navigate("/", { replace: true });
|
|
|
|
};
|
2022-01-19 16:50:25 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
return (
|
|
|
|
<Flex
|
|
|
|
ml={{ base: 0, md: 60 }}
|
|
|
|
px={{ base: 4, md: 4 }}
|
|
|
|
height="20"
|
|
|
|
position="fixed"
|
|
|
|
right="0"
|
|
|
|
left="0"
|
|
|
|
alignItems="center"
|
|
|
|
bg={useColorModeValue("white", "gray.900")}
|
|
|
|
borderBottomWidth="1px"
|
|
|
|
borderBottomColor={useColorModeValue("gray.200", "gray.700")}
|
|
|
|
justifyContent={{ base: "space-between", md: "flex-end" }}
|
|
|
|
zIndex={99}
|
|
|
|
{...rest}
|
|
|
|
>
|
|
|
|
<IconButton
|
|
|
|
display={{ base: "flex", md: "none" }}
|
|
|
|
onClick={onOpen}
|
|
|
|
variant="outline"
|
|
|
|
aria-label="open menu"
|
|
|
|
icon={<FiMenu />}
|
|
|
|
/>
|
2022-01-19 16:50:25 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
<Image
|
|
|
|
src="https://authorizer.dev/images/logo.png"
|
|
|
|
alt="logo"
|
|
|
|
height="36px"
|
|
|
|
display={{ base: "flex", md: "none" }}
|
|
|
|
/>
|
2022-01-19 16:50:25 +00:00
|
|
|
|
2022-05-07 16:40:29 +00:00
|
|
|
<HStack spacing={{ base: "0", md: "6" }}>
|
|
|
|
<Flex alignItems={"center"}>
|
|
|
|
<Menu>
|
|
|
|
<MenuButton
|
|
|
|
py={2}
|
|
|
|
transition="all 0.3s"
|
|
|
|
_focus={{ boxShadow: "none" }}
|
|
|
|
>
|
|
|
|
<HStack mr={5}>
|
|
|
|
<FiUser />
|
|
|
|
<VStack
|
|
|
|
display={{ base: "none", md: "flex" }}
|
|
|
|
alignItems="flex-start"
|
|
|
|
spacing="1px"
|
|
|
|
ml="2"
|
|
|
|
>
|
|
|
|
<Text fontSize="sm">Admin</Text>
|
|
|
|
</VStack>
|
|
|
|
<Box display={{ base: "none", md: "flex" }}>
|
|
|
|
<FiChevronDown />
|
|
|
|
</Box>
|
|
|
|
</HStack>
|
|
|
|
</MenuButton>
|
|
|
|
<MenuList
|
|
|
|
bg={useColorModeValue("white", "gray.900")}
|
|
|
|
borderColor={useColorModeValue("gray.200", "gray.700")}
|
|
|
|
>
|
|
|
|
<MenuItem onClick={handleLogout}>Sign out</MenuItem>
|
|
|
|
</MenuList>
|
|
|
|
</Menu>
|
|
|
|
</Flex>
|
|
|
|
</HStack>
|
|
|
|
</Flex>
|
|
|
|
);
|
|
|
|
};
|