webapp/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx

89 lines
2.4 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-02-04 11:25:21 +00:00
import { Show, createEffect, createSignal, on } from 'solid-js'
import { useLocalize } from '../../../../context/localize'
import { Icon } from '../../../_shared/Icon'
import styles from './PasswordField.module.scss'
type Props = {
class?: string
errorMessage?: (error: string) => void
onInput: (value: string) => void
2024-01-27 06:21:48 +00:00
variant?: 'login' | 'registration'
}
export const PasswordField = (props: Props) => {
const { t } = useLocalize()
const [showPassword, setShowPassword] = createSignal(false)
const [error, setError] = createSignal<string>()
const validatePassword = (passwordToCheck) => {
const minLength = 8
const hasNumber = /\d/
const hasSpecial = /[!#$%&*@^]/
if (passwordToCheck.length < minLength) {
return t('Password should be at least 8 characters')
}
if (!hasNumber.test(passwordToCheck)) {
return t('Password should contain at least one number')
}
if (!hasSpecial.test(passwordToCheck)) {
return t('Password should contain at least one special character: !@#$%^&*')
}
return null
}
const handleInputChange = (value) => {
props.onInput(value)
const errorValue = validatePassword(value)
if (errorValue) {
setError(errorValue)
} else {
setError()
}
}
createEffect(
on(
() => error(),
() => {
2024-02-04 09:03:15 +00:00
props.errorMessage?.(error())
},
{ defer: true },
),
)
return (
<div class={clsx(styles.PassportField, props.class)}>
<div
class={clsx('pretty-form__item', {
2024-01-27 06:21:48 +00:00
'pretty-form__item--error': error() && props.variant !== 'login',
})}
>
<input
id="password"
name="password"
autocomplete="current-password"
type={showPassword() ? 'text' : 'password'}
placeholder={t('Password')}
onInput={(event) => handleInputChange(event.currentTarget.value)}
/>
<label for="password">{t('Password')}</label>
<button
type="button"
class={styles.passwordToggle}
onClick={() => setShowPassword(!showPassword())}
>
<Icon class={styles.passwordToggleIcon} name={showPassword() ? 'eye-off' : 'eye'} />
</button>
2024-01-27 06:21:48 +00:00
<Show when={error() && props.variant !== 'login'}>
<div class={clsx(styles.registerPassword, styles.validationError)}>{error()}</div>
</Show>
</div>
</div>
)
}