Skip to content

Commit

Permalink
feat: passwordless frontend (#3941)
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyjablonski committed Mar 18, 2024
1 parent 02a4dbd commit fc912c8
Show file tree
Hide file tree
Showing 15 changed files with 428 additions and 76 deletions.
2 changes: 2 additions & 0 deletions shared-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ export * from "./src/views/summaryTables"
export * from "./src/views/forgot-password/FormForgotPassword"
export * from "./src/views/layout/ExygyFooter"
export * from "./src/views/sign-in/FormSignIn"
export * from "./src/views/sign-in/FormSignInDefault"
export * from "./src/views/sign-in/FormSignInErrorBox"
export * from "./src/views/sign-in/FormSignInPwdless"
export * from "./src/views/sign-in/ResendConfirmationModal"
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@
"authentication.signIn.changeYourPassword": "Puede cambiar su contraseña",
"authentication.signIn.enterLoginEmail": "Por favor, escriba su correo electrónico de inicio de sesión",
"authentication.signIn.enterLoginPassword": "Por favor, escriba su contraseña de inicio de sesión",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Por favor, escriba un código válido.",
"authentication.signIn.enterValidEmailAndPassword": "Por favor, escriba un correo electrónico y una contraseña válidos.",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Por favor, escriba un código válido",
"authentication.signIn.enterValidEmailAndPassword": "Por favor, escriba un correo electrónico y una contraseña válidos",
"authentication.signIn.errorGenericMessage": "Por favor inténtelo de nuevo, o comuníquese con servicio al cliente para recibir asistencia.",
"authentication.signIn.error": "Hubo un error cuando usted inició sesión",
"authentication.signIn.forgotPassword": "Olvidé la contraseña",
Expand Down
22 changes: 20 additions & 2 deletions shared-helpers/src/locales/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"account.viewApplications": "View applications",
"account.myApplicationsSubtitle": "See lottery dates and listings for properties for which you've applied",
"account.noApplications": "It looks like you haven't applied to any listings yet.",
"account.reviewTerms": "Review Terms of Use",
"account.reviewTermsHelper": "You must accept the terms of use before creating an account.",
"account.signUpSaveTime.applyFaster": "Apply faster with saved application details",
"account.signUpSaveTime.checkStatus": "Check on the status of an application at any time",
"account.signUpSaveTime.resetPassword": "Simply reset your password if you forget it",
Expand All @@ -37,6 +39,16 @@
"account.settings.placeholders.year": "YYYY",
"account.settings.update": "Update",
"account.settings.iconTitle": "generic user",
"account.pwdless.code": "Your code",
"account.pwdless.codeAlert": "We sent a code to %{email} to finish signing up. Be aware, the code will expire in 5 minutes.",
"account.pwdless.codeNewAlert": "A new code has been sent to %{email}. Be aware, the code will expire in 5 minutes.",
"account.pwdless.continue": "Continue",
"account.pwdless.notReceived": "Didn't receive your code?",
"account.pwdless.resend": "Resend",
"account.pwdless.resendCode": "Resend Code",
"account.pwdless.resendCodeButton": "Resend the code",
"account.pwdless.resendCodeHelper": "If there is an account made with that email, we’ll send a new code. Be aware, the code will expire in 5 minutes.",
"account.pwdless.verifyTitle": "Verify that it's you",
"alert.maintenance": "This site is undergoing scheduled maintenance. We apologize for any inconvenience.",
"application.ada.hearing": "For Hearing Impairments",
"application.ada.label": "ADA Accessible Units",
Expand Down Expand Up @@ -530,14 +542,19 @@
"authentication.signIn.changeYourPassword": "You can change your password",
"authentication.signIn.enterLoginEmail": "Please enter your login email",
"authentication.signIn.enterLoginPassword": "Please enter your login password",
"authentication.signIn.enterValidEmailAndPassword": "Please enter a valid email and password.",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Please enter a valid code.",
"authentication.signIn.enterValidEmailAndPassword": "Please enter a valid email and password",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Please enter a valid code",
"authentication.signIn.error": "There was an error signing you in",
"authentication.signIn.errorGenericMessage": "Please try again, or contact support for help.",
"authentication.signIn.forgotPassword": "Forgot password?",
"authentication.signIn.loginError": "Please enter a valid email address",
"authentication.signIn.passwordError": "Please enter a valid password",
"authentication.signIn.passwordOutdated": "Your password has expired. Please reset your password.",
"authentication.signIn.pwdless.createAccountCopy": "Sign up quicky with no need to remember any passwords.",
"authentication.signIn.pwdless.emailHelperText": "Enter your email and we'll send you a code to sign in.",
"authentication.signIn.pwdless.getCode": "Get code to sign in",
"authentication.signIn.pwdless.useCode": "Get a code instead",
"authentication.signIn.pwdless.usePassword": "Use your password instead",
"authentication.signIn.success": "Welcome back, %{name}!",
"authentication.signIn.youHaveToWait": "You’ll have to wait 30 minutes since the last failed attempt before trying again.",
"authentication.signIn.yourAccountIsNotConfirmed": "Your account is not confirmed",
Expand Down Expand Up @@ -917,6 +934,7 @@
"t.email": "Email",
"t.emailAddressPlaceholder": "you@myemail.com",
"t.filter": "Filter",
"t.finish": "Finish",
"t.floor": "floor",
"t.floors": "floors",
"t.getDirections": "Get Directions",
Expand Down
5 changes: 3 additions & 2 deletions shared-helpers/src/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@
"authentication.createAccount.password": "Mật khẩu",
"authentication.createAccount.reEnterEmail": "Nhập lại địa chỉ Email",
"authentication.createAccount.reEnterPassword": "Nhập lại mật khẩu của bạn",

"authentication.createAccount.resendAnEmailTo": "Gửi lại email đến",
"authentication.createAccount.resendEmailInfo": "Vui lòng nhấp vào liên kết trong email mà chúng tôi gửi cho quý vị trong vòng 24 giờ để hoàn tất việc tạo tài khoản.",
"authentication.createAccount.resendTheEmail": "Gửi lại Email",
Expand All @@ -386,8 +387,8 @@
"authentication.signIn.changeYourPassword": "Quý vị có thể đổi mật khẩu",
"authentication.signIn.enterLoginEmail": "Vui lòng nhập email đăng nhập của quý vị",
"authentication.signIn.enterLoginPassword": "Vui lòng nhập mật khẩu đăng nhập của quý vị",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Vui lòng nhập mã hợp lệ.",
"authentication.signIn.enterValidEmailAndPassword": "Vui lòng nhập email và mật khẩu hợp lệ.",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "Vui lòng nhập mã hợp lệ",
"authentication.signIn.enterValidEmailAndPassword": "Vui lòng nhập email và mật khẩu hợp lệ",
"authentication.signIn.errorGenericMessage": "Vui lòng thử lại hoặc liên lạc với bộ phận hỗ trợ để được trợ giúp.",
"authentication.signIn.error": "Đã xảy ra lỗi khi quý vị đăng nhập",
"authentication.signIn.forgotPassword": "Quên mật khẩu",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,8 @@
"authentication.signIn.changeYourPassword": "您可以變更密碼",
"authentication.signIn.enterLoginEmail": "請輸入您的登入電子郵件",
"authentication.signIn.enterLoginPassword": "請輸入您的登入密碼",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "請輸入有效的代碼",
"authentication.signIn.enterValidEmailAndPassword": "請輸入有效的電子郵件和密碼",
"authentication.signIn.enterValidEmailAndPasswordAndMFA": "請輸入有效的代碼",
"authentication.signIn.enterValidEmailAndPassword": "請輸入有效的電子郵件和密碼",
"authentication.signIn.errorGenericMessage": "請再試一次,或聯絡支援人員尋求協助。",
"authentication.signIn.error": "您在登入時出現錯誤",
"authentication.signIn.forgotPassword": "忘記密碼",
Expand Down
26 changes: 26 additions & 0 deletions shared-helpers/src/views/sign-in/FormSignIn.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,29 @@
margin-top: var(--seeds-s6);
width: 100%;
}

.sign-in-email-input {
margin-bottom: var(--seeds-s6);
}

.sign-in-password-input {
margin-bottom: var(--seeds-s3);
}

.sign-in-action {
margin-top: var(--seeds-s6);
}

.create-account-copy {
padding-bottom: var(--seeds-s6);
color: var(--seeds-text-color-light);
font-size: var(--seeds-type-label-size);
}

.pwdless-header {
margin-bottom: var(--seeds-s3);
}

.default-header {
margin-bottom: var(--seeds-s6);
}
72 changes: 19 additions & 53 deletions shared-helpers/src/views/sign-in/FormSignIn.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import React, { useContext } from "react"
import React from "react"
import type { UseFormMethods } from "react-hook-form"
import { Field, Form, NavigationContext, t } from "@bloom-housing/ui-components"
import { useRouter } from "next/router"
import { t } from "@bloom-housing/ui-components"
import { Button, Heading } from "@bloom-housing/ui-seeds"
import { CardSection } from "@bloom-housing/ui-seeds/src/blocks/Card"
import { FormSignInErrorBox } from "./FormSignInErrorBox"
import { NetworkStatus } from "../../auth/catchNetworkError"
import { BloomCard } from "../components/BloomCard"
import { useRouter } from "next/router"
import { getListingRedirectUrl } from "../../utilities/getListingRedirectUrl"
import styles from "./FormSignIn.module.scss"

export type FormSignInProps = {
control: FormSignInControl
onSubmit: (data: FormSignInValues) => void
networkStatus: NetworkStatus
showRegisterBtn?: boolean
children: React.ReactNode
}

export type FormSignInControl = {
errors: UseFormMethods["errors"]
handleSubmit: UseFormMethods["handleSubmit"]
register: UseFormMethods["register"]
watch: UseFormMethods["watch"]
}

export type FormSignInValues = {
Expand All @@ -30,18 +27,13 @@ export type FormSignInValues = {
}

const FormSignIn = ({
onSubmit,
children,
networkStatus,
showRegisterBtn,
control: { errors, register, handleSubmit },
control: { errors },
}: FormSignInProps) => {
const onError = () => {
window.scrollTo(0, 0)
}
const { LinkComponent } = useContext(NavigationContext)
const router = useRouter()
const listingIdRedirect = router.query?.listingId as string
const forgetPasswordURL = getListingRedirectUrl(listingIdRedirect, "/forgot-password")
const createAccountUrl = getListingRedirectUrl(listingIdRedirect, "/create-account")

return (
Expand All @@ -53,49 +45,23 @@ const FormSignIn = ({
errorMessageId={"main-sign-in"}
className={styles["sign-in-error-container"]}
/>
<CardSection divider={"inset"}>
<Form id="sign-in" onSubmit={handleSubmit(onSubmit, onError)}>
<Field
className="mb-6"
name="email"
label={t("t.email")}
validation={{ required: true }}
error={errors.email}
errorMessage={t("authentication.signIn.enterLoginEmail")}
register={register}
dataTestId="sign-in-email-field"
labelClassName={"text__caps-spaced"}
/>
<aside>
<LinkComponent href={forgetPasswordURL} className={styles["forgot-password"]}>
{t("authentication.signIn.forgotPassword")}
</LinkComponent>
</aside>
<Field
className="mb-3"
name="password"
label={t("authentication.createAccount.password")}
validation={{ required: true }}
error={errors.password}
errorMessage={t("authentication.signIn.enterLoginPassword")}
register={register}
type={"password"}
dataTestId="sign-in-password-field"
labelClassName={"text__caps-spaced"}
/>
<div className="mt-6">
<Button type="submit" variant="primary" id="sign-in-button">
{t("nav.signIn")}
</Button>
</div>
</Form>
</CardSection>
<CardSection divider={"inset"}>{children}</CardSection>
{showRegisterBtn && (
<CardSection divider={"inset"}>
<Heading priority={2} size="2xl" className="mb-6">
<Heading
priority={2}
size="2xl"
className={
process.env.showPwdless ? styles["pwdless-header"] : styles["default-header"]
}
>
{t("authentication.createAccount.noAccount")}
</Heading>

{process.env.showPwdless && (
<div className={styles["create-account-copy"]}>
{t("authentication.signIn.pwdless.createAccountCopy")}
</div>
)}
<Button variant="primary-outlined" href={createAccountUrl}>
{t("account.createAccount")}
</Button>
Expand Down
76 changes: 76 additions & 0 deletions shared-helpers/src/views/sign-in/FormSignInDefault.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useContext } from "react"
import { useRouter } from "next/router"
import type { UseFormMethods } from "react-hook-form"
import { Field, Form, NavigationContext, t } from "@bloom-housing/ui-components"
import { Button } from "@bloom-housing/ui-seeds"
import { getListingRedirectUrl } from "../../utilities/getListingRedirectUrl"
import styles from "./FormSignIn.module.scss"

export type FormSignInDefaultProps = {
control: FormSignInDefaultControl
onSubmit: (data: FormSignInDefaultValues) => void
}

export type FormSignInDefaultValues = {
email: string
password: string
}

export type FormSignInDefaultControl = {
errors: UseFormMethods["errors"]
handleSubmit: UseFormMethods["handleSubmit"]
register: UseFormMethods["register"]
}

const FormSignInDefault = ({
onSubmit,
control: { errors, register, handleSubmit },
}: FormSignInDefaultProps) => {
const onError = () => {
window.scrollTo(0, 0)
}
const { LinkComponent } = useContext(NavigationContext)
const router = useRouter()
const listingIdRedirect = router.query?.listingId as string
const forgetPasswordURL = getListingRedirectUrl(listingIdRedirect, "/forgot-password")

return (
<Form id="sign-in" onSubmit={handleSubmit(onSubmit, onError)}>
<Field
className={styles["sign-in-email-input"]}
name="email"
label={t("t.email")}
labelClassName="text__caps-spaced"
validation={{ required: true }}
error={errors.email}
errorMessage={t("authentication.signIn.enterLoginEmail")}
register={register}
dataTestId="sign-in-email-field"
/>
<aside>
<LinkComponent href={forgetPasswordURL} className={styles["forgot-password"]}>
{t("authentication.signIn.forgotPassword")}
</LinkComponent>
</aside>
<Field
className={styles["sign-in-password-input"]}
name="password"
label={t("authentication.createAccount.password")}
labelClassName="text__caps-spaced"
validation={{ required: true }}
error={errors.password}
errorMessage={t("authentication.signIn.enterLoginPassword")}
register={register}
type={"password"}
dataTestId="sign-in-password-field"
/>
<div className={styles["sign-in-action"]}>
<Button type="submit" variant="primary" id="sign-in-button">
{t("nav.signIn")}
</Button>
</div>
</Form>
)
}

export { FormSignInDefault as default, FormSignInDefault }

0 comments on commit fc912c8

Please sign in to comment.