mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: password update form
This commit is contained in:
parent
add3b1bb24
commit
fe00bb5e72
@ -1,8 +1,8 @@
|
||||
import { AxiosRequestConfig } from 'axios';
|
||||
import { API_BASE_URL } from './constants';
|
||||
import * as constants from './constants';
|
||||
|
||||
const apiConfig: AxiosRequestConfig = {
|
||||
baseURL: API_BASE_URL,
|
||||
baseURL: constants.API_BASE_URL,
|
||||
responseType: 'json',
|
||||
withCredentials: true,
|
||||
};
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import Cookies from 'js-cookie';
|
||||
import { useToast, Flex, Box, Heading, Text } from '@chakra-ui/react';
|
||||
import { MdError } from 'react-icons/md';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
|
||||
const ErrorFallback: React.FC<{ error: any }> = props => {
|
||||
const { userStore, authStore } = useRootStore();
|
||||
const { error } = props;
|
||||
const toast = useToast();
|
||||
|
||||
@ -10,6 +13,14 @@ const ErrorFallback: React.FC<{ error: any }> = props => {
|
||||
toast({ title: `${error.message}`, duration: 10000, isClosable: true, status: 'error' });
|
||||
});
|
||||
|
||||
if (error.response) {
|
||||
if (error.response.status === 401) {
|
||||
userStore.me = null;
|
||||
authStore.setIsLoggedIn(false);
|
||||
Cookies.remove('logged_in');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box textAlign='center' mt={40}>
|
||||
<Flex justifyContent='center'>
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Flex, Box, Text, Heading } from '@chakra-ui/react';
|
||||
import { MdSchool } from 'react-icons/md';
|
||||
import config from 'config';
|
||||
|
||||
const AppName: React.FC = () => {
|
||||
return (
|
||||
<Flex alignItems='center'>
|
||||
<Box mr='4'>
|
||||
<Box as={MdSchool} color='blue.500' size='36px' />
|
||||
</Box>
|
||||
<Box>
|
||||
<Heading as='p' fontSize='2xl' lineHeight='1'>
|
||||
{config.metaData.appName}
|
||||
</Heading>
|
||||
<Text as='small'>{config.metaData.appDescription}</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppName;
|
||||
@ -1,11 +1,13 @@
|
||||
import config from 'config';
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
import { Flex, Box, useColorMode } from '@chakra-ui/react';
|
||||
import AppName from './AppName';
|
||||
import { Flex, Box, Heading, Text, useColorMode } from '@chakra-ui/react';
|
||||
import UserInfo from './UserInfo';
|
||||
import UserNotifications from './UserNotifications';
|
||||
import NavMobile from 'components/Nav/Mobile';
|
||||
import ColorModeSwitcher from 'components/ColorModeSwitcher';
|
||||
import { MdSchool } from 'react-icons/md';
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const {
|
||||
@ -31,18 +33,27 @@ const Header: React.FC = () => {
|
||||
alignItems='center'
|
||||
padding='5px 1.5rem 5px 1.5rem'
|
||||
>
|
||||
<AppName />
|
||||
<Flex>
|
||||
<Flex alignItems='center'>
|
||||
<Box mr='4'>
|
||||
<Box as={MdSchool} color='blue.500' size='36px' />
|
||||
</Box>
|
||||
<Box>
|
||||
<Heading as='p' fontSize='2xl' lineHeight='1'>
|
||||
{config.metaData.appName}
|
||||
</Heading>
|
||||
<Text as='small'>{config.metaData.appDescription}</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
{isDesktop ? (
|
||||
<>
|
||||
<Flex>
|
||||
<ColorModeSwitcher />
|
||||
<UserNotifications />
|
||||
<UserInfo />
|
||||
</>
|
||||
</Flex>
|
||||
) : (
|
||||
<NavMobile />
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,7 +5,6 @@ import { Flex, Box } from '@chakra-ui/react';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
import Header from 'components/Header';
|
||||
import NavDesktop from 'components/Nav/Desktop';
|
||||
import ColorModeSwitcher from 'components/ColorModeSwitcher';
|
||||
|
||||
/**
|
||||
*
|
||||
@ -27,7 +26,7 @@ const Layout: React.FC = ({ children }) => {
|
||||
<NavDesktop />
|
||||
<Box
|
||||
as='main'
|
||||
flex='1 0 auto'
|
||||
flex='1 0'
|
||||
maxW='85rem'
|
||||
ml='25rem'
|
||||
mt='7rem'
|
||||
@ -45,7 +44,6 @@ const Layout: React.FC = ({ children }) => {
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<ColorModeSwitcher position='absolute' right={0} bottom={0} margin={5} />
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import React from 'react';
|
||||
import { ProfilePageViewStatusContextType } from 'types';
|
||||
import RootStore from '../stores/RootStore';
|
||||
|
||||
export const StoreContext = React.createContext<RootStore | undefined>(undefined);
|
||||
|
||||
export const ProfilePageViewContext = React.createContext<ProfilePageViewStatusContextType>({
|
||||
statusPageView: undefined,
|
||||
setStatusPageView: () => {},
|
||||
});
|
||||
|
||||
@ -1,15 +1,8 @@
|
||||
import { IconType } from 'react-icons/lib';
|
||||
import type { RouteProps } from 'react-router-dom';
|
||||
import type { RouteComponentProps } from 'react-router-dom';
|
||||
import { LinkType } from 'types';
|
||||
import { UserRoleEnum } from '../enums';
|
||||
|
||||
export type LinkType = {
|
||||
location: string;
|
||||
title: string;
|
||||
public: boolean;
|
||||
icon: IconType;
|
||||
};
|
||||
|
||||
export interface IAppConfig {
|
||||
metaData: {
|
||||
appName: string;
|
||||
|
||||
@ -18,9 +18,7 @@ const MainPage: React.FC<IPageProps> = ({ title }) => {
|
||||
<Box mt='10'>
|
||||
<Box>
|
||||
<Heading as='h1'>Main page</Heading>
|
||||
<Grid templateColumns='3fr 1fr' mt='25px'>
|
||||
...
|
||||
</Grid>
|
||||
<Grid templateColumns='3fr 1fr' mt='25px'></Grid>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { MdSave } from 'react-icons/md';
|
||||
import { IUserContacts } from 'interfaces';
|
||||
import { Box, Heading, Stack } from '@chakra-ui/layout';
|
||||
import { Text, Input, Button } from '@chakra-ui/react';
|
||||
import { FormControl, FormHelperText } from '@chakra-ui/form-control';
|
||||
import { Input } from '@chakra-ui/input';
|
||||
import { Text } from '@chakra-ui/react';
|
||||
import { Button } from '@chakra-ui/button';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
|
||||
import UpdateUserContactsSchema from 'validators/UpdateUserContactsSchema';
|
||||
import useUpdateUserContactsQuery from 'hooks/useUpdateUserContactsQuery';
|
||||
import { observer } from 'mobx-react';
|
||||
import UpdateUserContactsSchema from 'validators/UpdateUserContactsSchema';
|
||||
|
||||
type UpdateUserContactsInputType = {
|
||||
phone_number: string | null;
|
||||
@ -67,6 +64,7 @@ const UpdateUserContactsForm: React.FC<UpdateUserContactsFormProps> = ({ contact
|
||||
size='md'
|
||||
variant='flushed'
|
||||
placeholder='+1 (234) 555-1234'
|
||||
isInvalid={errors.phone_number ? true : false}
|
||||
{...register('phone_number')}
|
||||
/>
|
||||
<Text as='small' color='red.500'>
|
||||
@ -75,21 +73,42 @@ const UpdateUserContactsForm: React.FC<UpdateUserContactsFormProps> = ({ contact
|
||||
</FormControl>
|
||||
<FormControl id='twitter_id'>
|
||||
<FormHelperText color='gray.500'>Twitter</FormHelperText>
|
||||
<Input type='text' size='md' variant='flushed' placeholder='@tw_username' {...register('twitter_id')} />
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='flushed'
|
||||
placeholder='@tw_username'
|
||||
isInvalid={errors.twitter_id ? true : false}
|
||||
{...register('twitter_id')}
|
||||
/>
|
||||
<Text as='small' color='red.500'>
|
||||
{errors.twitter_id?.message}
|
||||
</Text>
|
||||
</FormControl>
|
||||
<FormControl id='telegram'>
|
||||
<FormHelperText color='gray.500'>Telegram</FormHelperText>
|
||||
<Input type='text' size='md' variant='flushed' placeholder='@tg_username' {...register('telegram_id')} />
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='flushed'
|
||||
placeholder='@tg_username'
|
||||
isInvalid={errors.telegram_id ? true : false}
|
||||
{...register('telegram_id')}
|
||||
/>
|
||||
<Text as='small' color='red.500'>
|
||||
{errors.telegram_id?.message}
|
||||
</Text>
|
||||
</FormControl>
|
||||
<FormControl id='vk'>
|
||||
<FormHelperText color='gray.500'>VKontakte</FormHelperText>
|
||||
<Input type='text' size='md' variant='flushed' placeholder='VKontakte id' {...register('vk_id')} />
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='flushed'
|
||||
placeholder='VKontakte id'
|
||||
isInvalid={errors.vk_id ? true : false}
|
||||
{...register('vk_id')}
|
||||
/>
|
||||
<Text as='small' color='red.500'>
|
||||
{errors.vk_id?.message}
|
||||
</Text>
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { Box, Heading, Stack, Flex, StackDivider, Text, Button } from '@chakra-ui/react';
|
||||
import { IUser } from 'interfaces';
|
||||
import { ProfilePageViewContext } from 'contexts';
|
||||
|
||||
type UserAccountInfoPropsType = {
|
||||
user: IUser;
|
||||
};
|
||||
|
||||
const UserAccountInfo: React.FC<UserAccountInfoPropsType> = ({ user }) => {
|
||||
const { setStatusPageView } = useContext(ProfilePageViewContext);
|
||||
return (
|
||||
<Box borderRadius='md' borderWidth='1px' padding='20px'>
|
||||
<Heading as='h3' size='lg'>
|
||||
@ -23,7 +25,6 @@ const UserAccountInfo: React.FC<UserAccountInfoPropsType> = ({ user }) => {
|
||||
</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Flex>
|
||||
<Box>
|
||||
<Text as='small' color='gray.500'>
|
||||
@ -34,7 +35,6 @@ const UserAccountInfo: React.FC<UserAccountInfoPropsType> = ({ user }) => {
|
||||
</Text>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
<Flex justifyContent='space-between' alignItems='center'>
|
||||
<Box>
|
||||
<Text as='small' color='gray.500'>
|
||||
@ -46,7 +46,6 @@ const UserAccountInfo: React.FC<UserAccountInfoPropsType> = ({ user }) => {
|
||||
</Box>
|
||||
<Button>Edit</Button>
|
||||
</Flex>
|
||||
|
||||
<Flex justifyContent='space-between' alignItems='center'>
|
||||
<Box>
|
||||
<Text as='small' color='gray.500'>
|
||||
@ -56,7 +55,7 @@ const UserAccountInfo: React.FC<UserAccountInfoPropsType> = ({ user }) => {
|
||||
**********
|
||||
</Text>
|
||||
</Box>
|
||||
<Button>Change</Button>
|
||||
<Button onClick={() => setStatusPageView('update-password')}>Change</Button>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { Box, Heading, Flex, Text, IconButton } from '@chakra-ui/react';
|
||||
import { ChevronLeftIcon } from '@chakra-ui/icons';
|
||||
import { ProfilePageViewContext } from 'contexts';
|
||||
import UpdatePasswordForm from './UpdatePasswordForm';
|
||||
|
||||
const UpdatePasswordContainer: React.FC = () => {
|
||||
const { setStatusPageView } = useContext(ProfilePageViewContext);
|
||||
|
||||
return (
|
||||
<Box maxW='700px'>
|
||||
<Flex alignItems='center'>
|
||||
<IconButton
|
||||
aria-label='Back'
|
||||
borderRadius='full'
|
||||
icon={<ChevronLeftIcon />}
|
||||
onClick={() => setStatusPageView(undefined)}
|
||||
mr='5'
|
||||
/>
|
||||
<Heading as='h1'>Update password</Heading>
|
||||
</Flex>
|
||||
<Box mt='3'>
|
||||
<Text>Your new password must be different from the current one.</Text>
|
||||
</Box>
|
||||
<UpdatePasswordForm />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdatePasswordContainer;
|
||||
@ -0,0 +1,108 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { Box, Stack } from '@chakra-ui/layout';
|
||||
import { FormControl, FormLabel, FormHelperText } from '@chakra-ui/form-control';
|
||||
import { Button } from '@chakra-ui/button';
|
||||
import { Input } from '@chakra-ui/input';
|
||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import UpdatePasswordSchema from './UpdatePasswordForm.validator';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
import { useToast } from '@chakra-ui/toast';
|
||||
import { useErrorHandler } from 'react-error-boundary';
|
||||
import { ProfilePageViewContext } from 'contexts';
|
||||
|
||||
type UpdatePasswordInputType = {
|
||||
old_password: string;
|
||||
new_password: string;
|
||||
confirm_password: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update password using form
|
||||
*/
|
||||
const UpdatePasswordForm: React.FC = () => {
|
||||
const { setStatusPageView } = useContext(ProfilePageViewContext);
|
||||
const { userStore } = useRootStore();
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
reset,
|
||||
formState: { errors },
|
||||
} = useForm<UpdatePasswordInputType>({
|
||||
resolver: yupResolver(UpdatePasswordSchema),
|
||||
});
|
||||
|
||||
const toast = useToast();
|
||||
const handleError = useErrorHandler();
|
||||
|
||||
const onSubmit: SubmitHandler<UpdatePasswordInputType> = async data => {
|
||||
try {
|
||||
await userStore.updateCurrentUserPassword(data.old_password, data.new_password);
|
||||
toast({ title: 'Password changed.', status: 'success' });
|
||||
reset();
|
||||
setStatusPageView(undefined);
|
||||
} catch (error: any) {
|
||||
if (error.response) {
|
||||
if (error.response.status === 401) {
|
||||
toast({ title: 'Invalid current password.', status: 'error', duration: 2000 });
|
||||
}
|
||||
} else {
|
||||
handleError(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box maxW='700px'>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Stack spacing='15px' mt='10'>
|
||||
<FormControl id='old_password' isRequired>
|
||||
<FormLabel>Old password</FormLabel>
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='filled'
|
||||
placeholder='*******'
|
||||
isInvalid={errors.old_password ? true : false}
|
||||
{...register('old_password')}
|
||||
/>
|
||||
<FormHelperText color='gray.500'>Type your current password.</FormHelperText>
|
||||
</FormControl>
|
||||
<FormControl id='new_password' isRequired>
|
||||
<FormLabel>New password</FormLabel>
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='filled'
|
||||
placeholder='*******'
|
||||
isInvalid={errors.new_password ? true : false}
|
||||
{...register('new_password')}
|
||||
/>
|
||||
<FormHelperText color={errors.new_password ? 'red' : 'gray.500'}>
|
||||
Must be at least 6 characters.
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
<FormControl id='confirm_password' isRequired>
|
||||
<FormLabel>Confirm new password</FormLabel>
|
||||
<Input
|
||||
type='text'
|
||||
size='md'
|
||||
variant='filled'
|
||||
placeholder='*******'
|
||||
isInvalid={errors.confirm_password ? true : false}
|
||||
{...register('confirm_password')}
|
||||
/>
|
||||
<FormHelperText color={errors.confirm_password ? 'red' : 'gray.500'}>
|
||||
Both passwords must match.
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
<Button colorScheme='blue' mt='4' type='submit' size='md' variant='outline' loadingText='Saving...'>
|
||||
Change
|
||||
</Button>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpdatePasswordForm;
|
||||
@ -0,0 +1,14 @@
|
||||
import yup from 'validators';
|
||||
|
||||
const UpdatePasswordSchema = yup.object().shape({
|
||||
old_password: yup.string().required('Old password is required'),
|
||||
new_password: yup.string().required('New password is required').min(6, 'Password bust be at least 6 characters.'),
|
||||
confirm_password: yup
|
||||
.string()
|
||||
.required('Confirm password is required')
|
||||
.test('passwords-match', 'Make sure your passwords match.', function (value) {
|
||||
return this.parent.new_password === value;
|
||||
}),
|
||||
});
|
||||
|
||||
export default UpdatePasswordSchema;
|
||||
@ -0,0 +1,3 @@
|
||||
import UpdatePasswordForm from './UpdatePasswordForm';
|
||||
|
||||
export default UpdatePasswordForm;
|
||||
@ -0,0 +1,3 @@
|
||||
import UpdatePasswordContainer from './UpdatePasswordContainer';
|
||||
|
||||
export default UpdatePasswordContainer;
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Heading,
|
||||
@ -12,21 +12,23 @@ import {
|
||||
TabPanels,
|
||||
TabPanel,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { IPageProps } from 'interfaces';
|
||||
import { ProfilePageStatusType } from 'types';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { observer } from 'mobx-react';
|
||||
import { ProfilePageViewContext } from 'contexts';
|
||||
import UserBadge from 'components/UserBadge';
|
||||
|
||||
import LoadingPage from './components/LoadingPage';
|
||||
import UserAccountInfo from './components/UserAccountInfo';
|
||||
import UpdateUserContactsForm from './components/UpdateUserContactsForm';
|
||||
import UpdatePasswordContainer from './containers/UpdatePasswordContainer';
|
||||
|
||||
/**
|
||||
* Profile page
|
||||
*/
|
||||
const ProfilePage: React.FC<IPageProps> = ({ title }) => {
|
||||
const ProfilePage: React.FC<IPageProps> = () => {
|
||||
const [statusPageView, setStatusPageView] = useState<ProfilePageStatusType>(undefined);
|
||||
const { colorMode } = useColorMode();
|
||||
const { userStore, authStore } = useRootStore();
|
||||
const history = useHistory();
|
||||
@ -42,6 +44,8 @@ const ProfilePage: React.FC<IPageProps> = ({ title }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<ProfilePageViewContext.Provider value={{ statusPageView, setStatusPageView }}>
|
||||
{statusPageView === undefined && (
|
||||
<Box maxW='900px'>
|
||||
<Heading as='h1'>My account</Heading>
|
||||
<Flex
|
||||
@ -97,7 +101,6 @@ const ProfilePage: React.FC<IPageProps> = ({ title }) => {
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Box mt='10'>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
@ -115,6 +118,9 @@ const ProfilePage: React.FC<IPageProps> = ({ title }) => {
|
||||
</Tabs>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{statusPageView === 'update-password' && <UpdatePasswordContainer />}
|
||||
</ProfilePageViewContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
import RootStore from 'stores/RootStore';
|
||||
|
||||
export default class ApiService {
|
||||
@ -26,9 +25,9 @@ export default class ApiService {
|
||||
* Unauthorized Error 401
|
||||
*/
|
||||
if (error.response.status === 401) {
|
||||
this.root.userStore.me = null;
|
||||
this.root.authStore.setIsLoggedIn(false);
|
||||
Cookies.remove('logged_in');
|
||||
// this.root.userStore.me = null;
|
||||
// this.root.authStore.setIsLoggedIn(false);
|
||||
// Cookies.remove('logged_in');
|
||||
}
|
||||
}
|
||||
return Promise.reject(error);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { IUpdatedContactsResult, IUserContacts, IUserResult } from 'interfaces';
|
||||
import { IDataResult, IUpdatedContactsResult, IUserContacts, IUserResult } from 'interfaces';
|
||||
import * as helpers from 'helpers';
|
||||
|
||||
export default class UserService {
|
||||
@ -29,4 +29,19 @@ export default class UserService {
|
||||
const result = await this.api.put('v1/me/contacts', helpers.removeEmptyValues(data));
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update password of authorized user
|
||||
*
|
||||
* @param oldPassword string
|
||||
* @param newPassword string
|
||||
* @returns Result data
|
||||
*/
|
||||
public async updatePassword(oldPassword: string, newPassword: string): Promise<IDataResult> {
|
||||
const result = await this.api.patch('v1/me/password', {
|
||||
oldPassword,
|
||||
newPassword,
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { makeAutoObservable, runInAction } from 'mobx';
|
||||
import { IUserResult, IUser, IUserContacts, IUpdatedContactsResult } from 'interfaces';
|
||||
import { IUserResult, IUser, IUserContacts, IUpdatedContactsResult, IDataResult } from 'interfaces';
|
||||
|
||||
/**
|
||||
* Services
|
||||
@ -57,6 +57,15 @@ export default class UserStore {
|
||||
}
|
||||
}
|
||||
|
||||
public async updateCurrentUserPassword(oldPassword: string, newPassword: string): Promise<IDataResult> {
|
||||
try {
|
||||
const result = await this.userService.updatePassword(oldPassword, newPassword);
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
runInAction(() => {
|
||||
this.me = null;
|
||||
|
||||
14
src/types/index.d.ts
vendored
Normal file
14
src/types/index.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
import { IconType } from 'react-icons/lib';
|
||||
|
||||
export type LinkType = {
|
||||
location: string;
|
||||
title: string;
|
||||
public: boolean;
|
||||
icon: IconType;
|
||||
};
|
||||
|
||||
export type ProfilePageStatusType = 'update-password' | 'update-email' | undefined;
|
||||
export type ProfilePageViewStatusContextType = {
|
||||
statusPageView: ProfilePageStatusType;
|
||||
setStatusPageView: React.Dispatch<React.SetStateAction<ProfilePageStatusType>>;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user