refactor(SW-360): extract password validation outside main NewPassword component to minimize re-renders.

This commit is contained in:
Chuma McPhoy
2024-11-25 15:25:12 +01:00
parent c8eaae7928
commit c14fe6bc86

View File

@@ -36,21 +36,6 @@ export default function NewPassword({
const intl = useIntl()
const [isPasswordVisible, setIsPasswordVisible] = useState(false)
function getErrorMessage(key: PasswordValidatorKey) {
switch (key) {
case "length":
return `10 ${intl.formatMessage({ id: "to" })} 40 ${intl.formatMessage({ id: "characters" })}`
case "hasUppercase":
return `1 ${intl.formatMessage({ id: "uppercase letter" })}`
case "hasLowercase":
return `1 ${intl.formatMessage({ id: "lowercase letter" })}`
case "hasNumber":
return `1 ${intl.formatMessage({ id: "number" })}`
case "hasSpecialChar":
return `1 ${intl.formatMessage({ id: "special character" })}`
}
}
return (
<Controller
disabled={disabled}
@@ -59,6 +44,7 @@ export default function NewPassword({
rules={registerOptions}
render={({ field, fieldState, formState }) => {
const errors = Object.values(formState.errors[name]?.types ?? []).flat()
return (
<TextField
aria-label={ariaLabel}
@@ -100,20 +86,9 @@ export default function NewPassword({
</Button>
) : null}
</div>
{field.value ? (
<div className={styles.errors}>
{Object.entries(passwordValidators).map(
([key, { message }]) => (
<Caption asChild color="black" key={key}>
<Text className={styles.helpText} slot="description">
<Icon errorMessage={message} errors={errors} />
{getErrorMessage(key as PasswordValidatorKey)}
</Text>
</Caption>
)
)}
</div>
) : null}
<PasswordValidation value={field.value} errors={errors} />
{!field.value && fieldState.error ? (
<Caption className={styles.error} fontOnly>
<InfoCircleIcon color="red" />
@@ -134,3 +109,43 @@ function Icon({ errorMessage, errors }: IconProps) {
<CheckIcon color="green" height={20} width={20} />
)
}
function PasswordValidation({
value,
errors,
}: {
value: string
errors: string[]
}) {
const intl = useIntl()
if (!value) return null
function getErrorMessage(key: PasswordValidatorKey) {
switch (key) {
case "length":
return `10 ${intl.formatMessage({ id: "to" })} 40 ${intl.formatMessage({ id: "characters" })}`
case "hasUppercase":
return `1 ${intl.formatMessage({ id: "uppercase letter" })}`
case "hasLowercase":
return `1 ${intl.formatMessage({ id: "lowercase letter" })}`
case "hasNumber":
return `1 ${intl.formatMessage({ id: "number" })}`
case "hasSpecialChar":
return `1 ${intl.formatMessage({ id: "special character" })}`
}
}
return (
<div className={styles.errors}>
{Object.entries(passwordValidators).map(([key, { message }]) => (
<Caption asChild color="black" key={key}>
<Text className={styles.helpText} slot="description">
<Icon errorMessage={message} errors={errors} />
{getErrorMessage(key as PasswordValidatorKey)}
</Text>
</Caption>
))}
</div>
)
}