mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: users management page layout
This commit is contained in:
parent
79b82d317b
commit
b0155d1ab3
@ -24,7 +24,7 @@ import MainPage from 'pages/main';
|
|||||||
import CoursesPage from 'pages/courses';
|
import CoursesPage from 'pages/courses';
|
||||||
import MessagesPage from 'pages/messages';
|
import MessagesPage from 'pages/messages';
|
||||||
import ProfilePage from 'pages/profile';
|
import ProfilePage from 'pages/profile';
|
||||||
import ControlPage from 'pages/control';
|
import UsersPage from 'pages/users';
|
||||||
import AuthPage from 'pages/auth';
|
import AuthPage from 'pages/auth';
|
||||||
import NotFoundPage from 'pages/404';
|
import NotFoundPage from 'pages/404';
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ const App = () => {
|
|||||||
<PrivateRoute path='/messages' component={MessagesPage} title='Messages' />
|
<PrivateRoute path='/messages' component={MessagesPage} title='Messages' />
|
||||||
<PrivateRoute path='/profile' component={ProfilePage} title='Profile' />
|
<PrivateRoute path='/profile' component={ProfilePage} title='Profile' />
|
||||||
<PrivateRoute
|
<PrivateRoute
|
||||||
path='/control'
|
path='/users'
|
||||||
component={ControlPage}
|
component={UsersPage}
|
||||||
title='Control'
|
title='Control'
|
||||||
roles={[UserRoleEnum.ADMIN, UserRoleEnum.TEACHER]}
|
roles={[UserRoleEnum.ADMIN, UserRoleEnum.TEACHER]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { UserRoleEnum } from 'enums';
|
import { UserRoleEnum } from 'enums';
|
||||||
import { MdAccountCircle, MdBuild, MdCollectionsBookmark, MdHome, MdMessage } from 'react-icons/md';
|
import { MdAccountCircle, MdCollectionsBookmark, MdGroup, MdHome, MdMessage } from 'react-icons/md';
|
||||||
import { IAppConfig } from './interfaces';
|
import { IAppConfig } from './interfaces';
|
||||||
|
|
||||||
const config: IAppConfig = {
|
const config: IAppConfig = {
|
||||||
@ -13,11 +13,11 @@ const config: IAppConfig = {
|
|||||||
{ location: '/messages', title: 'Messages', public: true, icon: MdMessage },
|
{ location: '/messages', title: 'Messages', public: true, icon: MdMessage },
|
||||||
{ location: '/profile', title: 'Profile', public: true, icon: MdAccountCircle },
|
{ location: '/profile', title: 'Profile', public: true, icon: MdAccountCircle },
|
||||||
{
|
{
|
||||||
location: '/control',
|
location: '/users',
|
||||||
title: 'Control',
|
title: 'Users',
|
||||||
public: false,
|
public: false,
|
||||||
roles: [UserRoleEnum.ADMIN, UserRoleEnum.TEACHER],
|
roles: [UserRoleEnum.ADMIN, UserRoleEnum.TEACHER],
|
||||||
icon: MdBuild,
|
icon: MdGroup,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -33,7 +33,7 @@ const useUpdateUserContactsQuery = () => {
|
|||||||
if (isMountedRef.current) {
|
if (isMountedRef.current) {
|
||||||
setState(s => ({ ...s, result }));
|
setState(s => ({ ...s, result }));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
if (isMountedRef.current) {
|
if (isMountedRef.current) {
|
||||||
setState(s => ({ ...s, error }));
|
setState(s => ({ ...s, error }));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Box, Heading, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Grid } from '@chakra-ui/react';
|
|
||||||
|
|
||||||
import { IPageProps } from 'interfaces';
|
|
||||||
import { observer } from 'mobx-react';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Control page
|
|
||||||
*/
|
|
||||||
const ControlPage: React.FC<IPageProps> = ({ title }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Breadcrumb fontWeight='medium' fontSize='sm'>
|
|
||||||
<BreadcrumbItem isCurrentPage>
|
|
||||||
<BreadcrumbLink href='/'>{title}</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
</Breadcrumb>
|
|
||||||
<Box mt='10'>
|
|
||||||
<Box>
|
|
||||||
<Heading as='h1'>Control page</Heading>
|
|
||||||
<Grid templateColumns='3fr 1fr' mt='25px'>
|
|
||||||
...
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default observer(ControlPage);
|
|
||||||
96
src/pages/users/index.tsx
Normal file
96
src/pages/users/index.tsx
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Select } from '@chakra-ui/react';
|
||||||
|
import { Box, Flex, Text, Button, Heading, Badge, Avatar, Stack, Tooltip } from '@chakra-ui/react';
|
||||||
|
import { Input, InputGroup, InputLeftElement, IconButton } from '@chakra-ui/react';
|
||||||
|
import { IPageProps } from 'interfaces';
|
||||||
|
import { AddIcon, ChevronLeftIcon, ChevronRightIcon, SearchIcon } from '@chakra-ui/icons';
|
||||||
|
import { MdMoreHoriz } from 'react-icons/md';
|
||||||
|
import { FaFileExcel } from 'react-icons/fa';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Users Page
|
||||||
|
*/
|
||||||
|
const UsersPage: React.FC<IPageProps> = ({ title }) => {
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Heading as='h1'>User management</Heading>
|
||||||
|
<Box mt='5'>
|
||||||
|
<Flex justifyContent='space-between' sx={{ gap: '10px' }} flexWrap='wrap'>
|
||||||
|
<Box flexBasis='600px'>
|
||||||
|
<Flex>
|
||||||
|
<Select defaultValue='any' w='full' mr='2'>
|
||||||
|
<option value='any'>Any role</option>
|
||||||
|
<option value='administrator'>Administrator</option>
|
||||||
|
<option value='teacher'>Teacher</option>
|
||||||
|
<option value='student'>Student</option>
|
||||||
|
</Select>
|
||||||
|
<InputGroup maxW='400px' w='full'>
|
||||||
|
<InputLeftElement pointerEvents='none' children={<SearchIcon color='gray.300' />} />
|
||||||
|
<Input placeholder='Search for a user...' />
|
||||||
|
</InputGroup>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
<Flex sx={{ gap: '10px' }}>
|
||||||
|
<Button variant='outline' color='blue.500' leftIcon={<AddIcon />}>
|
||||||
|
Create new
|
||||||
|
</Button>
|
||||||
|
<Button variant='outline' colorScheme='green' leftIcon={<FaFileExcel />}>
|
||||||
|
Import
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<Box>
|
||||||
|
<Flex mt='7' p='0 10px' fontWeight='bold' alignItems='center' justifyContent='space-between'>
|
||||||
|
<Text>Total users: (24)</Text>
|
||||||
|
<Text>Actions</Text>
|
||||||
|
</Flex>
|
||||||
|
<Stack mt='4' spacing='2'>
|
||||||
|
{[1, 2, 3, 4, 5, 6, 7].map(e => (
|
||||||
|
<Box key={e} borderWidth='1px' borderRadius='lg' w='full' p='3'>
|
||||||
|
<Flex alignItems='center' justifyContent='space-between' sx={{ gap: '20px' }}>
|
||||||
|
<Flex alignItems='center'>
|
||||||
|
<Avatar name='Sergey Yarkov' size='sm' mr='3' />
|
||||||
|
<Box>
|
||||||
|
<Text fontSize='md' fontWeight='medium'>
|
||||||
|
Sergey Yarkov
|
||||||
|
</Text>
|
||||||
|
<Text fontSize='sm' color='gray.600'>
|
||||||
|
serzh.yarkov@gmail.com
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex sx={{ gap: '5px' }}>
|
||||||
|
<Badge variant='subtle' colorScheme='purple'>
|
||||||
|
Administrator
|
||||||
|
</Badge>
|
||||||
|
</Flex>
|
||||||
|
<Box>
|
||||||
|
<Tooltip label='Edit user' openDelay={400}>
|
||||||
|
<IconButton aria-label='Actions' variant='ghost' icon={<MdMoreHoriz />} />
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
<Flex mt='5' flexDirection={{ base: 'column', sm: 'column', md: 'row' }}>
|
||||||
|
<Box textAlign={{ base: 'center', sm: 'center', md: 'left' }} mb={{ base: '2', md: '0' }}>
|
||||||
|
Page <b>1</b> of 23
|
||||||
|
</Box>
|
||||||
|
<Flex ml='auto' mr='auto' alignItems='center' sx={{ gap: '30px' }}>
|
||||||
|
<Button variant='link' leftIcon={<ChevronLeftIcon />}>
|
||||||
|
Previous page
|
||||||
|
</Button>
|
||||||
|
<Button variant='link' rightIcon={<ChevronRightIcon />}>
|
||||||
|
Next page
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default observer(UsersPage);
|
||||||
@ -47,7 +47,7 @@ export default class UserStore {
|
|||||||
data: { id, first_name, last_name, email, roles, contacts, courses },
|
data: { id, first_name, last_name, email, roles, contacts, courses },
|
||||||
} = result;
|
} = result;
|
||||||
|
|
||||||
console.log(`[UserStore]: Fetched authorized user data.`, result);
|
console.log(`[UserStore]: ${result.message}`, result);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.me = {
|
this.me = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user