diff --git a/apps/frontend/src/components/forms/resetPasswordModal.tsx b/apps/frontend/src/components/forms/resetPasswordModal.tsx index e87df83c0..0b61f7119 100644 --- a/apps/frontend/src/components/forms/resetPasswordModal.tsx +++ b/apps/frontend/src/components/forms/resetPasswordModal.tsx @@ -25,6 +25,18 @@ const ResetPasswordModal: React.FC = () => { const navigate = useNavigate(); + const handleSendCodeKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && email) { + handleSendCode(); + } + }; + + const handleResetPasswordKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && password && confirmPassword) { + handleResetPassword(); + } + }; + const handleSendCode = async () => { try { await resetPassword({ username: email }); @@ -136,6 +148,11 @@ const ResetPasswordModal: React.FC = () => { ? (e) => setCode(e.target.value) : (e) => setEmail(e.target.value) } + onKeyDown={ + step === 'reset' + ? handleSendCodeKeyDown + : handleResetPasswordKeyDown + } /> @@ -148,6 +165,7 @@ const ResetPasswordModal: React.FC = () => { placeholder="Enter new password" {...inputStyles} onChange={(e) => setPassword(e.target.value)} + onKeyDown={handleResetPasswordKeyDown} /> @@ -157,6 +175,7 @@ const ResetPasswordModal: React.FC = () => { placeholder="Confirm Password" {...inputStyles} onChange={(e) => setConfirmPassword(e.target.value)} + onKeyDown={handleResetPasswordKeyDown} /> diff --git a/apps/frontend/src/containers/homepage.tsx b/apps/frontend/src/containers/homepage.tsx index 26750cb02..7ad0834fc 100644 --- a/apps/frontend/src/containers/homepage.tsx +++ b/apps/frontend/src/containers/homepage.tsx @@ -14,7 +14,7 @@ import { import { useAuthenticator } from '@aws-amplify/ui-react'; const Homepage: React.FC = () => { - const { user } = useAuthenticator((context) => [context.user]); + const { authStatus } = useAuthenticator((context) => [context.authStatus]); return ( @@ -171,7 +171,7 @@ const Homepage: React.FC = () => { - {!user && ( + {authStatus !== 'authenticated' && ( Other Pages diff --git a/apps/frontend/src/containers/loginPage.tsx b/apps/frontend/src/containers/loginPage.tsx index 1cc951dfd..c77f66d9d 100644 --- a/apps/frontend/src/containers/loginPage.tsx +++ b/apps/frontend/src/containers/loginPage.tsx @@ -1,5 +1,6 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { signIn, confirmSignIn, fetchAuthSession } from '@aws-amplify/auth'; +import { useAuthenticator } from '@aws-amplify/ui-react'; import { useNavigate, useLocation } from 'react-router-dom'; import { Box, @@ -31,12 +32,35 @@ const LoginPage: React.FC = () => { const [showConfirmNewPassword, setShowConfirmNewPassword] = useState(false); const [step, setStep] = useState('login'); const [alertState, setAlertMessage] = useAlert(); + const { authStatus } = useAuthenticator((context) => [context.authStatus]); const navigate = useNavigate(); const location = useLocation(); const from = location.state?.from?.pathname || '/'; + useEffect(() => { + if (authStatus === 'authenticated') { + navigate(from, { replace: true }); + } + }, [authStatus, from, navigate]); + + const handleLoginKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && email && password) { + handleLogin(); + } + }; + + const handleNewPasswordKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && newPassword && confirmNewPassword) { + handleSetNewPassword(); + } + }; + const handleLogin = async () => { + if (authStatus === 'authenticated') { + navigate(from, { replace: true }); + return; + } try { const result = await signIn({ username: email, password }); // On temporary password signin, this will trigger the need to create a new password @@ -48,8 +72,25 @@ const LoginPage: React.FC = () => { } else { navigate(from, { replace: true }); } - } catch { - setAlertMessage('Login failed'); + } catch (error: unknown) { + if (error instanceof Error) { + if (error.name === 'UserAlreadyAuthenticatedException') { + navigate(from, { replace: true }); + return; + } + if ( + error.name === 'NotAuthorizedException' || + error.name === 'UserNotFoundException' + ) { + setAlertMessage('Incorrect email or password. Please try again.'); + return; + } + } + setAlertMessage( + navigator.onLine + ? 'Login failed. The server may be unavailable. Please try again later.' + : 'No internet connection. Please check your network and try again.', + ); } }; @@ -137,6 +178,7 @@ const LoginPage: React.FC = () => { color="neutral.700" _placeholder={{ ...placeholderStyles }} onChange={(e) => setEmail(e.target.value)} + onKeyDown={handleLoginKeyDown} /> @@ -152,6 +194,7 @@ const LoginPage: React.FC = () => { color="neutral.700" _placeholder={{ ...placeholderStyles }} onChange={(e) => setPassword(e.target.value)} + onKeyDown={handleLoginKeyDown} /> { color="neutral.700" _placeholder={{ ...placeholderStyles }} onChange={(e) => setNewPassword(e.target.value)} + onKeyDown={handleNewPasswordKeyDown} /> { color="neutral.700" _placeholder={{ ...placeholderStyles }} onChange={(e) => setConfirmNewPassword(e.target.value)} + onKeyDown={handleNewPasswordKeyDown} /> { const navigate = useNavigate(); + const location = useLocation(); + const { authStatus } = useAuthenticator((context) => [context.authStatus]); + + const from = location.state?.from?.pathname || '/'; + + useEffect(() => { + if (authStatus === 'authenticated') { + navigate(from, { replace: true }); + } + }, [authStatus, from, navigate]); return (