-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: authentication service and UI improvements
- Loading branch information
Showing
10 changed files
with
287 additions
and
56 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { FC, useCallback } from 'react'; | ||
|
||
import { Form as FormRFF, Field as FieldRFF } from 'react-final-form'; | ||
|
||
import { useRouter } from 'next/navigation'; | ||
|
||
import { FORM_ERROR } from 'final-form'; | ||
|
||
import { AuthWrapper } from 'containers/wrapper/component'; | ||
|
||
import LinkButton, { Button } from 'components/button/component'; | ||
import Input from 'components/forms/input/component'; | ||
|
||
import authenticationService from 'services/authentication'; | ||
|
||
const ChangePassword: FC<{ token: string | undefined }> = ({ token }) => { | ||
const router = useRouter(); | ||
|
||
const handleFormSubmit = useCallback( | ||
async ({ | ||
password, | ||
passwordConfirmation, | ||
}: { | ||
password: string; | ||
passwordConfirmation: string; | ||
}) => { | ||
try { | ||
const res = await authenticationService.changePassword( | ||
token, | ||
password, | ||
passwordConfirmation | ||
); | ||
|
||
if (res?.status === 200) { | ||
router.push('/auth/signin'); | ||
} else { | ||
throw new Error('Failed to change password'); | ||
} | ||
} catch (err) { | ||
return { | ||
[FORM_ERROR]: err instanceof Error ? err.message : 'An unexpected error occurred', | ||
}; | ||
} | ||
}, | ||
[router, token] | ||
); | ||
|
||
return ( | ||
<AuthWrapper> | ||
<FormRFF | ||
onSubmit={handleFormSubmit} | ||
initialValues={{ password: '', passwordConfirmation: '' }} | ||
> | ||
{({ submitError, handleSubmit }) => ( | ||
<form className="space-y-5" onSubmit={handleSubmit} autoComplete="off"> | ||
<h2 className="text-3xl text-center font-normal">Change password</h2> | ||
<div> | ||
<label>New password</label> | ||
<FieldRFF name="password" type="password"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
</div> | ||
<div> | ||
<label>Confirm password</label> | ||
<FieldRFF name="passwordConfirmation" type="password"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
</div> | ||
{submitError && <div className="text-red-0">{submitError}</div>} | ||
<div className="flex justify-between gap-3"> | ||
<LinkButton theme="outline" className="flex-1" href="/auth/signin"> | ||
Cancel | ||
</LinkButton> | ||
<Button theme="green" size="base" className="flex-1" type="submit"> | ||
<span>Reset password</span> | ||
</Button> | ||
</div> | ||
</form> | ||
)} | ||
</FormRFF> | ||
</AuthWrapper> | ||
); | ||
}; | ||
|
||
export default ChangePassword; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { useParams } from 'next/navigation'; | ||
|
||
import ChangePassword from 'containers/auth/change-password'; | ||
|
||
const ChangePasswordPage = () => { | ||
const params = useParams<{ token: string } | null>(); | ||
|
||
return <ChangePassword token={params?.token} />; | ||
}; | ||
|
||
export default ChangePasswordPage; |
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,79 @@ | ||
import { useCallback } from 'react'; | ||
|
||
import { Form as FormRFF, Field as FieldRFF, useFormState } from 'react-final-form'; | ||
|
||
import { FORM_ERROR } from 'final-form'; | ||
|
||
import { AuthWrapper } from 'containers/wrapper/component'; | ||
|
||
import Button from 'components/button'; | ||
import LinkButton from 'components/button/component'; | ||
import { Input } from 'components/forms'; | ||
|
||
import authenticationService from 'services/authentication'; | ||
|
||
const SuccessMessage = () => { | ||
const formState = useFormState(); | ||
const emailValue = formState.values?.email; | ||
|
||
return ( | ||
<div className="flex flex-col items-center gap-5"> | ||
<h2 className="text-3xl font-normal">Check your inbox</h2> | ||
<p className="text-center"> | ||
We've sent a link to {emailValue}. Please check your email to reset your password. If | ||
you don't see it, check your spam or junk folder. | ||
</p> | ||
<LinkButton theme="green" size="base" href="/auth/signin"> | ||
Ok | ||
</LinkButton> | ||
</div> | ||
); | ||
}; | ||
|
||
const ForgotPasswordPage = () => { | ||
const handleFormSubmit = useCallback(async ({ email }: { email: string }) => { | ||
try { | ||
await authenticationService.forgotPassword(email); | ||
} catch (err) { | ||
return { | ||
[FORM_ERROR]: err instanceof Error ? err.message : 'An unexpected error occurred', | ||
}; | ||
} | ||
}, []); | ||
|
||
return ( | ||
<AuthWrapper> | ||
<FormRFF onSubmit={handleFormSubmit} initialValues={{ email: '' }}> | ||
{({ submitError, handleSubmit, submitSucceeded }) => ( | ||
<> | ||
{submitSucceeded ? ( | ||
<SuccessMessage /> | ||
) : ( | ||
<form className="space-y-5 mb-10" onSubmit={handleSubmit} autoComplete="off"> | ||
<h2 className="text-3xl text-center font-normal">Forgot password?</h2> | ||
<p>Enter your email and we'll send you a link back to your account.</p> | ||
<div> | ||
<label>Email</label> | ||
<FieldRFF name="email" type="email"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
</div> | ||
{submitError && <div className="text-red-0">{submitError}</div>} | ||
<div className="flex justify-between gap-3"> | ||
<LinkButton theme="outline" className="flex-1" href="/auth/signin"> | ||
Cancel | ||
</LinkButton> | ||
<Button theme="green" size="base" className="flex-1" type="submit"> | ||
Send link | ||
</Button> | ||
</div> | ||
</form> | ||
)} | ||
</> | ||
)} | ||
</FormRFF> | ||
</AuthWrapper> | ||
); | ||
}; | ||
|
||
export default ForgotPasswordPage; |
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 |
---|---|---|
|
@@ -9,6 +9,8 @@ import { FORM_ERROR } from 'final-form'; | |
import { getServerSession } from 'next-auth/next'; | ||
import { signIn } from 'next-auth/react'; | ||
|
||
import { AuthWrapper } from 'containers/wrapper/component'; | ||
|
||
import Button from 'components/button'; | ||
import { Input } from 'components/forms/input/component'; | ||
import { authOptions } from 'pages/api/auth/[...nextauth]'; | ||
|
@@ -40,52 +42,47 @@ const SignInPage: React.FC = () => { | |
); | ||
|
||
return ( | ||
<div className="justify-center items-center flex grow"> | ||
<div className="bg-white px-40 py-20"> | ||
<FormRFF | ||
onSubmit={handleFormSubmit} | ||
initialValues={{ email: '[email protected]', password: 'NP!-.9Q*csfnuJXDDchj' }} | ||
<AuthWrapper> | ||
<FormRFF onSubmit={handleFormSubmit} initialValues={{ email: '', password: '' }}> | ||
{({ submitError, handleSubmit }) => ( | ||
<form className="space-y-5 mb-10" onSubmit={handleSubmit} autoComplete="off"> | ||
<h2 className="text-3xl text-center font-normal">Log in</h2> | ||
<div> | ||
<label>Username</label> | ||
<FieldRFF name="email" type="email"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
</div> | ||
<div> | ||
<label>Password</label> | ||
<FieldRFF name="password" type="password"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
<Link href="/auth/forgot-password" className="text-sm text-green-0 hover:underline"> | ||
Forgot password? | ||
</Link> | ||
</div> | ||
{submitError && <div className="text-red-0">{submitError}</div>} | ||
<div className="flex justify-center"> | ||
<Button theme="green" size="base" type="submit"> | ||
Connect | ||
</Button> | ||
</div> | ||
</form> | ||
)} | ||
</FormRFF> | ||
<div className="flex gap-4"> | ||
<p>Don’t have an account, but you are a FORA member?</p> | ||
<Link | ||
href="https://forainitiative.org/contact/" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="text-base text-green-0 hover:underline" | ||
> | ||
{({ submitError, handleSubmit }) => ( | ||
<form className="space-y-5 mb-10" onSubmit={handleSubmit} autoComplete="off"> | ||
<h2 className="text-3xl text-center font-normal">Log in</h2> | ||
<div> | ||
<label>Username</label> | ||
<FieldRFF name="email" type="email"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
</div> | ||
<div> | ||
<label>Password</label> | ||
<FieldRFF name="password" type="password"> | ||
{({ input }) => <Input {...input} />} | ||
</FieldRFF> | ||
<Link href="/auth/forgot-password" className="text-sm text-green-0 hover:underline"> | ||
Forgot password? | ||
</Link> | ||
</div> | ||
{submitError && <div className="text-red-0">{submitError}</div>} | ||
<div className="flex justify-center"> | ||
<Button theme="green" size="base" type="submit"> | ||
Connect | ||
</Button> | ||
</div> | ||
</form> | ||
)} | ||
</FormRFF> | ||
<div className="flex gap-4"> | ||
<p>Don’t have an account, but you are a FORA member?</p> | ||
<Link | ||
href="https://forainitiative.org/contact/" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
className="text-base text-green-0 hover:underline" | ||
> | ||
Contact us | ||
</Link> | ||
</div> | ||
Contact us | ||
</Link> | ||
</div> | ||
</div> | ||
</AuthWrapper> | ||
); | ||
}; | ||
|
||
|
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,11 @@ | ||
import { useParams } from 'next/navigation'; | ||
|
||
import ChangePassword from 'containers/auth/change-password'; | ||
|
||
const SignupPage = () => { | ||
const params = useParams<{ token: string } | null>(); | ||
|
||
return <ChangePassword token={params?.token} />; | ||
}; | ||
|
||
export default SignupPage; |
Oops, something went wrong.