feat: added chat based layout

This commit is contained in:
Sergey Yarkov 2022-02-07 22:52:21 +03:00
parent 25bed8b538
commit 682cbc6ce9
11 changed files with 157 additions and 24 deletions

View File

@ -0,0 +1,12 @@
import React from 'react';
import { GridItem, GridItemProps } from '@chakra-ui/react';
const Sidebar: React.FC<GridItemProps> = props => {
return (
<GridItem pt='7rem' borderRightWidth={'1px'} width='400px' pr='6' {...props}>
{props.children}
</GridItem>
);
};
export { Sidebar };

View File

@ -0,0 +1,8 @@
import React from 'react';
import { GridItem, GridItemProps } from '@chakra-ui/react';
const Window: React.FC<GridItemProps> = props => {
return <GridItem {...props}>{props.children}</GridItem>;
};
export { Window };

View File

@ -0,0 +1,22 @@
import React from 'react';
import { Grid, GridItemProps, GridProps } from '@chakra-ui/react';
import { Sidebar } from './Sidebar';
import { Window } from './Window';
interface IChatComposition {
Sidebar: React.FC<GridItemProps>;
Window: React.FC<GridItemProps>;
}
const Chat: React.FC<GridProps> & IChatComposition = props => {
return (
<Grid gridTemplateColumns={'1fr 3fr'} h='100vh' {...props}>
{props.children}
</Grid>
);
};
Chat.Sidebar = Sidebar;
Chat.Window = Window;
export { Chat };

View File

@ -81,7 +81,7 @@ const Layout: React.FC<ILayoutProps> = ({ children, roles }) => {
</Header>
<NavDesktop />
<Flex minH='100vh' justifyContent='center'>
<Box as='main' flex='1 0' maxW='85rem' ml={{ base: '0', lg: '20rem' }} mt='7rem' mb='1rem' pr='2rem' pl='2rem'>
<Box as='main' flex='1 0' ml={{ base: '0', lg: '20rem' }}>
<Suspense fallback={<LoadingPage />}>
{(() => {
/**
@ -98,12 +98,12 @@ const Layout: React.FC<ILayoutProps> = ({ children, roles }) => {
if (!userContainRoles(me.roles, roles)) return <Redirect to='/404' />;
return children;
} else {
}
/**
* Return children if "roles" prop is not defined
*/
return children;
}
})()}
</Suspense>
</Box>

View File

@ -3,7 +3,7 @@ import React from 'react';
const LoadingPage: React.FC = () => {
return (
<Flex justifyContent='center' mt='40'>
<Flex justifyContent='center' mt='20rem'>
<Box mt='auto' mb='auto' textAlign='center'>
<Spinner thickness='4px' speed='0.55s' emptyColor='gray.200' color='blue.500' size='xl' />
<Text mt='2' color='gray.500' userSelect='none'>

View File

@ -8,7 +8,11 @@ interface IPageComposition {
}
const Page: React.FC<BoxProps> & IPageComposition = props => {
return <Box {...props}>{props.children}</Box>;
return (
<Box maxW='85rem' ml='auto' mr='auto' mt='7rem' mb='2rem' px='2rem' {...props}>
{props.children}
</Box>
);
};
interface IPageHeadingProps {
@ -27,16 +31,12 @@ Page.Heading = props => {
</Flex>
{description && <Text mt='2'>{description}</Text>}
{props.children}
<Divider mt='5' />
<Divider my='5' />
</Box>
);
};
Page.Content = props => (
<Box mt='4' {...props}>
{props.children}
</Box>
);
Page.Content = props => <Box {...props}>{props.children}</Box>;
Page.Footer = props => (
<Box mt='4' {...props}>

View File

@ -50,7 +50,7 @@ const CoursePage: React.FC<IPageProps> = () => {
const handleEditCourse = () => history.push(`/courses/edit/${course.id}`);
return (
<Page maxW='1200px'>
<Page>
<Helmet>
<title>{course.title}</title>
</Helmet>

View File

@ -24,7 +24,7 @@ export const CourseCardList: React.FC<SimpleGridProps> = props => (
mt='4'
templateColumns={{
base: '1fr',
md: 'repeat(auto-fill, minmax(320px, 1fr))',
md: 'repeat(auto-fill, minmax(400px, 1fr))',
}}
spacing={'6'}
{...props}

View File

@ -1,16 +1,110 @@
import React from 'react';
import { Box, Heading } from '@chakra-ui/react';
import {
Avatar,
AvatarBadge,
Box,
Flex,
Heading,
WrapItem,
Text,
Stack,
Input,
Icon,
Button,
HStack,
InputGroup,
InputLeftElement,
useColorModeValue,
} from '@chakra-ui/react';
import { Link as ReactRouterLink } from 'react-router-dom';
import { Page } from '@educt/components/PageElements';
import { IPageProps } from '@educt/interfaces';
import { MdOutlineChat } from 'react-icons/md';
import { LinkBox, LinkOverlay } from '@chakra-ui/react';
import { SearchIcon } from '@chakra-ui/icons';
import { Chat } from '@educt/components/Chat';
/**
* Messages page
*/
const MessagesPage: React.FC<IPageProps> = () => {
return (
<Page>
<Page.Heading heading='Messages' />
<Page maxW='100%' mt='0' mb='0'>
<Page.Content>
<Chat>
<Chat.Sidebar>
<Flex my='4' justifyContent={'space-between'} alignItems={'center'}>
<Heading as='h2' fontSize={'md'} fontWeight='medium' mr='9'>
Chats
</Heading>
<InputGroup maxW='230px' size='sm'>
<InputLeftElement pointerEvents='none'>
<SearchIcon color='gray.300' />
</InputLeftElement>
<Input type='text' placeholder='Search' borderRadius={'md'} />
</InputGroup>
</Flex>
<HStack>
<Button isActive variant={'ghost'} size='sm'>
All
</Button>
<Button colorScheme={'blue'} variant='ghost' size='sm'>
Unread
</Button>
</HStack>
<Stack mt='12' maxH='690px' overflowY={'scroll'} pr='3'>
{Array(20)
.fill(0)
.map((e, i) => i)
.map(n => (
<LinkBox
key={n}
py='5'
px='4'
bg={n === 2 ? useColorModeValue('gray.50', 'gray.700') : ''}
borderRadius={'lg'}
_hover={{ bg: `${useColorModeValue('gray.50', 'gray.700')}` }}
transition='all .1s'
>
<Flex flexDir={'row'} alignItems={'center'}>
<WrapItem>
<Avatar name='Sergey Yarkov' size='md'>
<AvatarBadge boxSize='0.90em' bg='green.500' />
</Avatar>
</WrapItem>
<Box ml='4'>
<LinkOverlay as={ReactRouterLink} to='/'>
<Text fontWeight={'semibold'}>
Sergey Yarkov <br />
<Text as={'span'} fontWeight='normal' fontSize={'sm'} color='gray.500'>
Sergey: hello, how you doing?
</Text>
</Text>
</LinkOverlay>
</Box>
<Box alignSelf={'flex-end'} ml='auto'>
<Text as='span' color='gray.500'>
2h
</Text>
</Box>
</Flex>
</LinkBox>
))}
</Stack>
</Chat.Sidebar>
<Chat.Window>
<Flex justifyContent={'center'} mt='20rem'>
<Box textAlign={'center'}>
<Icon as={MdOutlineChat} color='gray.600' w='16' h='16' />
<Text color='gray.500' userSelect={'none'}>
Select a chat to start messaging
</Text>
</Box>
</Flex>
</Chat.Window>
</Chat>
</Page.Content>
</Page>
);
};

View File

@ -30,7 +30,7 @@ const ProfilePage: React.FC<IPageProps> = () => {
if (me === null) return <LoadingPage />;
return (
<Page maxW={'900px'}>
<Page>
<Page.Heading heading='My account' description='Update your profile information or password here.' />
<Page.Content>
<UserProfile mt='14'>

View File

@ -11,10 +11,7 @@ export const theme = extendTheme({
width: '5px',
height: '5px',
},
'::-webkit-scrollbar-track': {
backgroundColor: 'gray.100',
borderRadius: '100px',
},
'::-webkit-scrollbar-thumb': {
background: 'blue.600',
borderRadius: '100px',