feat: added notification rendering

This commit is contained in:
Sergey Yarkov 2022-02-21 23:57:43 +03:00
parent 4b846a7b27
commit 981a0ef642
5 changed files with 60 additions and 15 deletions

View File

@ -1,27 +1,35 @@
import React from 'react';
import { Menu, MenuButton, MenuList, MenuGroup, IconButton, MenuDivider } from '@chakra-ui/react';
import moment from 'moment';
import { Menu, MenuButton, MenuList, MenuItem, MenuGroup, IconButton, MenuDivider, Flex, Text } from '@chakra-ui/react';
import { Skeleton } from '@chakra-ui/skeleton';
import { MdNotifications } from 'react-icons/md';
import { useRootStore } from '@educt/hooks/useRootStore';
import { MdNotifications, MdOutlineMessage } from 'react-icons/md';
import { observer } from 'mobx-react';
export interface INotificationsProps {
count?: number | undefined;
}
/**
* Hooks
*/
import { useHistory } from 'react-router-dom';
import { useRootStore } from '@educt/hooks/useRootStore';
const Notifications: React.FC<INotificationsProps> = observer(props => {
const Notifications: React.FC = observer(() => {
const {
userStore: { me },
} = useRootStore();
const { count, ...menuProps } = props;
const history = useHistory();
if (me === null) {
return <Skeleton width='50px' height='40px' mr={3} ml={3} borderRadius='md' />;
}
const count = me.notifications.length;
/**
* Filter types of notifications
*/
const messages = me.notifications.filter(notification => notification.type === 'MESSAGE');
return (
<Menu isLazy {...menuProps}>
<Menu>
<MenuButton
as={IconButton}
mx='2'
@ -41,9 +49,29 @@ const Notifications: React.FC<INotificationsProps> = observer(props => {
borderRadius: '100%',
}}
/>
<MenuList>
<MenuGroup title={'Notifications'}>
<MenuList minWidth='300px'>
<MenuGroup title={count && count > 0 ? `${count} new notifications` : 'Notifications'}>
<MenuDivider />
{/* MESSAGES */}
{messages.length !== 0 && (
<MenuItem onClick={() => history.push('/messages')} py='3' icon={<MdOutlineMessage />}>
<Flex flexDir='column' fontSize={'sm'}>
<Text as='span' mr='3'>
You have <b>{messages.length}</b> new private messages
</Text>
<Text as='span' fontSize={'xs'} color='gray.500' justifySelf='flex-start'>
{moment(messages[0].time).fromNow()}
</Text>
</Flex>
</MenuItem>
)}
{/* EMPTY NOTIFICATIONS */}
{me.notifications.length === 0 && (
<Text fontSize={'sm'} color='gray.500' textAlign='center' py='3' userSelect={'none'}>
You have no notifications
</Text>
)}
</MenuGroup>
</MenuList>
</Menu>

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Flex, Box, BoxProps } from '@chakra-ui/react';
import { Logo } from './Logo';
import { Profile } from './Profile';
import { INotificationsProps, Notifications } from './Notifications';
import { Notifications } from './Notifications';
import ColorModeSwitcher from '@educt/components/ColorModeSwitcher';
import NavMobile from '@educt/components/Nav/Mobile';
import type { ColorModeSwitcherProps } from '../ColorModeSwitcher/ColorModeSwitcher';
@ -15,7 +15,7 @@ import { useColorModeValue, useMediaQuery } from '@chakra-ui/react';
interface IHeaderComposition {
Logo: React.FC<BoxProps>;
ThemeSwitcher: React.FC<ColorModeSwitcherProps>;
Notifications: React.FC<INotificationsProps>;
Notifications: React.FC;
Profile: React.FC;
}

View File

@ -1,5 +1,12 @@
import type { RouteComponentProps } from 'react-router-dom';
import { AttachmentFileType, ColorType, LessonProgress, LessonVideoType, LinkType } from '@educt/types';
import {
AttachmentFileType,
ColorType,
LessonProgress,
LessonVideoType,
LinkType,
NotificationType,
} from '@educt/types';
import { CourseStatusEnum, UserRoleEnum } from '../enums';
export interface IAppConfig {
@ -135,6 +142,7 @@ export interface IMe extends IUser {
*/
courses?: UserCourseType[];
likes: Array<Pick<ICourse, 'id'>>;
notifications: Array<NotificationType>;
isAdmin: boolean;
isTeacher: boolean;
isStudent: boolean;

View File

@ -72,6 +72,7 @@ export default class UserStore {
email,
roles,
likes,
notifications,
contacts,
courses,
created_at,
@ -91,6 +92,7 @@ export default class UserStore {
about,
last_login,
likes,
notifications,
contacts,
courses,
isAdmin: helpers.userContainRoles(roles, [UserRoleEnum.ADMIN]),

View File

@ -76,6 +76,13 @@ export type HistoryMessageType = {
time: string;
};
export type NotificationType = {
id: string;
content: string;
time: string;
type: 'SYSTEM' | 'MESSAGE';
};
export type UserSeesionType = {
sessionId: string | undefined;
userId: string | undefined;