Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: various Toast updates #818

Merged
merged 2 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions shared-helpers/src/auth/RequireLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { FunctionComponent, useContext, useEffect, useState } from "react"
import { NavigationContext } from "@bloom-housing/ui-components"
import { AuthContext } from "./AuthContext"
import { MessageContext } from "../utilities/MessageContext"
import { useToastyRef } from "../utilities/MessageContext"

// See https://github.com/Microsoft/TypeScript/issues/14094
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
Expand Down Expand Up @@ -31,7 +31,7 @@ const RequireLogin: FunctionComponent<RequireLoginProps> = ({
}) => {
const { router } = useContext(NavigationContext)
const { profile, initialStateLoaded } = useContext(AuthContext)
const { addToast } = useContext(MessageContext)
const toastyRef = useToastyRef()
const [hasTerms, setHasTerms] = useState(false)

// Parse just the pathname portion of the signInPath (in case we want to pass URL params)
Expand All @@ -56,6 +56,8 @@ const RequireLogin: FunctionComponent<RequireLoginProps> = ({
}, [profile])

useEffect(() => {
const { addToast } = toastyRef.current

if (loginRequiredForPath && initialStateLoaded && !profile) {
addToast(signInMessage, { variant: "primary" })
void router.push(signInPath)
Expand All @@ -73,7 +75,7 @@ const RequireLogin: FunctionComponent<RequireLoginProps> = ({
signInMessage,
termsPath,
hasTerms,
addToast,
toastyRef,
])

if (
Expand Down
2 changes: 1 addition & 1 deletion shared-helpers/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@
"authentication.forgotPassword.errors.passwordTooWeak": "La contraseña es demasiado débil. Debe tener al menos 12 caracteres e incluir al menos una letra minúscula, una letra mayúscula, un número y un carácter especial (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "El token de restablecimiento de contraseña caducó. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.errors.tokenMissing": "El token no fue encontrado. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.message": "Si hay una cuenta creada con ese correo electrónico, recibirás un correo electrónico con un enlace para restablecer tu contraseña.",
"authentication.forgotPassword.message": "Si hay una cuenta creada con ese correo electrónico, recibirás un correo electrónico con un enlace para restablecer tu contraseña. El enlace de reinicio es válido por 1 hora.",
"authentication.forgotPassword.passwordConfirmation": "Confirmación de contraseña",
"authentication.forgotPassword.sendEmail": "Enviar correo electrónico",
"authentication.signIn.accountHasBeenLocked": "Por razones de seguridad, esta cuenta ha sido bloqueada.",
Expand Down
2 changes: 1 addition & 1 deletion shared-helpers/src/locales/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@
"authentication.forgotPassword.errors.passwordTooWeak": "Password is too weak. Must be at least 12 characters and include at least one lowercase letter, one uppercase letter, one number, and one special character (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Reset password token expired. Please request for a new one.",
"authentication.forgotPassword.errors.tokenMissing": "Token not found. Please request for a new one.",
"authentication.forgotPassword.message": "If there is an account made with that email, you'll receive an email with a link to reset your password.",
"authentication.forgotPassword.message": "If there is an account made with that email, you'll receive an email with a link to reset your password. The reset link is valid for 1 hour.",
"authentication.forgotPassword.passwordConfirmation": "Password Confirmation",
"authentication.forgotPassword.sendEmail": "Send email",
"authentication.signIn.accountHasBeenLocked": "For security reasons, this account has been locked.",
Expand Down
2 changes: 1 addition & 1 deletion shared-helpers/src/locales/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
"authentication.forgotPassword.errors.passwordTooWeak": "Masyadong mahina ang password. Dapat ay hindi bababa sa 12 character at may kasamang hindi bababa sa isang maliit na titik, isang malaking titik, isang numero, at isang espesyal na character (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Nag-expire na ang token ng pag-reset ng password. Humiling ng bago.",
"authentication.forgotPassword.errors.tokenMissing": "Hindi nahanap ang token. Humiling ng bago.",
"authentication.forgotPassword.message": "Kung may account na ginawa gamit ang email na iyon, makakatanggap ka ng email na may link para i-reset ang iyong password.",
"authentication.forgotPassword.message": "Kung may account na ginawa gamit ang email na iyon, makakatanggap ka ng email na may link para i-reset ang iyong password. Ang link sa pag-reset ay may bisa sa loob ng 1 oras.",
"authentication.forgotPassword.passwordConfirmation": "Pagkumpirma ng Password",
"authentication.forgotPassword.sendEmail": "Magpadala ng email",
"authentication.signIn.accountHasBeenLocked": "Para sa mga kadahilanang pangseguridad, ang account na ito isinara na.",
Expand Down
2 changes: 1 addition & 1 deletion shared-helpers/src/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@
"authentication.forgotPassword.errors.passwordTooWeak": "Mật khẩu quá yếu. Phải có ít nhất 12 ký tự và bao gồm ít nhất một chữ cái viết thường, một chữ cái viết hoa, một số và một ký tự đặc biệt (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Mã thông báo đặt lại mật khẩu đã hết hạn. Vui lòng yêu cầu mã mới.",
"authentication.forgotPassword.errors.tokenMissing": "Không tìm thấy mã thông báo. Vui lòng yêu cầu mã mới.",
"authentication.forgotPassword.message": "Nếu có tài khoản được tạo bằng email đó, bạn sẽ nhận được email có liên kết để đặt lại mật khẩu của mình.",
"authentication.forgotPassword.message": "Nếu có tài khoản được tạo bằng email đó, bạn sẽ nhận được email có liên kết để đặt lại mật khẩu của mình. Liên kết đặt lại có hiệu lực trong 1 giờ.",
"authentication.forgotPassword.passwordConfirmation": "Xác nhận mật khẩu",
"authentication.forgotPassword.sendEmail": "Gửi email",
"authentication.signIn.accountHasBeenLocked": "Vì lý do bảo mật, tài khoản này đã bị khóa.",
Expand Down
2 changes: 1 addition & 1 deletion shared-helpers/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@
"authentication.forgotPassword.errors.passwordTooWeak": "密碼強度太弱。必須至少 12 個字符,並且至少包含 1 個小寫字母、1 個大寫字母、1 個數字和 1 個特殊字符 (#?!@$%^&*-)。",
"authentication.forgotPassword.errors.tokenExpired": "重設密碼權杖已到期。請要求新的權杖。",
"authentication.forgotPassword.errors.tokenMissing": "找不到權杖。請要求新的權杖。",
"authentication.forgotPassword.message": "如果使用该电子邮件创建了帐户,您将收到一封包含重置密码链接的电子邮件。",
"authentication.forgotPassword.message": "如果使用该电子邮件创建了帐户,您将收到一封包含重置密码链接的电子邮件。 重置链接有效期为1小时。",
"authentication.forgotPassword.passwordConfirmation": "确认密码",
"authentication.forgotPassword.sendEmail": "傳送電子郵件",
"authentication.signIn.accountHasBeenLocked": "基於安全原因,此帳戶已遭到鎖定。",
Expand Down
18 changes: 17 additions & 1 deletion shared-helpers/src/utilities/MessageContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import React, { FunctionComponent, createContext, createElement, useState, useRef } from "react"
import React, {
FunctionComponent,
createContext,
createElement,
useContext,
useState,
useRef,
} from "react"
import { CommonMessageProps } from "@bloom-housing/ui-seeds/src/blocks/shared/CommonMessage"

// TODO: this should be exportable from seeds directly
Expand Down Expand Up @@ -49,3 +56,12 @@ export const MessageProvider: FunctionComponent<React.PropsWithChildren> = ({ ch
children
)
}

/**
* Use the current value of a ref within `useEffect` so you can pass the ref to the dependencies
* array. Otherwise, the effect will constantly rerun because the context alone isn't a stable ref.
* File this one in the "Weird React" category!
*/
export const useToastyRef = () => {
return useRef(useContext(MessageContext))
}
11 changes: 6 additions & 5 deletions sites/public/src/components/account/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { t, Form, Field } from "@bloom-housing/ui-components"
import { Button, Dialog } from "@bloom-housing/ui-seeds"
import { AuthContext, MessageContext, emailRegex } from "@bloom-housing/shared-helpers"
import { AuthContext, useToastyRef, emailRegex } from "@bloom-housing/shared-helpers"
import { useRouter } from "next/router"
import { useContext, useEffect, useRef, useState } from "react"
import { useForm } from "react-hook-form"
Expand All @@ -10,7 +10,7 @@ export interface ConfirmationModalProps {}

const ConfirmationModal = () => {
const { resendConfirmation, profile, confirmAccount } = useContext(AuthContext)
const { addToast } = useContext(MessageContext)
const toastyRef = useToastyRef()
const [openModal, setOpenModal] = useState(false)
const router = useRouter()

Expand All @@ -23,6 +23,8 @@ const ConfirmationModal = () => {
email.current = watch("email", "")

const onSubmit = async (email) => {
const { addToast } = toastyRef.current

try {
const listingId = router.query?.listingId as string
await resendConfirmation(email, listingId)
Expand All @@ -42,6 +44,7 @@ const ConfirmationModal = () => {
}

useEffect(() => {
const { addToast } = toastyRef.current
const redirectUrl = router.query?.redirectUrl as string
const listingId = router.query?.listingId as string

Expand Down Expand Up @@ -71,9 +74,7 @@ const ConfirmationModal = () => {
}
})
}
// This ensures useEffect is called only once
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router, profile])
}, [router, profile, toastyRef])

return (
<Dialog
Expand Down
10 changes: 6 additions & 4 deletions sites/public/src/pages/applications/review/summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
PageView,
pushGtmEvent,
AuthContext,
MessageContext,
useToastyRef,
listingSectionQuestions,
} from "@bloom-housing/shared-helpers"
import {
Expand All @@ -29,7 +29,7 @@ import dayjs from "dayjs"
const ApplicationSummary = () => {
const router = useRouter()
const { profile, applicationsService } = useContext(AuthContext)
const { addToast } = useContext(MessageContext)
const toastyRef = useToastyRef()
const [validationError, setValidationError] = useState(false)
const { conductor, application, listing } = useFormConductor("summary")
let currentPageSection = 4
Expand All @@ -51,18 +51,20 @@ const ApplicationSummary = () => {
}, [profile])

useEffect(() => {
const { addToast } = toastyRef.current

if (listing && router.isReady) {
const currentDate = dayjs()
if (
!(listing.digitalApplication && listing.commonDigitalApplication) ||
listing?.status !== ListingsStatusEnum.active ||
(listing?.applicationDueDate && currentDate > dayjs(listing.applicationDueDate))
) {
// addToast(t("listings.applicationsClosedRedirect"), { variant: "alert" })
addToast(t("listings.applicationsClosedRedirect"), { variant: "alert" })
void router.push(`/${router.locale}/listing/${listing?.id}/${listing.urlSlug}`)
}
}
}, [listing, router, addToast])
}, [listing, router, toastyRef])

useEffect(() => {
conductor.application.reachedReviewStep = true
Expand Down
10 changes: 6 additions & 4 deletions sites/public/src/pages/applications/start/choose-language.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
PageView,
pushGtmEvent,
AuthContext,
MessageContext,
useToastyRef,
CustomIconMap,
} from "@bloom-housing/shared-helpers"
import {
Expand Down Expand Up @@ -54,7 +54,7 @@ const ApplicationChooseLanguage = () => {
const [listing, setListing] = useState(null)
const context = useContext(AppSubmissionContext)
const { initialStateLoaded, profile, listingsService } = useContext(AuthContext)
const { addToast } = useContext(MessageContext)
const toastyRef = useToastyRef()
const { conductor } = context

const listingId = router.query.listingId
Expand Down Expand Up @@ -86,18 +86,20 @@ const ApplicationChooseLanguage = () => {
}, [router, conductor, context, listingId, initialStateLoaded, profile, listingsService])

useEffect(() => {
const { addToast } = toastyRef.current

if (listing && router.isReady) {
const currentDate = dayjs()
if (
!(listing.digitalApplication && listing.commonDigitalApplication) ||
(router?.query?.preview !== "true" && listing?.status !== ListingsStatusEnum.active) ||
(listing?.applicationDueDate && currentDate > dayjs(listing.applicationDueDate))
) {
// addToast(t("listings.applicationsClosedRedirect"), { variant: "alert" })
addToast(t("listings.applicationsClosedRedirect"), { variant: "alert" })
void router.push(`/${router.locale}/listing/${listing?.id}/${listing?.urlSlug}`)
}
}
}, [listing, router, addToast])
}, [listing, router, toastyRef])

const imageUrl = listing?.assets
? imageUrlFromListing(listing, parseInt(process.env.listingPhotoSize))[0]
Expand Down
Loading