Skip to content

Commit

Permalink
fix(core): user is not redirected to Login page after requesting pass…
Browse files Browse the repository at this point in the history
…word reset link
  • Loading branch information
“bc-yevhenii-buliuk” committed Jun 6, 2024
1 parent 19a3d14 commit 7470b1f
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Message } from '~/components/ui/message';
import { useRouter } from '~/navigation';

import { submitChangePasswordForm } from '../_actions/submit-change-password-form';
import { useLoginStatusContext } from './login-status-provider';

interface Props {
customerId: string;
Expand Down Expand Up @@ -49,6 +50,8 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {
message: '',
});

const {loginState, setLoginState} = useLoginStatusContext();

const [newPassword, setNewPasssword] = useState('');
const [isConfirmPasswordValid, setIsConfirmPasswordValid] = useState(true);

Expand All @@ -59,10 +62,6 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {
messageText = state.message;
}

if (state.status === 'success') {
messageText = t('successMessage');
}

const handleNewPasswordChange = (e: ChangeEvent<HTMLInputElement>) =>
setNewPasssword(e.target.value);
const handleConfirmPasswordValidation = (e: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -72,12 +71,13 @@ export const ChangePasswordForm = ({ customerId, customerToken }: Props) => {
};

if (state.status === 'success') {
setTimeout(() => router.push('/login'), 2000);
setLoginState({ status: 'success', message: t('confirmChangePassword') });
router.push('/login');
}

return (
<>
{(state.status === 'error' || state.status === 'success') && (
{state.status === 'error' && (
<Message className="mb-8 w-full text-gray-500" variant={state.status}>
<p>{messageText}</p>
</Message>
Expand Down
9 changes: 9 additions & 0 deletions core/app/[locale]/(default)/login/_components/login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { Input } from '~/components/ui/input';
import { Message } from '~/components/ui/message';

import { submitLoginForm } from '../_actions/submit-login-form';
import { useLoginStatusContext } from './login-status-provider';
import { useRouter } from 'next/router';

const SubmitButton = () => {
const { pending } = useFormStatus();
Expand All @@ -39,6 +41,7 @@ export const LoginForm = () => {
const [isEmailValid, setIsEmailValid] = useState(true);
const [isPasswordValid, setIsPasswordValid] = useState(true);
const [state, formAction] = useFormState(submitLoginForm, { status: 'idle' });
const {loginState, setLoginState} = useLoginStatusContext();

const t = useTranslations('Account.Login');

Expand All @@ -62,6 +65,12 @@ export const LoginForm = () => {

return (
<>
{loginState.status === 'success' && (
<Message className="mb-8 w-full text-gray-500 col-span-full" variant={loginState.status}>
<p>{loginState.message}</p>
</Message>
)}

{isFormInvalid && (
<Message
aria-labelledby="error-message"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';

import { createContext, useContext, useState, useEffect, PropsWithChildren } from 'react';

export interface LoginState {
status: 'idle' | 'success';
message?: string;
}

export const LoginStatusContext = createContext<{
loginState: LoginState;
setLoginState: (state: LoginState | ((prevState: LoginState) => LoginState)) => void;
} | null>(null);

export const LoginStatusProvider = ({ children }: PropsWithChildren) => {
const [loginState, setLoginState] = useState<LoginState>({status: 'idle', message: ''});

useEffect(() => {
if (loginState.status !== 'idle') {
setTimeout(() => {
setLoginState({ status: 'idle', message: '' });
}, 3000);
}
}, [loginState, setLoginState]);

return (
<LoginStatusContext.Provider value={{loginState, setLoginState}}>
{children}
</LoginStatusContext.Provider>
)
}

export function useLoginStatusContext() {
const context = useContext(LoginStatusContext);

if (!context) {
throw new Error('useLoginStatusContext must be used within a LoginStatusProvider');
}

return context;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { Message } from '~/components/ui/message';
import { submitResetPasswordForm } from '../../_actions/submit-reset-password-form';

import { ResetPasswordFormFragment } from './fragment';
import { useLoginStatusContext } from '../login-status-provider';
import { useRouter } from 'next/navigation';

interface Props {
reCaptchaSettings?: FragmentOf<typeof ResetPasswordFormFragment>;
Expand Down Expand Up @@ -58,6 +60,8 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {
const reCaptchaRef = useRef<ReCaptcha>(null);
const [reCaptchaToken, setReCaptchaToken] = useState('');
const [isReCaptchaValid, setReCaptchaValid] = useState(true);
const {loginState, setLoginState} = useLoginStatusContext();
const router = useRouter();

const onReCatpchaChange = (token: string | null) => {
if (!token) {
Expand Down Expand Up @@ -96,10 +100,8 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {

const customerEmail = formData.get('email');

setFormStatus({
status: 'success',
message: t('successMessage', { email: customerEmail?.toString() }),
});
setLoginState({ status: 'success', message: t('confirmResetPassword', { email: customerEmail?.toString() })});
router.push('/login')
}

if (submit.status === 'error') {
Expand All @@ -111,9 +113,9 @@ export const ResetPasswordForm = ({ reCaptchaSettings }: Props) => {

return (
<>
{formStatus && (
<Message className="mb-8 w-full" variant={formStatus.status}>
<p>{formStatus.message}</p>
{formStatus?.status === 'error' && (
<Message className="mb-8 w-full" variant={formStatus?.status}>
<p>{formStatus?.message}</p>
</Message>
)}

Expand Down
10 changes: 10 additions & 0 deletions core/app/[locale]/(default)/login/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { PropsWithChildren } from 'react';
import { LoginStatusProvider } from './_components/login-status-provider';

export default function LoginLayout({ children }: PropsWithChildren) {
return (
<LoginStatusProvider>
{children}
</LoginStatusProvider>
)
}
8 changes: 5 additions & 3 deletions core/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@
"Register": {
"heading": "New account",
"submit": "Create account",
"submitting": "Creating account...",
"submitting": "Creating account...",
"recaptchaText": "Pass ReCAPTCHA check",
"successMessage": "Dear {firstName} {lastName}, your account was successfully created. Redirecting to account...",
"stateProvincePrefix": "Choose state or province",
Expand All @@ -283,7 +283,8 @@
"confirmPasswordValidationMessage": "Entered passwords are mismatched. Please try again.",
"newPasswordValidationMessage": "New password must be different from the current password or/and match confirm password.",
"notEmptyMessage": "Field should not be empty",
"successMessage": "Password has been updated successfully!"
"successMessage": "Password has been updated successfully!",
"confirmChangePassword": "Your password has been successfully updated."
},
"SubmitChangePassword": {
"spinnerText": "Submitting...",
Expand All @@ -294,7 +295,8 @@
"emailLabel": "Email",
"emailValidationMessage": "Enter a valid email such as name@domain.com",
"successMessage": "Your password reset email is on its way to {email}. If you don't see it, check your spam folder.",
"recaptchaText": "Pass ReCAPTCHA check"
"recaptchaText": "Pass ReCAPTCHA check",
"confirmResetPassword": "If the email address {email} is linked to an account in our store, we have sent you a password reset email. Please check your inbox and spam folder if you don't see it."
},
"SubmitResetPassword": {
"spinnerText": "Submitting...",
Expand Down

0 comments on commit 7470b1f

Please sign in to comment.