Skip to content

Commit

Permalink
create otp login
Browse files Browse the repository at this point in the history
  • Loading branch information
Janderson Souza Matias authored and Janderson Souza Matias committed Jan 15, 2024
1 parent a819a6c commit 21a0de3
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 25 deletions.
14 changes: 10 additions & 4 deletions src/contexts/UserContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import UserService from '@/services/user';
import { useTranslation } from 'react-i18next';

export type UserContextProps = {
login: (prop: { email: string; password: string }) => Promise<void>;
login: (prop: { email: string; code: string }) => Promise<void>;
sendOTPCode: (email: string) => Promise<void>;
handleUpdateUser: (user: Partial<IUser>) => Promise<void>;
updateLocalUser: (user: IUser) => void;
logout: () => void;
Expand Down Expand Up @@ -49,7 +50,7 @@ const UserContextProvider = ({ children }: Props) => {
}
}, [user]);

const handleLogin = async (props: { email: string; password: string }) => {
const handleLogin = async (props: { email: string; code: string }) => {
const response = await AuthService.login(props);

setUser(response.data);
Expand Down Expand Up @@ -83,13 +84,18 @@ const UserContextProvider = ({ children }: Props) => {
setUser(user);
};

const sendOTPCode = async (email: string) => {
await AuthService.sendOTPCode(email);
};

return (
<UserContext.Provider
value={{
handleUpdateUser,
login: handleLogin,
logout,
sendOTPCode,
updateLocalUser,
handleUpdateUser,
login: handleLogin,
user,
userRegionsPath,
}}
Expand Down
82 changes: 63 additions & 19 deletions src/pages/Login/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,56 @@
import { CoachLogo } from '@/assets/images/logos';
import Loader from '@/components/Base/Loader';
import { UserContext } from '@/contexts/UserContext';
import { Button, Center, Image, Input, VStack } from '@chakra-ui/react';
import React, { useContext } from 'react';
import {
Alert,
AlertIcon,
AlertTitle,
Button,
Center,
HStack,
Image,
Input,
PinInput,
PinInputField,
Text,
VStack,
} from '@chakra-ui/react';
import React, { useContext, useState } from 'react';
import { useForm, SubmitHandler, Controller } from 'react-hook-form';
import { CloseButton } from 'react-toastify/dist/components';

const defaultValues = {
email: '',
password: '',
};

const Login: React.FC = () => {
const { login } = useContext(UserContext);
const { sendOTPCode, login } = useContext(UserContext);
const {
control,
handleSubmit,
formState: { isSubmitting },
} = useForm({ defaultValues });
const [error, setError] = useState('');
const [showOTP, setShowOTP] = useState(false);
const [code, setCode] = useState('');

const handleLogin: SubmitHandler<typeof defaultValues> = async (values) => {
const handleLogin: SubmitHandler<typeof defaultValues> = async ({ email }) => {
try {
await login(values);
} catch {}
setError('');
if (showOTP) {
await login({ email, code });
} else {
await sendOTPCode(email);
setShowOTP(true);
}
} catch (err: any) {
if (showOTP) {
setError('Invalid code');
} else {
setError('Invalid email');
}
setCode('');
}
return;
};

Expand All @@ -46,21 +75,36 @@ const Login: React.FC = () => {
rules={{ required: true }}
name="email"
render={({ field, fieldState: { error } }) => (
<Input placeholder="E-mail" {...field} isInvalid={!!error} h={'48px'} />
)}
/>

<Controller
control={control}
rules={{ required: true }}
name="password"
render={({ field, fieldState: { error } }) => (
<Input placeholder="Password" type="password" {...field} isInvalid={!!error} h={'48px'} />
<Input placeholder="E-mail" {...field} isInvalid={!!error} h={'48px'} disabled={showOTP} />
)}
/>
{error && (
<Alert status="error">
<AlertIcon />
<AlertTitle>{error}</AlertTitle>
</Alert>
)}
{showOTP && (
<VStack my={10}>
<Text>Enter the code we sent to your email</Text>
<HStack>
<PinInput otp onComplete={setCode}>
<PinInputField />
<PinInputField />
<PinInputField />
<PinInputField />
</PinInput>
</HStack>
</VStack>
)}
</VStack>
<Button mt={'32px !important'} w={'100%'} onClick={handleSubmit(handleLogin)}>
SignIn
<Button
mt={'32px !important'}
w={'100%'}
onClick={handleSubmit(handleLogin)}
isDisabled={showOTP && code.length < 4}
>
{showOTP ? 'Verify code' : 'Send OTP code'}
</Button>
</>
)}
Expand Down
5 changes: 3 additions & 2 deletions src/services/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IUser } from '../../types';

type UserLoginParams = {
email: IUser['email'];
password: string;
code: string;
};

export type UserSignUpParams = {
Expand All @@ -16,7 +16,8 @@ export type UserSignUpParams = {
};

export const AuthService = {
login: (body: UserLoginParams): Promise<any> => _axios.post('auth', body),
sendOTPCode: (email: string): Promise<any> => _axios.post('auth', { email }),
login: (body: UserLoginParams): Promise<any> => _axios.post('auth/verify', body),
sighup: (body: IUser): Promise<IUser> => _axios.post('users/admin/sign-up', body),
getGuestToken: () => _axios.get<string>('auth/superset'),
};
Expand Down

0 comments on commit 21a0de3

Please sign in to comment.