Skip to content

Commit

Permalink
chore: add reusable dashboard header; implement profile page design #757
Browse files Browse the repository at this point in the history
  • Loading branch information
davydocsurg committed Oct 24, 2023
1 parent 46a8879 commit 3154fcb
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 89 deletions.
83 changes: 83 additions & 0 deletions src/pages/components/DashboardHeader/DashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { ArrowBackIcon, ChevronRightIcon, CopyIcon } from '@chakra-ui/icons';
import {
Box,
Input,
InputGroup,
InputRightElement,
Text,
Tooltip,
useBreakpointValue,
useToast,
} from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';

interface DashboardHeaderProps {
pageTitle: string;
}

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

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

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,
});
};

return (
<>
<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">
{pageTitle}
</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>
</>
);
};

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

export default DashboardHeader;
25 changes: 18 additions & 7 deletions src/pages/components/Sidebar/SidebarContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import React, { useEffect } 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 { useRouter } from 'next/router';
import Link from 'next/link';
import SidebarItem from './SidebarItem';
import { LOGO_URL } from '../../../shared/constants/Developers';

Expand All @@ -12,7 +14,7 @@ interface SidebarProps extends BoxProps {

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

const router = useRouter();
const LinkItems = [
{ name: t('Profile'), href: '/profile', icon: <AtSignIcon /> },
{ name: t('Dashboard'), href: '/dashboard', icon: <ChatIcon /> },
Expand Down Expand Up @@ -42,11 +44,20 @@ const SidebarContent: React.FC<SidebarProps> = function SidebarContent({ onClose
</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>
<Link key={link.name} href={link.href} passHref>
<SidebarItem
href={link.href}
icon={link.icon}
_hover={{ bg: 'blue.400', color: 'white' }}
color={router.pathname === link.href ? 'white' : 'gray.800'}
activeBgColor={router.pathname === link.href ? 'blue.600' : 'transparent'}
activeTextColor={router.pathname === link.href ? 'white' : 'gray.800'}
>
<Text fontSize="md" fontFamily="monospace" fontWeight="medium" paddingLeft={3}>
{link.name}
</Text>
</SidebarItem>
</Link>
))}
</Box>
);
Expand Down
17 changes: 16 additions & 1 deletion src/pages/components/Sidebar/SidebarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ interface SidebarItemProps extends FlexProps {
icon: React.ReactElement<IconType>;
href: string;
children: React.ReactNode;
activeBgColor?: string;
activeTextColor?: string;
}

const SidebarItem: React.FC<SidebarItemProps> = function SidebarItem({ icon, href, children }) {
const SidebarItem: React.FC<SidebarItemProps> = function SidebarItem({
icon,
href,
children,
activeBgColor,
activeTextColor,
}) {
return (
<Box as="a" href={href} style={{ textDecoration: 'none' }} _focus={{ boxShadow: 'none' }}>
<Flex
Expand All @@ -25,6 +33,8 @@ const SidebarItem: React.FC<SidebarItemProps> = function SidebarItem({ icon, hre
bg: 'cyan.400',
color: 'white',
}}
bg={activeBgColor}
color={activeTextColor}
>
{icon}
{children}
Expand All @@ -33,4 +43,9 @@ const SidebarItem: React.FC<SidebarItemProps> = function SidebarItem({ icon, hre
);
};

SidebarItem.defaultProps = {
activeBgColor: 'transparent',
activeTextColor: 'gray.800',
};

export default SidebarItem;
13 changes: 0 additions & 13 deletions src/pages/components/UserInformation/UserInfo.js

This file was deleted.

37 changes: 37 additions & 0 deletions src/pages/components/UserInformation/UserInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { Box, Text, useBreakpointValue } from '@chakra-ui/react';

const UserInfo: React.FC = function UserInfo() {
const ml = useBreakpointValue({ base: 10, lg: 260 });

return (
<Box ml={ml} p="3">
<Box display="flex">
<Text fontSize="md" fontWeight="bold" fontFamily="monospace" marginTop={3}>
Name:
</Text>
<Text fontSize="md" ml={3} fontWeight="medium" fontFamily="monospace" marginTop={3}>
David Egorp
</Text>
</Box>
<Box display="flex">
<Text fontSize="md" fontWeight="bold" fontFamily="monospace" marginTop={3}>
Email:
</Text>
<Text fontSize="md" ml={3} fontWeight="medium" fontFamily="monospace" marginTop={3}>
[email protected]
</Text>
</Box>
<Box display="flex">
<Text fontSize="md" fontWeight="bold" fontFamily="monospace" marginTop={3}>
Date joined:
</Text>
<Text fontSize="md" ml={3} fontWeight="medium" fontFamily="monospace" marginTop={3}>
20 May, 2023
</Text>
</Box>
</Box>
);
};

export default UserInfo;
72 changes: 4 additions & 68 deletions src/pages/dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,17 @@
import React, { useState } from 'react';
import React 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 { Box, Text, useColorModeValue, useBreakpointValue } from '@chakra-ui/react';
import Sidebar from './components/Sidebar';
import DashboardHeader from './components/DashboardHeader';

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>

<DashboardHeader pageTitle={t('Dashboard')} />
<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">
Expand Down
20 changes: 20 additions & 0 deletions src/pages/profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Box, useColorModeValue } from '@chakra-ui/react';
import Sidebar from './components/Sidebar';
import DashboardHeader from './components/DashboardHeader';
import UserInfo from './components/UserInformation';

const Profile: React.FC = function Profile() {
const { t } = useTranslation('dashboard');

return (
<Box minH="100vh" bg={useColorModeValue('white', 'white')}>
<Sidebar />
<DashboardHeader pageTitle={t('Profile')} />
<UserInfo />
</Box>
);
};

export default Profile;

0 comments on commit 3154fcb

Please sign in to comment.