mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: users pagination & searching users by role
This commit is contained in:
parent
3ab6cafb06
commit
a4f3aebec5
@ -12,6 +12,7 @@ const UserBadge: React.FC<{ roles: IUserRole[] }> = ({ roles }) => {
|
|||||||
if (userHasRoles(roles, [UserRoleEnum.ADMIN])) return { name: 'Administrator', color: 'purple' };
|
if (userHasRoles(roles, [UserRoleEnum.ADMIN])) return { name: 'Administrator', color: 'purple' };
|
||||||
if (userHasRoles(roles, [UserRoleEnum.TEACHER])) return { name: 'Teacher', color: 'orange' };
|
if (userHasRoles(roles, [UserRoleEnum.TEACHER])) return { name: 'Teacher', color: 'orange' };
|
||||||
if (userHasRoles(roles, [UserRoleEnum.STUDENT])) return { name: 'Student', color: 'blue' };
|
if (userHasRoles(roles, [UserRoleEnum.STUDENT])) return { name: 'Student', color: 'blue' };
|
||||||
|
if (roles.length === 0) return { name: 'Guest', color: 'gray' };
|
||||||
};
|
};
|
||||||
|
|
||||||
const role = getCurrentRole();
|
const role = getCurrentRole();
|
||||||
|
|||||||
@ -1,10 +1,17 @@
|
|||||||
import React from 'react';
|
import { createContext } from 'react';
|
||||||
import { ProfilePageViewStatusContextType } from 'types';
|
import { ProfilePageViewStatusContextType, UsersPageContextType } from 'types';
|
||||||
import RootStore from '../stores/RootStore';
|
import RootStore from '../stores/RootStore';
|
||||||
|
|
||||||
export const StoreContext = React.createContext<RootStore | undefined>(undefined);
|
export const StoreContext = createContext<RootStore | undefined>(undefined);
|
||||||
|
|
||||||
export const ProfilePageViewContext = React.createContext<ProfilePageViewStatusContextType>({
|
export const ProfilePageViewContext = createContext<ProfilePageViewStatusContextType>({
|
||||||
statusPageView: 'default',
|
statusPageView: 'default',
|
||||||
setStatusPageView: () => {},
|
setStatusPageView: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const UsersPageContext = createContext<UsersPageContextType>({
|
||||||
|
searchingRole: undefined,
|
||||||
|
setSearchingRole: () => {},
|
||||||
|
loading: false,
|
||||||
|
setLoading: () => {},
|
||||||
|
});
|
||||||
|
|||||||
@ -112,6 +112,9 @@ export interface IUserRole {
|
|||||||
export interface IApiRespose<T> {
|
export interface IApiRespose<T> {
|
||||||
data: T;
|
data: T;
|
||||||
meta?: {
|
meta?: {
|
||||||
|
/**
|
||||||
|
* The server can return the pagination meta data
|
||||||
|
*/
|
||||||
pagination?: IPaginationMeta;
|
pagination?: IPaginationMeta;
|
||||||
};
|
};
|
||||||
message: string;
|
message: string;
|
||||||
|
|||||||
@ -75,6 +75,7 @@ const ProfilePage: React.FC<IPageProps> = () => {
|
|||||||
{statusPageView.status === 'default' && (
|
{statusPageView.status === 'default' && (
|
||||||
<Box maxW='900px'>
|
<Box maxW='900px'>
|
||||||
<Heading as='h1'>My account</Heading>
|
<Heading as='h1'>My account</Heading>
|
||||||
|
<Text mt='2'>Update you contacts information or password here.</Text>
|
||||||
<Flex
|
<Flex
|
||||||
alignItems='center'
|
alignItems='center'
|
||||||
mt='20'
|
mt='20'
|
||||||
|
|||||||
@ -2,10 +2,12 @@ import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
|
|||||||
import { Flex, Box, Stack, Text } from '@chakra-ui/layout';
|
import { Flex, Box, Stack, Text } from '@chakra-ui/layout';
|
||||||
import { Button } from '@chakra-ui/button';
|
import { Button } from '@chakra-ui/button';
|
||||||
import { IPaginationMeta, IUser } from 'interfaces';
|
import { IPaginationMeta, IUser } from 'interfaces';
|
||||||
import React, { useState } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import UserItem from './UserItem';
|
import UserItem from './UserItem';
|
||||||
import { useRootStore } from 'hooks/useRootStore';
|
import { useRootStore } from 'hooks/useRootStore';
|
||||||
import { useErrorHandler } from 'react-error-boundary';
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
|
import { UsersPageContextType } from 'types';
|
||||||
|
import { UsersPageContext } from 'contexts';
|
||||||
|
|
||||||
type UserListPropsType = {
|
type UserListPropsType = {
|
||||||
users: IUser[];
|
users: IUser[];
|
||||||
@ -14,21 +16,18 @@ type UserListPropsType = {
|
|||||||
|
|
||||||
const UserList: React.FC<UserListPropsType> = ({ users, pagination }) => {
|
const UserList: React.FC<UserListPropsType> = ({ users, pagination }) => {
|
||||||
const { userStore } = useRootStore();
|
const { userStore } = useRootStore();
|
||||||
|
const { searchingRole, loading, setLoading } = useContext<UsersPageContextType>(UsersPageContext);
|
||||||
const handleError = useErrorHandler();
|
const handleError = useErrorHandler();
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const pagesCount = Math.ceil(pagination.total / pagination.per_page);
|
||||||
const pagesCount = Math.round(pagination.total / pagination.per_page);
|
|
||||||
const [pages] = useState<number>(pagesCount < 1 ? 1 : pagesCount);
|
|
||||||
const [currentPage, setCurrentPage] = useState<number>(pagination.current_page);
|
|
||||||
|
|
||||||
const nextPage = async () => {
|
const nextPage = async () => {
|
||||||
if (currentPage === pages) return;
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await userStore.loadUsersData({
|
await userStore.loadUsersData({
|
||||||
page: currentPage + 1,
|
page: pagination.current_page + 1,
|
||||||
limit: pagination.per_page,
|
limit: pagination.per_page,
|
||||||
|
role: searchingRole,
|
||||||
});
|
});
|
||||||
setCurrentPage(p => p + 1);
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -37,14 +36,13 @@ const UserList: React.FC<UserListPropsType> = ({ users, pagination }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const prevPage = async () => {
|
const prevPage = async () => {
|
||||||
if (currentPage <= 1) return;
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await userStore.loadUsersData({
|
await userStore.loadUsersData({
|
||||||
page: currentPage - 1,
|
page: pagination.current_page - 1,
|
||||||
limit: pagination.per_page,
|
limit: pagination.per_page,
|
||||||
|
role: searchingRole,
|
||||||
});
|
});
|
||||||
setCurrentPage(p => p - 1);
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
} finally {
|
} finally {
|
||||||
@ -52,19 +50,13 @@ const UserList: React.FC<UserListPropsType> = ({ users, pagination }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pagination.total === 0) {
|
|
||||||
return (
|
|
||||||
<Box textAlign='center' mt='10' userSelect='none'>
|
|
||||||
<Text color='gray.500'>There are no users in the system</Text>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{pagination.total !== 0 ? (
|
||||||
<>
|
<>
|
||||||
<Box>
|
<Box>
|
||||||
<Flex mt='7' p='0 10px' fontWeight='bold' alignItems='center' justifyContent='space-between'>
|
<Flex mt='7' p='0 10px' fontWeight='bold' alignItems='center' justifyContent='space-between'>
|
||||||
<Text>Total users: ({pagination.total})</Text>
|
<Text>Total: ({pagination.total})</Text>
|
||||||
<Text>Actions</Text>
|
<Text>Actions</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@ -81,18 +73,34 @@ const UserList: React.FC<UserListPropsType> = ({ users, pagination }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
<Flex mt='auto' mb='16' flexDirection={{ base: 'column', sm: 'column', md: 'row' }}>
|
<Flex mt='auto' mb='16' flexDirection={{ base: 'column', sm: 'column', md: 'row' }}>
|
||||||
<Box textAlign={{ base: 'center', sm: 'center', md: 'left' }} mb={{ base: '2', md: '0' }}>
|
<Box textAlign={{ base: 'center', sm: 'center', md: 'left' }} mb={{ base: '2', md: '0' }}>
|
||||||
Page <b>{currentPage}</b> of {pages}
|
Page <b>{pagination.current_page}</b> of {pagesCount}
|
||||||
</Box>
|
</Box>
|
||||||
<Flex ml='auto' mr='auto' alignItems='center' sx={{ gap: '30px' }}>
|
<Flex ml='auto' mr='auto' alignItems='center' sx={{ gap: '30px' }}>
|
||||||
<Button onClick={prevPage} disabled={currentPage <= 1} variant='link' leftIcon={<ChevronLeftIcon />}>
|
<Button
|
||||||
|
onClick={prevPage}
|
||||||
|
disabled={pagination.current_page <= 1}
|
||||||
|
variant='link'
|
||||||
|
leftIcon={<ChevronLeftIcon />}
|
||||||
|
>
|
||||||
Previous page
|
Previous page
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={nextPage} disabled={currentPage === pages} variant='link' rightIcon={<ChevronRightIcon />}>
|
<Button
|
||||||
|
onClick={nextPage}
|
||||||
|
disabled={pagination.current_page === pagesCount}
|
||||||
|
variant='link'
|
||||||
|
rightIcon={<ChevronRightIcon />}
|
||||||
|
>
|
||||||
Next page
|
Next page
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
|
) : (
|
||||||
|
<Box textAlign='center' mt='10' userSelect='none'>
|
||||||
|
<Text color='gray.500'>Cannot find any users.</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
53
src/pages/users/components/UserSearch/UserSearch.tsx
Normal file
53
src/pages/users/components/UserSearch/UserSearch.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Flex, Select, Input, InputGroup, InputLeftElement } from '@chakra-ui/react';
|
||||||
|
import { SearchIcon } from '@chakra-ui/icons';
|
||||||
|
import { useRootStore } from 'hooks/useRootStore';
|
||||||
|
import { UserRoleEnum } from 'enums';
|
||||||
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
|
import { UsersPageContext } from 'contexts';
|
||||||
|
import { UsersPageContextType } from 'types';
|
||||||
|
|
||||||
|
type SelectRoleStateType = UserRoleEnum | 'any';
|
||||||
|
|
||||||
|
const UserSearch: React.FC = () => {
|
||||||
|
const { userStore } = useRootStore();
|
||||||
|
const { searchingRole, setSearchingRole, setLoading } = useContext<UsersPageContextType>(UsersPageContext);
|
||||||
|
const { pagination } = userStore;
|
||||||
|
const handleError = useErrorHandler();
|
||||||
|
|
||||||
|
if (pagination === undefined) return null;
|
||||||
|
|
||||||
|
const onSearchRole: React.ChangeEventHandler<HTMLSelectElement> | undefined = async e => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const value = e.target.value as SelectRoleStateType;
|
||||||
|
await userStore.loadUsersData({
|
||||||
|
page: 1,
|
||||||
|
limit: pagination.per_page,
|
||||||
|
role: value,
|
||||||
|
});
|
||||||
|
setSearchingRole(value);
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex flexBasis='600px'>
|
||||||
|
<Select value={searchingRole} onChange={onSearchRole} w='full' mr='2'>
|
||||||
|
<option value='any'>Any role</option>
|
||||||
|
<option value={UserRoleEnum.ADMIN}>Administrator</option>
|
||||||
|
<option value={UserRoleEnum.TEACHER}>Teacher</option>
|
||||||
|
<option value={UserRoleEnum.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>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UserSearch;
|
||||||
3
src/pages/users/components/UserSearch/index.ts
Normal file
3
src/pages/users/components/UserSearch/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import UserSearch from './UserSearch';
|
||||||
|
|
||||||
|
export default UserSearch;
|
||||||
@ -1,19 +1,19 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Select } from '@chakra-ui/react';
|
import { Box, Flex, Button, Heading, Text } from '@chakra-ui/react';
|
||||||
import { Box, Flex, Button, Heading } from '@chakra-ui/react';
|
import { AddIcon } from '@chakra-ui/icons';
|
||||||
import { Input, InputGroup, InputLeftElement } from '@chakra-ui/react';
|
|
||||||
import { AddIcon, SearchIcon } from '@chakra-ui/icons';
|
|
||||||
import { FaFileExcel } from 'react-icons/fa';
|
import { FaFileExcel } from 'react-icons/fa';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
import { IPageProps } from 'interfaces';
|
import { IPageProps } from 'interfaces';
|
||||||
|
import { SearchingRoleStateType } from 'types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Components
|
* Components
|
||||||
*/
|
*/
|
||||||
|
import UserSearch from './components/UserSearch';
|
||||||
import UserList from './components/UserList';
|
import UserList from './components/UserList';
|
||||||
import LoadingPage from './components/LoadingPage';
|
import LoadingPage from './components/LoadingPage';
|
||||||
|
|
||||||
@ -24,36 +24,34 @@ import { useRootStore } from 'hooks/useRootStore';
|
|||||||
import { useErrorHandler } from 'react-error-boundary';
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
import { useLocation } from 'react-router';
|
import { useLocation } from 'react-router';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context
|
||||||
|
*/
|
||||||
|
import { UsersPageContext } from 'contexts';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Users Page
|
* Users Page
|
||||||
*/
|
*/
|
||||||
const UsersPage: React.FC<IPageProps> = ({ title }) => {
|
const UsersPage: React.FC<IPageProps> = ({ title }) => {
|
||||||
const { userStore } = useRootStore();
|
const { userStore } = useRootStore();
|
||||||
|
const [searchingRole, setSearchingRole] = useState<SearchingRoleStateType>(undefined);
|
||||||
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const handleError = useErrorHandler();
|
const handleError = useErrorHandler();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
userStore.loadUsersData({ page: 1, limit: 2 }).catch(error => handleError(error));
|
userStore.loadUsersData().catch(error => handleError(error));
|
||||||
}, [handleError, userStore, location.search]);
|
}, [handleError, userStore, location.search]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<UsersPageContext.Provider value={{ searchingRole, setSearchingRole, loading, setLoading }}>
|
||||||
<Box h='full'>
|
<Box h='full'>
|
||||||
<Heading as='h1'>User management</Heading>
|
<Heading as='h1'>User management</Heading>
|
||||||
|
<Text mt='2'>You can add or delete your users on this page.</Text>
|
||||||
{userStore.users !== null ? (
|
{userStore.users !== null ? (
|
||||||
<Flex mt='5' flexDir='column' h='full'>
|
<Flex mt='5' flexDir='column' h='full'>
|
||||||
<Flex justifyContent='space-between' sx={{ gap: '10px' }} flexWrap='wrap'>
|
<Flex justifyContent='space-between' sx={{ gap: '10px' }} flexWrap='wrap'>
|
||||||
<Flex flexBasis='600px'>
|
<UserSearch />
|
||||||
<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>
|
|
||||||
<Flex sx={{ gap: '10px' }}>
|
<Flex sx={{ gap: '10px' }}>
|
||||||
<Button variant='outline' color='blue.500' leftIcon={<AddIcon />}>
|
<Button variant='outline' color='blue.500' leftIcon={<AddIcon />}>
|
||||||
Create new
|
Create new
|
||||||
@ -63,14 +61,13 @@ const UsersPage: React.FC<IPageProps> = ({ title }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
{userStore.users.meta.pagination && (
|
{userStore.pagination && <UserList users={userStore.users} pagination={userStore.pagination} />}
|
||||||
<UserList users={userStore.users.data} pagination={userStore.users.meta.pagination} />
|
|
||||||
)}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
) : (
|
) : (
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
</UsersPageContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { AxiosInstance } from 'axios';
|
import { AxiosInstance } from 'axios';
|
||||||
import { IApiRespose, IMe, IUser, IUserContacts } from 'interfaces';
|
import { IApiRespose, IMe, IUser, IUserContacts } from 'interfaces';
|
||||||
import * as helpers from 'helpers';
|
import * as helpers from 'helpers';
|
||||||
|
import { UserRoleEnum } from 'enums';
|
||||||
|
|
||||||
export type FetchUsersParamsType = { page?: number; limit?: number };
|
export type FetchUsersParamsType = { page?: number; limit?: number; role?: UserRoleEnum | 'any' };
|
||||||
|
|
||||||
export default class UserService {
|
export default class UserService {
|
||||||
public api: AxiosInstance;
|
public api: AxiosInstance;
|
||||||
@ -17,11 +18,12 @@ export default class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async fetchAll(params?: FetchUsersParamsType): Promise<IApiRespose<IUser[]>> {
|
public async fetchAll(params?: FetchUsersParamsType): Promise<IApiRespose<IUser[]>> {
|
||||||
const { page, limit } = params || {};
|
const { page = 1, limit = 1, role } = params || {};
|
||||||
const result = await this.api.get('/v1/users', {
|
const result = await this.api.get('/v1/users', {
|
||||||
params: {
|
params: {
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
|
role: role === 'any' ? undefined : role,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return result.data;
|
return result.data;
|
||||||
|
|||||||
@ -19,7 +19,9 @@ export default class UserStore {
|
|||||||
|
|
||||||
public me: IMe | null = null;
|
public me: IMe | null = null;
|
||||||
|
|
||||||
public users: { data: IUser[]; meta: { pagination?: IPaginationMeta } } | null = null;
|
public users: IUser[] | null = null;
|
||||||
|
|
||||||
|
public pagination: IPaginationMeta | undefined;
|
||||||
|
|
||||||
constructor(root: RootStore, api: AxiosInstance) {
|
constructor(root: RootStore, api: AxiosInstance) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
@ -33,12 +35,8 @@ export default class UserStore {
|
|||||||
console.log(`[${this.constructor.name}]: ${result.message}`, result);
|
console.log(`[${this.constructor.name}]: ${result.message}`, result);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.users = {
|
this.users = result.data;
|
||||||
data: result.data,
|
this.pagination = result.meta && result.meta.pagination;
|
||||||
meta: {
|
|
||||||
pagination: result.meta?.pagination,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -70,7 +68,7 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +90,7 @@ export default class UserStore {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +106,7 @@ export default class UserStore {
|
|||||||
try {
|
try {
|
||||||
const result = await this.userService.updatePassword(oldPassword, newPassword);
|
const result = await this.userService.updatePassword(oldPassword, newPassword);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +121,7 @@ export default class UserStore {
|
|||||||
try {
|
try {
|
||||||
const result = await this.userService.updateEmail(email);
|
const result = await this.userService.updateEmail(email);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +142,7 @@ export default class UserStore {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/types/index.d.ts
vendored
16
src/types/index.d.ts
vendored
@ -1,4 +1,5 @@
|
|||||||
import { UserRoleEnum } from 'enums';
|
import { UserRoleEnum } from 'enums';
|
||||||
|
import React from 'react';
|
||||||
import { IconType } from 'react-icons/lib';
|
import { IconType } from 'react-icons/lib';
|
||||||
|
|
||||||
export type LinkType = {
|
export type LinkType = {
|
||||||
@ -27,7 +28,22 @@ export type ProfilePageStatusType = {
|
|||||||
confirmEmailData?: ConfirmEmailContainerDataType;
|
confirmEmailData?: ConfirmEmailContainerDataType;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProfilePageViewStatusContextType = {
|
export type ProfilePageViewStatusContextType = {
|
||||||
statusPageView: ProfilePageStatusType['status'];
|
statusPageView: ProfilePageStatusType['status'];
|
||||||
setStatusPageView: React.Dispatch<React.SetStateAction<ProfilePageStatusType>>;
|
setStatusPageView: React.Dispatch<React.SetStateAction<ProfilePageStatusType>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SearchingRoleStateType = UserRoleEnum | 'any' | undefined;
|
||||||
|
export type UsersPageContextType = {
|
||||||
|
/**
|
||||||
|
* Search users by user role
|
||||||
|
*/
|
||||||
|
searchingRole: SearchingRoleStateType;
|
||||||
|
setSearchingRole: React.Dispatch<React.SetStateAction<SearchingRoleStateType>>;
|
||||||
|
/**
|
||||||
|
* Set loading state while loading users
|
||||||
|
*/
|
||||||
|
loading: boolean;
|
||||||
|
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user