mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 02:09:08 +03:00
feat: added notification rendering
This commit is contained in:
parent
4b846a7b27
commit
981a0ef642
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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]),
|
||||
|
||||
7
src/types/index.d.ts
vendored
7
src/types/index.d.ts
vendored
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user