-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* AC/UI password reset screen * Email forgotten password reset link. * AC/added reset password functionality Co-authored-by: Vadim Zabolotniy <[email protected]>
- Loading branch information
1 parent
2ddf02d
commit 97d32c2
Showing
11 changed files
with
493 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
frontend/src/app/main/forgot-password/ForgotPasswordConfig.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import authRoles from '../../auth/authRoles'; | ||
import { PATHS } from '../../constants/paths'; | ||
|
||
import ForgotPasswordPage from './ForgotPasswordPage'; | ||
|
||
const ForgotPasswordConfig = { | ||
settings: { | ||
layout: { | ||
config: { | ||
navbar: { display: false }, | ||
toolbar: { display: false }, | ||
footer: { display: false }, | ||
leftSidePanel: { display: false }, | ||
rightSidePanel: { display: false }, | ||
}, | ||
}, | ||
}, | ||
auth: authRoles.onlyGuest, | ||
routes: [ | ||
{ | ||
path: PATHS.FORGOT_PASSWORD, | ||
element: <ForgotPasswordPage />, | ||
}, | ||
], | ||
}; | ||
|
||
export default ForgotPasswordConfig; |
193 changes: 193 additions & 0 deletions
193
frontend/src/app/main/forgot-password/ForgotPasswordPage.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
import { yupResolver } from '@hookform/resolvers/yup'; | ||
import Avatar from '@mui/material/Avatar'; | ||
import AvatarGroup from '@mui/material/AvatarGroup'; | ||
import Box from '@mui/material/Box'; | ||
import Button from '@mui/material/Button'; | ||
import Paper from '@mui/material/Paper'; | ||
import Snackbar from '@mui/material/Snackbar'; | ||
import TextField from '@mui/material/TextField'; | ||
import Typography from '@mui/material/Typography'; | ||
import { useState } from 'react'; | ||
import { Controller, useForm } from 'react-hook-form'; | ||
import { Link } from 'react-router-dom'; | ||
import * as yup from 'yup'; | ||
|
||
import _ from '@lodash'; | ||
|
||
import jwtService from '../../auth/services/jwtService'; | ||
import { getErrorMessage } from '../sign-in/utils'; | ||
|
||
/** | ||
* Form Validation Schema | ||
*/ | ||
const schema = yup.object().shape({ | ||
email: yup.string().email('You must enter a valid email').required('You must enter a email'), | ||
}); | ||
|
||
const defaultValues = { | ||
email: '', | ||
}; | ||
|
||
function ForgotPasswordPage() { | ||
const [open, setOpen] = useState(false); | ||
const { control, formState, handleSubmit, reset, setError } = useForm({ | ||
mode: 'onChange', | ||
defaultValues, | ||
resolver: yupResolver(schema), | ||
}); | ||
|
||
const { isValid, dirtyFields, errors } = formState; | ||
|
||
const onSubmit = async ({ email }) => { | ||
try { | ||
await jwtService.forgotPassword(email); | ||
setOpen(true); | ||
} catch (error) { | ||
setError('email', { | ||
type: 'manual', | ||
message: getErrorMessage(error), | ||
}); | ||
} | ||
reset(defaultValues); | ||
}; | ||
|
||
return ( | ||
<div className='flex flex-col sm:flex-row items-center md:items-start sm:justify-center md:justify-start flex-1 min-w-0'> | ||
<Paper className='h-full sm:h-auto md:flex md:items-center md:justify-end w-full sm:w-auto md:h-full md:w-1/2 py-8 px-16 sm:p-48 md:p-64 sm:rounded-2xl md:rounded-none sm:shadow md:shadow-none ltr:border-r-1 rtl:border-l-1'> | ||
<div className='w-full max-w-320 sm:w-320 mx-auto sm:mx-0'> | ||
<img className='w-[100px]' src='assets/images/logo.png' alt='logo' /> | ||
|
||
<Typography className='mt-32 text-4xl font-extrabold tracking-tight leading-tight'> | ||
Forgot password? | ||
</Typography> | ||
<div className='flex items-baseline mt-2 font-medium'> | ||
<Typography>Fill the form to reset your password</Typography> | ||
</div> | ||
|
||
<form | ||
name='registerForm' | ||
noValidate | ||
className='flex flex-col justify-center w-full mt-32' | ||
onSubmit={handleSubmit(onSubmit)} | ||
> | ||
<Controller | ||
name='email' | ||
control={control} | ||
render={({ field }) => ( | ||
<TextField | ||
{...field} | ||
className='mb-24' | ||
label='Email' | ||
type='email' | ||
error={!!errors.email} | ||
helperText={errors?.email?.message} | ||
variant='outlined' | ||
required | ||
fullWidth | ||
/> | ||
)} | ||
/> | ||
|
||
<Button | ||
variant='contained' | ||
color='secondary' | ||
className=' w-full mt-4' | ||
aria-label='Register' | ||
disabled={_.isEmpty(dirtyFields) || !isValid} | ||
type='submit' | ||
size='large' | ||
> | ||
Send reset link | ||
</Button> | ||
|
||
<Typography className='mt-32 text-md font-medium' color='text.secondary'> | ||
<span>Return to</span> | ||
<Link className='ml-4' to='/sign-in'> | ||
sign in | ||
</Link> | ||
</Typography> | ||
</form> | ||
</div> | ||
</Paper> | ||
<Box | ||
className='relative hidden md:flex flex-auto items-center justify-center h-full p-64 lg:px-112 overflow-hidden' | ||
sx={{ backgroundColor: 'primary.main' }} | ||
> | ||
<svg | ||
className='absolute inset-0 pointer-events-none' | ||
viewBox='0 0 960 540' | ||
width='100%' | ||
height='100%' | ||
preserveAspectRatio='xMidYMax slice' | ||
xmlns='http://www.w3.org/2000/svg' | ||
> | ||
<Box | ||
component='g' | ||
sx={{ color: 'primary.light' }} | ||
className='opacity-20' | ||
fill='none' | ||
stroke='currentColor' | ||
strokeWidth='100' | ||
> | ||
<circle r='234' cx='196' cy='23' /> | ||
<circle r='234' cx='790' cy='491' /> | ||
</Box> | ||
</svg> | ||
<Box | ||
component='svg' | ||
className='absolute -top-64 -right-64 opacity-20' | ||
sx={{ color: 'primary.light' }} | ||
viewBox='0 0 220 192' | ||
width='220px' | ||
height='192px' | ||
fill='none' | ||
> | ||
<defs> | ||
<pattern | ||
id='837c3e70-6c3a-44e6-8854-cc48c737b659' | ||
x='0' | ||
y='0' | ||
width='20' | ||
height='20' | ||
patternUnits='userSpaceOnUse' | ||
> | ||
<rect x='0' y='0' width='4' height='4' fill='currentColor' /> | ||
</pattern> | ||
</defs> | ||
<rect width='220' height='192' fill='url(#837c3e70-6c3a-44e6-8854-cc48c737b659)' /> | ||
</Box> | ||
|
||
<div className='z-10 relative w-full max-w-2xl'> | ||
<div className='text-7xl font-bold leading-none text-gray-100'> | ||
<img src='assets/images/logo-white.png' width='130px' /> | ||
<div>Service Hub</div> | ||
</div> | ||
<div className='mt-24 text-lg tracking-tight leading-6 text-gray-400'> | ||
Create on-demand services with Helm and Kubernetes. | ||
</div> | ||
<div className='flex items-center mt-32'> | ||
<AvatarGroup sx={{ '& .MuiAvatar-root': { borderColor: 'primary.main' } }}> | ||
<Avatar src='assets/images/avatars/male-16.jpg' /> | ||
<Avatar src='assets/images/avatars/female-11.jpg' /> | ||
<Avatar src='assets/images/avatars/male-09.jpg' /> | ||
<Avatar src='assets/images/avatars/female-18.jpg' /> | ||
</AvatarGroup> | ||
|
||
<div className='ml-16 font-medium tracking-tight text-gray-400'> | ||
More than 1k Platform engineers are using Service Hub, now it's your turn. | ||
</div> | ||
</div> | ||
</div> | ||
</Box> | ||
<Snackbar | ||
anchorOrigin={{ vertical: 'top', horizontal: 'center' }} | ||
open={open} | ||
autoHideDuration={6000} | ||
onClose={() => setOpen(false)} | ||
message='A password reset link has been sent to your email' | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
export default ForgotPasswordPage; |
27 changes: 27 additions & 0 deletions
27
frontend/src/app/main/reset-password/ResetPasswordConfig.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import authRoles from '../../auth/authRoles'; | ||
import { PATHS } from '../../constants/paths'; | ||
|
||
import ResetPasswordPage from './ResetPasswordPage'; | ||
|
||
const ResetPasswordConfig = { | ||
settings: { | ||
layout: { | ||
config: { | ||
navbar: { display: false }, | ||
toolbar: { display: false }, | ||
footer: { display: false }, | ||
leftSidePanel: { display: false }, | ||
rightSidePanel: { display: false }, | ||
}, | ||
}, | ||
}, | ||
auth: authRoles.onlyGuest, | ||
routes: [ | ||
{ | ||
path: PATHS.RESET_PASSWORD, | ||
element: <ResetPasswordPage />, | ||
}, | ||
], | ||
}; | ||
|
||
export default ResetPasswordConfig; |
Oops, something went wrong.