mirror of https://github.com/AlphaNecron/Void.git
109 lines
4.1 KiB
TypeScript
109 lines
4.1 KiB
TypeScript
import { Box, Button, HStack, Icon, IconButton, Menu, MenuButton, MenuItem, MenuList, Skeleton, Spacer, useColorMode, useColorModeValue, useDisclosure } from '@chakra-ui/react';
|
|
import Link from 'next/link';
|
|
import { useRouter } from 'next/router';
|
|
import React, { useState } from 'react';
|
|
import { Edit, File, Home, Link2, LogOut, Moon, Sun, Tool, UploadCloud, User, Users } from 'react-feather';
|
|
import MediaQuery from 'react-responsive';
|
|
import ManageAccountDialog from './ManageAccountDialog';
|
|
import ShareXDialog from './ShareXDialog';
|
|
|
|
export default function Layout({ children, id, user }) {
|
|
const { colorMode, toggleColorMode } = useColorMode();
|
|
const router = useRouter();
|
|
const [busy, setBusy] = useState(false);
|
|
const { onClose: onShareXClose, isOpen: shareXOpen, onOpen: onShareXOpen } = useDisclosure();
|
|
const { onClose: onManageClose, isOpen: manageOpen, onOpen: onManageOpen } = useDisclosure();
|
|
const logout = async () => {
|
|
setBusy(true);
|
|
const userRes = await fetch('/api/user');
|
|
if (userRes.ok) {
|
|
const res = await fetch('/api/auth/logout');
|
|
if (res.ok) router.push('/auth/login');
|
|
} else {
|
|
router.push('/auth/login');
|
|
}
|
|
};
|
|
const pages = [
|
|
{
|
|
icon: Home,
|
|
label: 'Dashboard',
|
|
route: '/dash'
|
|
},
|
|
{
|
|
icon: File,
|
|
label: 'Files',
|
|
route: '/dash/files'
|
|
},
|
|
{
|
|
icon: UploadCloud,
|
|
label: 'Upload',
|
|
route: '/dash/upload'
|
|
},
|
|
{
|
|
icon: Link2,
|
|
label: 'URLs',
|
|
route: '/dash/urls'
|
|
},
|
|
{
|
|
icon: Users,
|
|
label: 'Users',
|
|
route: '/dash/users',
|
|
adminRequired: true
|
|
}
|
|
];
|
|
return (
|
|
<>
|
|
{busy ? (
|
|
<Skeleton mr={4} ml={4} mt={4} mb={4} height='96%' width='98%' m={4} pos='fixed'/>
|
|
) : (
|
|
<>
|
|
<Box h='48px' bg={useColorModeValue('gray.100', 'gray.900')} sx={{ zIndex: 100, position: 'sticky' }} top={0} right={0} left={0} p={1} boxShadow='base'>
|
|
<HStack align='left'>
|
|
{pages.map((page, i) => (
|
|
<>
|
|
{(page.adminRequired && !user.isAdmin) || (
|
|
<>
|
|
<MediaQuery minWidth={pages.length * 150}>
|
|
<Link key={i} href={page.route} passHref>
|
|
<Button justifyContent='flex-start' colorScheme='purple' isActive={i === id} variant='ghost' leftIcon={<Icon as={page.icon}/>}>{page.label}</Button>
|
|
</Link>
|
|
</MediaQuery>
|
|
<MediaQuery maxWidth={pages.length * 150 - 1}>
|
|
<Link key={i} href={page.route} passHref>
|
|
<IconButton colorScheme='purple' aria-label={page.label} isActive={i === id} variant='ghost' icon={<Icon as={page.icon}/>}>{page.label}</IconButton>
|
|
</Link>
|
|
</MediaQuery>
|
|
</>
|
|
)}
|
|
</>
|
|
))}
|
|
<Spacer/>
|
|
<IconButton aria-label='Theme toggle' onClick={toggleColorMode} variant='solid' colorScheme='purple' icon={colorMode === 'light' ? <Moon size={20}/> : <Sun size={20}/>}/>
|
|
<Menu>
|
|
<MenuButton
|
|
as={Button}
|
|
aria-label='Options'
|
|
leftIcon={<User size={16}/>}
|
|
>{user.username}</MenuButton>
|
|
<MenuList>
|
|
<MenuItem icon={<Edit size={16}/>} onClick={onManageOpen}>
|
|
Manage account
|
|
</MenuItem>
|
|
<MenuItem icon={<Tool size={16}/>} onClick={onShareXOpen}>
|
|
ShareX config
|
|
</MenuItem>
|
|
<MenuItem icon={<LogOut size={16}/>} onClick={logout}>
|
|
Logout
|
|
</MenuItem>
|
|
</MenuList>
|
|
</Menu>
|
|
</HStack>
|
|
</Box>
|
|
<ManageAccountDialog onClose={onManageClose} open={manageOpen} user={user}/>
|
|
<ShareXDialog onClose={onShareXClose} open={shareXOpen} token={user.token}/>
|
|
{children}
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
} |