Skip to content

Commit

Permalink
chore: add dashboard design #753 (#754)
Browse files Browse the repository at this point in the history
* chore: add dashboard design #753

* chore: sync updates #753

* chore: add translations #753
  • Loading branch information
davydocsurg authored Oct 16, 2023
1 parent cc81be4 commit 46a8879
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 25 deletions.
101 changes: 101 additions & 0 deletions src/pages/components/Navbar/MobileNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import {
Avatar,
Box,
Flex,
FlexProps,
HStack,
IconButton,
Input,
InputGroup,
InputRightElement,
Menu,
MenuButton,
MenuDivider,
MenuItem,
MenuList,
Text,
VStack,
useBreakpointValue,
useColorModeValue,
} from '@chakra-ui/react';
import Image from 'next/image';
import { BellIcon, ChevronDownIcon, HamburgerIcon, Search2Icon } from '@chakra-ui/icons';
import { useTranslation } from 'react-i18next';
import { DEFAULT_AVATAR, LOGO_URL } from '../../../shared/constants/Developers';

interface MobileProps extends FlexProps {
onOpen: () => void;
}

const MobileNav: React.FC<MobileProps> = function MobileNav({ onOpen }) {
const { t } = useTranslation('dashboard');
const showLogo = useBreakpointValue({ base: false, md: false });
const showIconBtn = useBreakpointValue({ base: 'flex', md: false });
const showMd = useBreakpointValue({ base: 'none', md: 'flex' });

return (
<Flex
ml={{ base: 0, md: 60 }}
px={{ base: 4, md: 4 }}
height="20"
alignItems="center"
bg={useColorModeValue('white', 'gray.900')}
borderBottomWidth="1px"
borderBottomColor={useColorModeValue('gray.200', 'gray.700')}
justifyContent={{ base: 'space-between', md: 'flex-end' }}
>
{showIconBtn ? (
<IconButton onClick={onOpen} variant="outline" aria-label="open menu" icon={<HamburgerIcon />} />
) : null}

{showLogo ? <Image src={LOGO_URL} width={100} height={100} alt="IgboAPI logo" /> : null}

<InputGroup style={{ maxWidth: '500px', margin: '0 auto' }}>
<Input padding={6} background="gray.100" placeholder={t('Search...')} />
<InputRightElement padding={6}>
<Search2Icon />
</InputRightElement>
</InputGroup>

<HStack spacing={{ base: '0', md: '6' }}>
<BellIcon color="red.500" width={10} height={6} cursor="pointer" />

<Flex alignItems="center">
<Menu>
<MenuButton py={2} transition="all 0.3s" _focus={{ boxShadow: 'none' }}>
<HStack>
<Avatar size="sm" src={DEFAULT_AVATAR} />
{showMd ? (
<>
<VStack alignItems="flex-start" spacing="1px" ml="2">
<Text fontSize="sm">Egorp David</Text>
</VStack>
<Box>
<ChevronDownIcon boxSize="30px" />
</Box>
</>
) : null}
</HStack>
</MenuButton>
<MenuList
bg={useColorModeValue('white', 'gray.900')}
borderColor={useColorModeValue('gray.200', 'gray.700')}
>
<MenuItem as="a" href="/profile" fontWeight="light">
{t('Profile')}
</MenuItem>
<MenuItem as="a" href="/settings" fontWeight="light">
{t('Settings')}
</MenuItem>
<MenuDivider />
<MenuItem>{t('Sign out')}</MenuItem>
</MenuList>
</Menu>
</Flex>
</HStack>
</Flex>
);
};

export default MobileNav;
30 changes: 30 additions & 0 deletions src/pages/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { Drawer, DrawerContent, useBreakpointValue, useDisclosure } from '@chakra-ui/react';
import SidebarContent from './SidebarContent';
import MobileNav from '../Navbar/MobileNav';

const Sidebar: React.FC = function Sidebar() {
const { isOpen, onOpen, onClose } = useDisclosure();
const showSidebar = useBreakpointValue({ base: false, md: true });

return (
<>
{showSidebar ? <SidebarContent onClose={onClose} /> : null}
<Drawer
isOpen={isOpen}
placement="left"
onClose={onClose}
returnFocusOnClose={false}
onOverlayClick={onClose}
size="full"
>
<DrawerContent>
<SidebarContent onClose={onClose} />
</DrawerContent>
</Drawer>
<MobileNav onOpen={onOpen} />
</>
);
};

export default Sidebar;
55 changes: 55 additions & 0 deletions src/pages/components/Sidebar/SidebarContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import { Box, BoxProps, CloseButton, Flex, Text, useColorModeValue } from '@chakra-ui/react';
import { AtSignIcon, ChatIcon, HamburgerIcon, StarIcon, WarningIcon } from '@chakra-ui/icons';
import { useTranslation } from 'react-i18next';
import Image from 'next/image';
import SidebarItem from './SidebarItem';
import { LOGO_URL } from '../../../shared/constants/Developers';

interface SidebarProps extends BoxProps {
onClose: () => void;
}

const SidebarContent: React.FC<SidebarProps> = function SidebarContent({ onClose }) {
const { t } = useTranslation('dashboard');

const LinkItems = [
{ name: t('Profile'), href: '/profile', icon: <AtSignIcon /> },
{ name: t('Dashboard'), href: '/dashboard', icon: <ChatIcon /> },
{ name: t('API Documentation'), href: '/api-documentation', icon: <StarIcon /> },
{ name: t('Contact Us'), href: '/contact-us', icon: <WarningIcon /> },
];

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"
>
<Flex h="20" alignItems="center" mx="8" justifyContent="space-between">
<Image src={LOGO_URL} width={100} height={100} alt="Igbo API logo" />
<CloseButton display={{ base: 'flex', md: 'none' }} onClick={onClose} />
</Flex>

<SidebarItem icon={<HamburgerIcon />} href="#" _active={{ bg: 'gray.200' }} _hover={{ bg: 'gray.200' }} mb={5}>
<Text fontSize="2xl" fontFamily="monospace" fontWeight="bold" paddingLeft={3}>
{t('Menu')}
</Text>
</SidebarItem>

{LinkItems.map((link) => (
<SidebarItem key={link.name} href={link.href} icon={link.icon} _hover={{ bg: 'blue.400', color: 'white' }}>
<Text fontSize="md" fontFamily="monospace" fontWeight="medium" paddingLeft={3}>
{link.name}
</Text>
</SidebarItem>
))}
</Box>
);
};

export default SidebarContent;
36 changes: 36 additions & 0 deletions src/pages/components/Sidebar/SidebarItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { Box, Flex, FlexProps } from '@chakra-ui/react';

interface IconType {
size?: string | number | boolean;
}

interface SidebarItemProps extends FlexProps {
icon: React.ReactElement<IconType>;
href: string;
children: React.ReactNode;
}

const SidebarItem: React.FC<SidebarItemProps> = function SidebarItem({ icon, href, children }) {
return (
<Box as="a" href={href} style={{ textDecoration: 'none' }} _focus={{ boxShadow: 'none' }}>
<Flex
align="center"
p="4"
mx="4"
borderRadius="lg"
role="group"
cursor="pointer"
_hover={{
bg: 'cyan.400',
color: 'white',
}}
>
{icon}
{children}
</Flex>
</Box>
);
};

export default SidebarItem;
3 changes: 3 additions & 0 deletions src/pages/components/Sidebar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Sidebar from './Sidebar';

export default Sidebar;
25 changes: 0 additions & 25 deletions src/pages/dashboard.js

This file was deleted.

97 changes: 97 additions & 0 deletions src/pages/dashboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Box,
Input,
InputGroup,
InputRightElement,
Text,
useColorModeValue,
Tooltip,
useToast,
useBreakpointValue,
} from '@chakra-ui/react';
import { ArrowBackIcon, ChevronRightIcon, CopyIcon } from '@chakra-ui/icons';
import { useRouter } from 'next/router';
import Sidebar from './components/Sidebar';

const Dashboard: React.FC = function Dashboard() {
const { t } = useTranslation('dashboard');
const router = useRouter();
const [apiKey, setApiKey] = useState('');
const toast = useToast();
const ml = useBreakpointValue({ base: 10, lg: 270 });
const pageHeaderDisplay = useBreakpointValue({ base: 'block', lg: 'flex' });

const handleCopyApiKey = () => {
setApiKey('example-api-key');
navigator.clipboard.writeText(apiKey);
toast({
title: t('API key copied'),
description: t('Your API key has been copied to your clipboard.'),
status: 'success',
duration: 5000,
isClosable: true,
});
};

const handleGoBack = () => {
router.back();
};

return (
<Box minH="100vh" bg={useColorModeValue('white', 'white')}>
<Sidebar />
<Box ml={ml} pt={5} display="flex">
<Text
fontSize="lg"
fontFamily="monospace"
color="blue.400"
fontWeight="bold"
marginRight={3}
cursor="pointer"
onClick={handleGoBack}
>
<ArrowBackIcon boxSize="1rem" marginRight="5px" />
{t('Back')}
</Text>
|
<Text fontSize="md" fontFamily="monospace" marginLeft={3}>
{t('Dashboard')} <ChevronRightIcon /> {t('App one')}
</Text>
</Box>
<Box ml={ml} pt={4} pr={10} display={pageHeaderDisplay} justifyContent="space-between">
<Text fontSize="2xl" fontWeight="bold">
{t('Dashboard')}
</Text>

<InputGroup style={{ maxWidth: '300px', margin: '0 auto', justifyContent: 'right', marginRight: 0 }}>
{/* TODO: Remove hardcoded value */}
<Input value="00y23804y29b3d9048hend" background="gray.200" padding={6} readOnly />
<InputRightElement padding={6} onClick={handleCopyApiKey} cursor="pointer">
<Tooltip label={t('Copy API key')}>
<CopyIcon />
</Tooltip>
</InputRightElement>
</InputGroup>
</Box>

<Box ml={ml} mt={70} p="3" maxW={250} background="gray.50" borderRadius={10} border="1px" borderColor="gray.900">
<Box display="flex" p="2" background="gray.100" justifyContent="space-between">
<Text fontSize="md" p="2" fontWeight="medium">
{t('Calls')}
</Text>

<Text fontSize="2xl" fontWeight="bold">
54
</Text>
</Box>
<Text fontSize="md" fontFamily="monospace" marginTop={3}>
{t('Total daily usage')}
</Text>
</Box>
</Box>
);
};

export default Dashboard;
13 changes: 13 additions & 0 deletions src/public/locales/en/dashboard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Dashboard": "Dashboard",
"Back": "Back",
"Total daily usage": "Total daily usage",
"Calls": "Calls",
"Copy API key": "Copy API key",
"API key copied": "API key copied",
"Your API key has been copied to your clipboard.": "Your API key has been copied to your clipboard.",
"Profile": "Profile",
"Settings": "Settings",
"Sign out": "Sign out",
"Menu": "Menu"
}
2 changes: 2 additions & 0 deletions src/public/locales/en/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import about from './about.json';
import common from './common.json';
import signup from './signup.json';
import dashboard from './dashboard.json';

export default {
about,
common,
signup,
dashboard,
};
13 changes: 13 additions & 0 deletions src/public/locales/ig/dashboard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Dashboard": "Mgbonkiri",
"Back": "Azụ",
"Total daily usage": "Ugboro ole ị ga-abịanwu na API kwa ụbọchị",
"Calls": "Oku",
"Copy API key": "Mapịa ọtụchi API",
"API key copied": "A mapịala ọtụchi API",
"Your API key has been copied to your clipboard.": "A mapịala ọtụchi API gị na mgbonta gị",
"Profile": "Agụgụojingwa",
"Settings": "Ndozi",
"Sign out": "Pụọ",
"Menu": "Mgbonhọrọ"
}
Loading

0 comments on commit 46a8879

Please sign in to comment.