From 677e4d9ef5520d9905a9b81b179dd0147f5a6019 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Mon, 6 Dec 2021 22:25:01 +0300 Subject: [PATCH] refactor: nav layout --- package-lock.json | 14 +---- package.json | 2 +- src/components/Header/Header.tsx | 37 ++++------- ...otifications.tsx => NotificationsMenu.tsx} | 4 +- .../Header/{UserInfo.tsx => ProfileMenu.tsx} | 4 +- src/components/Nav/Desktop/index.tsx | 17 ++---- src/components/Nav/Mobile/index.tsx | 6 +- src/components/Nav/NavLink.tsx | 61 ++++++++++--------- src/config.ts | 22 ++++--- src/interfaces/index.ts | 1 + 10 files changed, 79 insertions(+), 89 deletions(-) rename src/components/Header/{UserNotifications.tsx => NotificationsMenu.tsx} (91%) rename src/components/Header/{UserInfo.tsx => ProfileMenu.tsx} (95%) diff --git a/package-lock.json b/package-lock.json index 5038596..84556ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1337,11 +1337,6 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, "caniuse-lite": { "version": "1.0.30001267", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001267.tgz", @@ -2155,12 +2150,9 @@ "integrity": "sha512-7XhbCr7d9fDC1TgcK/BUbt7D3q0VJMu7jPErfsa0JrxVjv/nni41xWdJcy0Zb7R+Np8OsCkQ2lMyloAtE3DLiQ==" }, "react-icons": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.11.0.tgz", - "integrity": "sha512-JRgiI/vdF6uyBgyZhVyYJUZAop95Sy4XDe/jmT3R/bKliFWpO/uZBwvSjWEdxwzec7SYbEPNPck0Kff2tUGM2Q==", - "requires": { - "camelcase": "^5.0.0" - } + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz", + "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==" }, "react-is": { "version": "16.13.1", diff --git a/package.json b/package.json index 95776c8..db21b00 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "react-error-boundary": "^3.1.3", "react-helmet": "^6.1.0", "react-hook-form": "^7.12.2", - "react-icons": "^3.11.0", + "react-icons": "^4.3.1", "react-router-dom": "^5.2.0", "react-spinners": "^0.11.0", "react-virtuoso": "^2.2.8", diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 9081cee..9cae6d4 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,25 +1,24 @@ import React from 'react'; import { observer } from 'mobx-react'; -import { Flex, Box, Heading, useColorMode } from '@chakra-ui/react'; -import { MdSchool } from 'react-icons/md'; -import config from '@educt/config'; +import { Flex, Box } from '@chakra-ui/react'; /** * Components */ +import Logo from '@educt/components/Logo'; import NavMobile from '@educt/components/Nav/Mobile'; import ColorModeSwitcher from '@educt/components/ColorModeSwitcher'; -import UserInfo from './UserInfo'; -import UserNotifications from './UserNotifications'; +import ProfileMenu from './ProfileMenu'; +import NotificationsMenu from './NotificationsMenu'; /** * Hooks */ import { useMediaQuery } from '@chakra-ui/media-query'; +import { useColorModeValue } from '@chakra-ui/color-mode'; const Header: React.FC = () => { const [isDesktop] = useMediaQuery('(min-width: 992px)'); - const { colorMode } = useColorMode(); return ( { top={0} left={0} right={0} - // borderBottomWidth={1} - // h='43px' - boxShadow='md' - backgroundColor={colorMode === 'dark' ? 'gray.800' : 'white'} + borderBottomWidth='1px' + backgroundColor={useColorModeValue('white', 'gray.800')} zIndex={4} > { alignItems='center' padding='5px 1.5rem 5px 1.5rem' > - - - - - - - {config.metaData.appName} - - - - {isDesktop ? ( + + {isDesktop && ( - - + + - ) : ( - )} + {!isDesktop && } ); diff --git a/src/components/Header/UserNotifications.tsx b/src/components/Header/NotificationsMenu.tsx similarity index 91% rename from src/components/Header/UserNotifications.tsx rename to src/components/Header/NotificationsMenu.tsx index c21e39c..a35d7cc 100644 --- a/src/components/Header/UserNotifications.tsx +++ b/src/components/Header/NotificationsMenu.tsx @@ -6,7 +6,7 @@ import { MdNotifications } from 'react-icons/md'; import { useRootStore } from '@educt/hooks/useRootStore'; import { observer } from 'mobx-react'; -const UserNotifications: React.FC = () => { +const NotificationsMenu: React.FC = () => { const { userStore } = useRootStore(); if (userStore.me === null) { @@ -39,4 +39,4 @@ const UserNotifications: React.FC = () => { ); }; -export default observer(UserNotifications); +export default observer(NotificationsMenu); diff --git a/src/components/Header/UserInfo.tsx b/src/components/Header/ProfileMenu.tsx similarity index 95% rename from src/components/Header/UserInfo.tsx rename to src/components/Header/ProfileMenu.tsx index 80213a8..cd44d81 100644 --- a/src/components/Header/UserInfo.tsx +++ b/src/components/Header/ProfileMenu.tsx @@ -24,7 +24,7 @@ import UserBadge from '@educt/components/UserBadge'; */ import { useLogout } from '@educt/hooks/queries'; -const UserInfo: React.FC = () => { +const ProfileMenu: React.FC = () => { const { userStore } = useRootStore(); const { logout } = useLogout(); @@ -64,4 +64,4 @@ const UserInfo: React.FC = () => { ); }; -export default observer(UserInfo); +export default observer(ProfileMenu); diff --git a/src/components/Nav/Desktop/index.tsx b/src/components/Nav/Desktop/index.tsx index ec33bb5..445bd3b 100644 --- a/src/components/Nav/Desktop/index.tsx +++ b/src/components/Nav/Desktop/index.tsx @@ -37,17 +37,10 @@ const Nav: React.FC = () => { zIndex='1' backgroundColor={colorMode === 'dark' ? 'gray.800' : 'white'} > - - + + + + @@ -55,7 +48,7 @@ const Nav: React.FC = () => { - + diff --git a/src/components/Nav/Mobile/index.tsx b/src/components/Nav/Mobile/index.tsx index 31dcca0..e55b2fc 100644 --- a/src/components/Nav/Mobile/index.tsx +++ b/src/components/Nav/Mobile/index.tsx @@ -13,6 +13,7 @@ import config from '@educt/config'; * Components */ import NavList from '../NavList'; +import Logo from '@educt/components/Logo'; /** * Hooks @@ -37,7 +38,10 @@ const NavMobile: React.FC = () => { - + + + + {me !== null ? ( diff --git a/src/components/Nav/NavLink.tsx b/src/components/Nav/NavLink.tsx index 1b1957f..560449c 100644 --- a/src/components/Nav/NavLink.tsx +++ b/src/components/Nav/NavLink.tsx @@ -1,62 +1,67 @@ import React from 'react'; import { observer } from 'mobx-react'; -import { userContainRoles } from '@educt/helpers'; -import { Box, useColorMode } from '@chakra-ui/react'; +import * as helpers from '@educt/helpers'; +import { Flex, Box, Icon, Text } from '@chakra-ui/react'; + +/** + * Types + */ import type { LinkType } from '@educt/types'; /** * Hooks */ import { useRootStore } from '@educt/hooks/useRootStore'; +import { useColorMode } from '@chakra-ui/react'; type NavLinkPropsType = { link: LinkType; onClickLink: (link: LinkType) => void; }; -/** - * Returns the link component for navigation. - */ const NavLink: React.FC = ({ link, onClickLink }) => { const { uiStore, userStore } = useRootStore(); const { colorMode } = useColorMode(); + const isActive = uiStore.location === link.location; const onClick = () => onClickLink(link); if (!link.public && link.roles !== undefined) { const { me } = userStore; if (me === null) return null; - if (!userContainRoles(me.roles, link.roles)) return null; + if (!helpers.userContainRoles(me.roles, link.roles)) return null; } return ( - - - {link.title} - + + + + {link.title} + + ); }; diff --git a/src/config.ts b/src/config.ts index 06102fe..99c03cf 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,12 @@ import { UserRoleEnum } from '@educt/enums'; -import { MdAccountCircle, MdCollectionsBookmark, MdGroup, MdHome, MdMessage, MdList } from 'react-icons/md'; +import { + MdOutlineHome, + MdOutlineMessage, + MdOutlineCollectionsBookmark, + MdOutlineVideoLibrary, + MdOutlineGroup, + MdOutlineAccountCircle, +} from 'react-icons/md'; import { IAppConfig } from './interfaces'; import packageJson from '../package.json'; @@ -11,28 +18,29 @@ const config: IAppConfig = { appName: 'Educt', appDescription: 'Learning management system', appVersion: packageJson.version, + appGithubLink: 'https://github.com/sergeyyarkov/educt-client', }, /** * Links that are rendered in the navigation */ links: [ - { location: '/', title: 'Main', public: true, icon: MdHome }, - { location: '/courses', title: 'Courses', public: true, icon: MdCollectionsBookmark }, + { location: '/', title: 'Main', public: true, icon: MdOutlineHome }, + { location: '/courses', title: 'Courses', public: true, icon: MdOutlineCollectionsBookmark }, { location: '/lessons', title: 'Lessons', public: false, - icon: MdList, + icon: MdOutlineVideoLibrary, roles: [UserRoleEnum.ADMIN, UserRoleEnum.TEACHER], }, - { location: '/messages', title: 'Messages', public: true, icon: MdMessage }, - { location: '/profile', title: 'Profile', public: true, icon: MdAccountCircle }, + { location: '/messages', title: 'Messages', public: true, icon: MdOutlineMessage }, + { location: '/profile', title: 'Profile', public: true, icon: MdOutlineAccountCircle }, { location: '/users', title: 'Users', public: false, roles: [UserRoleEnum.ADMIN, UserRoleEnum.TEACHER], - icon: MdGroup, + icon: MdOutlineGroup, }, ], }; diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 8dd813c..2e5ce23 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -7,6 +7,7 @@ export interface IAppConfig { appName: string; appDescription: string; appVersion: string; + appGithubLink: string; }; links: LinkType[]; }