Skip to content

Commit

Permalink
Merge pull request #50 from FacundoInza/feature/login-connection
Browse files Browse the repository at this point in the history
feat: add forgot password conection with error handler
  • Loading branch information
Jtendersen authored Sep 17, 2023
2 parents bce2af2 + 356bfa5 commit 6c9a2b1
Show file tree
Hide file tree
Showing 7 changed files with 549 additions and 10 deletions.
12 changes: 12 additions & 0 deletions app/(User)/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC } from 'react';
import { ForgotPassword } from '../../../components/ui/forgotPassword/ForgotPassword';

const InitWorkDay: FC = () => {
return (
<div>
<ForgotPassword />
</div>
);
};

export default InitWorkDay;
86 changes: 86 additions & 0 deletions components/ui/forgotPassword/ForgotPassword.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use client';

import Image from 'next/image';
import React, { FC, useState } from 'react';
import logo from '../../../assets/deliverit-full.png';
import MainButton from '../../commons/buttons/MainButton';
import { RequestPasswordReset } from './RequestPasswordReset';
import { VerifyResetToken } from './VerfiyResetToken';
import { ResetPassword } from './ResetPassword';
import { useRouter } from 'next/navigation';

export const ForgotPassword: FC = () => {
//Step 1: Request password reset
//Step 2: Verify reset token
//Step 3: Reset password
const [step, setStep] = useState(1);
const [email, setEmail] = useState('');
const [token, setToken] = useState('');

const router = useRouter();

const goToNextStep = () => {
setStep((prevStep) => prevStep + 1);
};

const goToPreviousStep = () => {
if (step === 1) {
router.push('/');
}
setStep((prevStep) => prevStep - 1);
};

const renderStepContent = () => {
switch (step) {
case 1:
return (
<RequestPasswordReset
onSuccess={setEmail}
onNext={goToNextStep}
/>
);
case 2:
return (
<VerifyResetToken
email={email}
onSuccess={setToken}
onNext={goToNextStep}
/>
);
case 3:
return <ResetPassword email={email} token={token} />;
default:
return (
<RequestPasswordReset
onSuccess={setEmail}
onNext={goToNextStep}
/>
);
}
};

return (
<>
<div className='flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8'>
<div className='sm:mx-auto sm:w-full sm:max-w-sm'>
<Image
className='mx-auto h-30 w-auto'
width={900}
height={400}
src={logo}
alt='DeliverIT'
objectFit='cover'
/>
</div>
{renderStepContent()}
<div className='mt-4'>
<MainButton
text='Back'
btnBlue
onClick={goToPreviousStep}
/>
</div>
</div>
</>
);
};
122 changes: 122 additions & 0 deletions components/ui/forgotPassword/RequestPasswordReset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React, { FC, useState } from 'react';
import MainButton from '../../commons/buttons/MainButton';
import { RiUserLine } from 'react-icons/ri';
import { useForm } from 'react-hook-form';
import { api } from 'api/axiosInstance';
import { AxiosError } from 'axios';
import Notification from '../modal/Notification';

interface RequestPasswordResetProps {
onSuccess: (email: string) => void;
onNext: () => void;
}

interface emailInput {
email: string;
}

interface ErrorResponse {
message: string;
}

export const RequestPasswordReset: FC<RequestPasswordResetProps> = ({
onSuccess,
onNext,
}) => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<emailInput>({ mode: 'onBlur' });

const [showModal, setShowModal] = useState(false);
const [modalMessage, setModalMessage] = useState('');
const [isModalSuccess, setIsModalSuccess] = useState(false);

const onSubmit = async (email: emailInput) => {
try {
const response = await api.post(
'/api/user/request-password-reset',
email
);
setModalMessage(response.data.message);
setIsModalSuccess(true);
onSuccess(email.email);
onNext();
} catch (error) {
const axiosError = error as AxiosError<ErrorResponse>;
if (axiosError && axiosError.response) {
setModalMessage(axiosError.response.data.message);
} else {
setModalMessage('Something went wrong on login');
}
setIsModalSuccess(false);
setShowModal(true);
}
};

const handleCloseModal = () => {
setShowModal(false);
};

return (
<>
<div className='mt-8 sm:mx-auto sm:w-full sm:max-w-sm text-center text-white text-xl'>
Enter your email below to reset your password:
</div>
<div className='mt-10 sm:mx-auto sm:w-full sm:max-w-sm'>
<form
className='space-y-6'
action='#'
method='POST'
onSubmit={handleSubmit(onSubmit)}
>
<div>
<div className='relative mt-2'>
<input
id='email'
type='email'
placeholder='[email protected]'
autoComplete='email'
{...register('email', {
required: 'Email is required',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message:
'Please enter a valid email address',
},
})}
className='block w-full rounded-lg border-1 px-12 py-3.5 text-white shadow-sm ring-1 ring-inset ring-white placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-500 text-sm sm:text-sm text-center font-bold sm:leading-6 bg-transparent'
/>
<span className='absolute left-3 top-1/2 transform -translate-y-6 text-gray-400'>
<RiUserLine size={25} />
</span>
<div style={{ height: '20px' }}>
{errors.email && (
<p className='text-red-400 text-right pe-2'>
{errors.email.message}
</p>
)}
</div>
</div>
</div>
<div className='space-y-6'>
<div className='mt-20'>
<MainButton text='Submit' btnGreen />
</div>
</div>
</form>
</div>

{showModal && (
<Notification
isSuccess={isModalSuccess}
message={modalMessage}
onClose={handleCloseModal}
buttonText={'Retry'}
redirectLink={'/forgot-password'}
/>
)}
</>
);
};
Loading

0 comments on commit 6c9a2b1

Please sign in to comment.