mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: added chat based layout
This commit is contained in:
parent
25bed8b538
commit
682cbc6ce9
12
src/components/Chat/Sidebar.tsx
Normal file
12
src/components/Chat/Sidebar.tsx
Normal 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 };
|
||||
8
src/components/Chat/Window.tsx
Normal file
8
src/components/Chat/Window.tsx
Normal 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 };
|
||||
22
src/components/Chat/index.tsx
Normal file
22
src/components/Chat/index.tsx
Normal 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 };
|
||||
@ -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>
|
||||
|
||||
@ -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'>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@ -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'>
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user