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 MessagesPage from 'pages/messages';
|
||||
import ProfilePage from 'pages/profile';
|
||||
import ControlPage from 'pages/control';
|
||||
import UsersPage from 'pages/users';
|
||||
import AuthPage from 'pages/auth';
|
||||
import NotFoundPage from 'pages/404';
|
||||
|
||||
@ -41,8 +41,8 @@ const App = () => {
|
||||
<PrivateRoute path='/messages' component={MessagesPage} title='Messages' />
|
||||
<PrivateRoute path='/profile' component={ProfilePage} title='Profile' />
|
||||
<PrivateRoute
|
||||
path='/control'
|
||||
component={ControlPage}
|
||||
path='/users'
|
||||
component={UsersPage}
|
||||
title='Control'
|
||||
roles={[UserRoleEnum.ADMIN, UserRoleEnum.TEACHER]}
|
||||
/>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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';
|
||||
|
||||
const config: IAppConfig = {
|
||||
@ -13,11 +13,11 @@ const config: IAppConfig = {
|
||||
{ location: '/messages', title: 'Messages', public: true, icon: MdMessage },
|
||||
{ location: '/profile', title: 'Profile', public: true, icon: MdAccountCircle },
|
||||
{
|
||||
location: '/control',
|
||||
title: 'Control',
|
||||
location: '/users',
|
||||
title: 'Users',
|
||||
public: false,
|
||||
roles: [UserRoleEnum.ADMIN, UserRoleEnum.TEACHER],
|
||||
icon: MdBuild,
|
||||
icon: MdGroup,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@ const useUpdateUserContactsQuery = () => {
|
||||
if (isMountedRef.current) {
|
||||
setState(s => ({ ...s, result }));
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (isMountedRef.current) {
|
||||
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 },
|
||||
} = result;
|
||||
|
||||
console.log(`[UserStore]: Fetched authorized user data.`, result);
|
||||
console.log(`[UserStore]: ${result.message}`, result);
|
||||
|
||||
runInAction(() => {
|
||||
this.me = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user