mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: exipred seconds interval
This commit is contained in:
parent
cf81c3f5da
commit
da4335ce7f
@ -52,6 +52,12 @@ export interface IUpdatedContactsResult extends IDataResult {
|
||||
data: IUserContacts;
|
||||
}
|
||||
|
||||
export interface IUpdatedEmailResult extends IDataResult {
|
||||
data: {
|
||||
expired_seconds: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IUserResult extends IDataResult {
|
||||
data: Omit<IUser, 'fullname'>;
|
||||
}
|
||||
|
||||
@ -1,9 +1,24 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { PinInput, PinInputField } from '@chakra-ui/react';
|
||||
import { Button } from '@chakra-ui/button';
|
||||
import { Box, Flex, Heading, HStack, Text } from '@chakra-ui/layout';
|
||||
import { ConfirmEmailContainerDataType } from 'types';
|
||||
|
||||
const ConfirmEmailContainer: React.FC<{ data: ConfirmEmailContainerDataType }> = ({ data }) => {
|
||||
const [expired, setExpired] = useState(data.expired_seconds);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = window.setInterval(() => {
|
||||
if (expired <= 0) {
|
||||
window.clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
setExpired(v => (v = v - 1));
|
||||
}, 1000);
|
||||
|
||||
return () => window.clearInterval(interval);
|
||||
});
|
||||
|
||||
const ConfirmEmailContainer: React.FC<{ newEmail: string }> = ({ newEmail }) => {
|
||||
return (
|
||||
<Box
|
||||
maxW='500px'
|
||||
@ -17,7 +32,7 @@ const ConfirmEmailContainer: React.FC<{ newEmail: string }> = ({ newEmail }) =>
|
||||
<Heading as='h1'>Confirmation</Heading>
|
||||
<Box mt='3'>
|
||||
<Text>
|
||||
Enter the 4-digit code we send to <Text as='b'>{newEmail}</Text>
|
||||
Enter the 4-digit code we send to <Text as='b'>{data.newEmail}</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
<Flex alignItems='center' mt='10'>
|
||||
@ -44,12 +59,15 @@ const ConfirmEmailContainer: React.FC<{ newEmail: string }> = ({ newEmail }) =>
|
||||
Verify
|
||||
</Button>
|
||||
<Box mt='1.5'>
|
||||
{expired > 0 ? (
|
||||
<Text as='small' color='red'>
|
||||
Expires in 1:59
|
||||
Expires in {expired} seconds.
|
||||
</Text>
|
||||
{/* <Button variant='link' size='sm' colorScheme='black' mt='3' textDecoration='underline'>
|
||||
) : (
|
||||
<Button variant='link' size='sm' colorScheme='black' mt='3' textDecoration='underline'>
|
||||
Resend code
|
||||
</Button> */}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
@ -2,10 +2,12 @@ import { Button } from '@chakra-ui/button';
|
||||
import { FormControl, FormHelperText, FormLabel } from '@chakra-ui/form-control';
|
||||
import { Input } from '@chakra-ui/input';
|
||||
import { Box, Stack } from '@chakra-ui/layout';
|
||||
import { useToast } from '@chakra-ui/toast';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { ProfilePageViewContext } from 'contexts';
|
||||
import { useRootStore } from 'hooks/useRootStore';
|
||||
import React, { useContext } from 'react';
|
||||
import { useErrorHandler } from 'react-error-boundary';
|
||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
import UpdateEmailSchema from './UpdateEmailForm.validator';
|
||||
|
||||
@ -18,9 +20,7 @@ type UpdateEmailInputType = {
|
||||
*/
|
||||
const UpdateEmailForm: React.FC = () => {
|
||||
const { setStatusPageView } = useContext(ProfilePageViewContext);
|
||||
const {
|
||||
userStore: { me },
|
||||
} = useRootStore();
|
||||
const { userStore } = useRootStore();
|
||||
const {
|
||||
handleSubmit,
|
||||
register,
|
||||
@ -28,10 +28,25 @@ const UpdateEmailForm: React.FC = () => {
|
||||
} = useForm<UpdateEmailInputType>({
|
||||
resolver: yupResolver(UpdateEmailSchema),
|
||||
});
|
||||
const toast = useToast();
|
||||
const handleError = useErrorHandler();
|
||||
|
||||
const onSubmit: SubmitHandler<UpdateEmailInputType> = async data => {
|
||||
console.log(data);
|
||||
setStatusPageView({ status: 'confirm-email', data: { confirmEmailData: { newEmail: data.email } } });
|
||||
const onSubmit: SubmitHandler<UpdateEmailInputType> = async ({ email }) => {
|
||||
userStore
|
||||
.updateUserEmail(email)
|
||||
.then(({ data }) => {
|
||||
setStatusPageView({
|
||||
status: 'confirm-email',
|
||||
data: { confirmEmailData: { newEmail: email, expired_seconds: data.expired_seconds } },
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response) {
|
||||
toast({ title: `${error.message}`, status: 'error' });
|
||||
} else {
|
||||
handleError(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@ -40,7 +55,7 @@ const UpdateEmailForm: React.FC = () => {
|
||||
<Stack spacing='15px' mt='10'>
|
||||
<FormControl id='email'>
|
||||
<FormLabel>Current email</FormLabel>
|
||||
<Input type='email' size='md' variant='filled' disabled value={me?.email} />
|
||||
<Input type='email' size='md' variant='filled' disabled value={userStore.me?.email} />
|
||||
</FormControl>
|
||||
<FormControl id='new_email' isRequired>
|
||||
<FormLabel>New email</FormLabel>
|
||||
|
||||
@ -124,7 +124,7 @@ const ProfilePage: React.FC<IPageProps> = () => {
|
||||
{statusPageView.status === 'update-password' && <UpdatePasswordContainer />}
|
||||
{statusPageView.status === 'update-email' && <UpdateEmailContainer />}
|
||||
{statusPageView.status === 'confirm-email' && statusPageView.data?.confirmEmailData && (
|
||||
<ConfirmEmailContainer newEmail={statusPageView.data.confirmEmailData.newEmail} />
|
||||
<ConfirmEmailContainer data={statusPageView.data.confirmEmailData} />
|
||||
)}
|
||||
</ProfilePageViewContext.Provider>
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { IDataResult, IUpdatedContactsResult, IUserContacts, IUserResult } from 'interfaces';
|
||||
import { IDataResult, IUpdatedContactsResult, IUpdatedEmailResult, IUserContacts, IUserResult } from 'interfaces';
|
||||
import * as helpers from 'helpers';
|
||||
|
||||
export default class UserService {
|
||||
@ -44,4 +44,17 @@ export default class UserService {
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
|
||||
public async updateEmail(email: string): Promise<IUpdatedEmailResult> {
|
||||
const result = await this.api.patch('v1/me/email', { email });
|
||||
return result.data;
|
||||
}
|
||||
|
||||
public async updateEmailConfirm(email: string, confirmationCode: number): Promise<IDataResult> {
|
||||
const result = await this.api.post('v1/me/email/change/confirm', {
|
||||
email,
|
||||
confirmationCode,
|
||||
});
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { makeAutoObservable, runInAction } from 'mobx';
|
||||
import { IUserResult, IUser, IUserContacts, IUpdatedContactsResult, IDataResult } from 'interfaces';
|
||||
import {
|
||||
IUserResult,
|
||||
IUser,
|
||||
IUserContacts,
|
||||
IUpdatedContactsResult,
|
||||
IDataResult,
|
||||
IUpdatedEmailResult,
|
||||
} from 'interfaces';
|
||||
|
||||
/**
|
||||
* Services
|
||||
@ -77,6 +84,15 @@ export default class UserStore {
|
||||
}
|
||||
}
|
||||
|
||||
public async updateUserEmail(email: string): Promise<IUpdatedEmailResult> {
|
||||
try {
|
||||
const result = await this.userService.updateEmail(email);
|
||||
return result;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
runInAction(() => {
|
||||
this.me = null;
|
||||
|
||||
9
src/types/index.d.ts
vendored
9
src/types/index.d.ts
vendored
@ -7,15 +7,18 @@ export type LinkType = {
|
||||
icon: IconType;
|
||||
};
|
||||
|
||||
export type ConfirmEmailContainerDataType = {
|
||||
newEmail: string;
|
||||
expired_seconds: number;
|
||||
};
|
||||
|
||||
export type ProfilePageStatusType = {
|
||||
status: 'update-password' | 'update-email' | 'confirm-email' | 'default';
|
||||
data?: {
|
||||
/**
|
||||
* The field that is set when trying to change the mail address through form
|
||||
*/
|
||||
confirmEmailData?: {
|
||||
newEmail: string;
|
||||
};
|
||||
confirmEmailData?: ConfirmEmailContainerDataType;
|
||||
};
|
||||
};
|
||||
export type ProfilePageViewStatusContextType = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user