mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 18:29:15 +03:00
feat: added Loading component
This commit is contained in:
parent
5dae2f5975
commit
248e57e548
@ -1,19 +1,31 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
import { Redirect } from 'react-router';
|
||||||
import { useErrorHandler } from 'react-error-boundary';
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
|
import { userContainRoles } from 'helpers';
|
||||||
import { Flex, Box } from '@chakra-ui/react';
|
import { Flex, Box } from '@chakra-ui/react';
|
||||||
import { useRootStore } from 'hooks/useRootStore';
|
|
||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
import { UserRoleEnum } from 'enums';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components
|
||||||
|
*/
|
||||||
|
import LoadingPage from 'components/LoadingPage';
|
||||||
import Header from 'components/Header';
|
import Header from 'components/Header';
|
||||||
import NavDesktop from 'components/Nav/Desktop';
|
import NavDesktop from 'components/Nav/Desktop';
|
||||||
import { UserRoleEnum } from 'enums';
|
|
||||||
import { userContainRoles } from 'helpers';
|
/**
|
||||||
import { Redirect } from 'react-router';
|
* Hooks
|
||||||
|
*/
|
||||||
|
import { useRootStore } from 'hooks/useRootStore';
|
||||||
|
|
||||||
type LayoutPropsType = { roles: UserRoleEnum[] | undefined };
|
type LayoutPropsType = { roles: UserRoleEnum[] | undefined };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Layout component
|
* Render the current page using layout
|
||||||
* Сomponent for rendering the current page.
|
|
||||||
*/
|
*/
|
||||||
const Layout: React.FC<LayoutPropsType> = ({ children, roles }) => {
|
const Layout: React.FC<LayoutPropsType> = ({ children, roles }) => {
|
||||||
const { userStore } = useRootStore();
|
const { userStore } = useRootStore();
|
||||||
@ -53,7 +65,7 @@ const Layout: React.FC<LayoutPropsType> = ({ children, roles }) => {
|
|||||||
*/
|
*/
|
||||||
if (roles) {
|
if (roles) {
|
||||||
const { me } = userStore;
|
const { me } = userStore;
|
||||||
if (me === null) return null;
|
if (me === null) return <LoadingPage />;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user does not have the required roles
|
* The user does not have the required roles
|
||||||
|
|||||||
17
src/components/LoadingPage/LoadingPage.tsx
Normal file
17
src/components/LoadingPage/LoadingPage.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Flex, Box, Spinner, Text } from '@chakra-ui/react';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const LoadingPage: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Flex justifyContent='center' mt='20' maxW='950px'>
|
||||||
|
<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'>
|
||||||
|
Loading...
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoadingPage;
|
||||||
3
src/components/LoadingPage/index.ts
Normal file
3
src/components/LoadingPage/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import LoadingPage from './LoadingPage';
|
||||||
|
|
||||||
|
export default LoadingPage;
|
||||||
@ -13,7 +13,9 @@ import config from 'config';
|
|||||||
import useLogoutQuery from 'hooks/useLogoutQuery';
|
import useLogoutQuery from 'hooks/useLogoutQuery';
|
||||||
|
|
||||||
const NavMobile: React.FC = () => {
|
const NavMobile: React.FC = () => {
|
||||||
const { userStore } = useRootStore();
|
const {
|
||||||
|
userStore: { me },
|
||||||
|
} = useRootStore();
|
||||||
const { colorMode } = useColorMode();
|
const { colorMode } = useColorMode();
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const { logout } = useLogoutQuery();
|
const { logout } = useLogoutQuery();
|
||||||
@ -29,8 +31,7 @@ const NavMobile: React.FC = () => {
|
|||||||
<Flex as='nav' flexDirection='column' alignItems='flex-start' textDecoration='none' mb='20px'>
|
<Flex as='nav' flexDirection='column' alignItems='flex-start' textDecoration='none' mb='20px'>
|
||||||
<NavList links={config.links} onCloseDrawer={onClose} />
|
<NavList links={config.links} onCloseDrawer={onClose} />
|
||||||
</Flex>
|
</Flex>
|
||||||
{userStore.me ? (
|
{me !== null ? (
|
||||||
<Box pb='10px'>
|
|
||||||
<Box
|
<Box
|
||||||
minHeight='60px'
|
minHeight='60px'
|
||||||
padding='10px'
|
padding='10px'
|
||||||
@ -39,16 +40,12 @@ const NavMobile: React.FC = () => {
|
|||||||
backgroundColor={colorMode === 'dark' ? 'gray.700' : 'gray.100'}
|
backgroundColor={colorMode === 'dark' ? 'gray.700' : 'gray.100'}
|
||||||
>
|
>
|
||||||
<Flex alignItems='center'>
|
<Flex alignItems='center'>
|
||||||
<Avatar size='sm' name={`${userStore.me.first_name} ${userStore.me.last_name}`} marginRight={3} />
|
<Avatar size='sm' name={me.fullname} marginRight={3} />
|
||||||
<Flex flexDirection='column'>
|
<Flex flexDirection='column'>
|
||||||
<Text as='span' mr={2} lineHeight='1.2'>
|
<Text as='span' mr={2} lineHeight='1.2'>
|
||||||
{`${userStore.me.first_name} ${userStore.me.last_name}`}
|
{me.fullname}
|
||||||
</Text>
|
</Text>
|
||||||
<Link
|
<Link to={`/profile`} style={{ fontSize: '13px', textDecoration: 'underline' }} onClick={onClose}>
|
||||||
to={`/profile`}
|
|
||||||
style={{ fontSize: '13px', textDecoration: 'underline' }}
|
|
||||||
onClick={onClose}
|
|
||||||
>
|
|
||||||
View profile
|
View profile
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -61,7 +58,6 @@ const NavMobile: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
|
||||||
) : (
|
) : (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
h='60px'
|
h='60px'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IUser } from 'interfaces';
|
import { IUser } from 'interfaces';
|
||||||
import { Stack, StackDivider } from '@chakra-ui/layout';
|
import { Box, Text, Stack, StackDivider } from '@chakra-ui/layout';
|
||||||
import CourseItem from './CourseItem';
|
import CourseItem from './CourseItem';
|
||||||
|
|
||||||
type CourseListPropsType = {
|
type CourseListPropsType = {
|
||||||
@ -16,6 +16,16 @@ const CourseList: React.FC<CourseListPropsType> = ({ courses }) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (courses.length === 0) {
|
||||||
|
return (
|
||||||
|
<Box textAlign='center' mt='10'>
|
||||||
|
<Text color='gray.500' userSelect='none'>
|
||||||
|
You are not a member of any course
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack spacing='8' divider={<StackDivider />}>
|
<Stack spacing='8' divider={<StackDivider />}>
|
||||||
{courses.map(course => (
|
{courses.map(course => (
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user