2023-12-21 10:02:28 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-02-04 11:25:21 +00:00
|
|
|
import { Show, createEffect, createSignal, on } from 'solid-js'
|
2023-12-21 10:02:28 +00:00
|
|
|
|
|
|
|
import { useLocalize } from '../../../../context/localize'
|
|
|
|
import { Icon } from '../../../_shared/Icon'
|
|
|
|
|
|
|
|
import styles from './PasswordField.module.scss'
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
class?: string
|
2024-02-06 14:34:27 +00:00
|
|
|
disabled?: boolean
|
|
|
|
placeholder?: string
|
2023-12-21 10:02:28 +00:00
|
|
|
errorMessage?: (error: string) => void
|
2024-03-07 08:07:46 +00:00
|
|
|
setError?: string
|
2024-03-11 07:41:31 +00:00
|
|
|
onInput?: (value: string) => void
|
2024-03-07 08:07:46 +00:00
|
|
|
onBlur?: (value: string) => void
|
2024-01-27 06:21:48 +00:00
|
|
|
variant?: 'login' | 'registration'
|
2024-02-08 15:37:17 +00:00
|
|
|
disableAutocomplete?: boolean
|
2024-05-12 23:36:46 +00:00
|
|
|
noValidate?: boolean
|
|
|
|
onFocus?: () => void
|
|
|
|
value?: string
|
2023-12-21 10:02:28 +00:00
|
|
|
}
|
|
|
|
|
2024-03-07 08:07:46 +00:00
|
|
|
const minLength = 8
|
|
|
|
const hasNumber = /\d/
|
|
|
|
const hasSpecial = /[!#$%&*@^]/
|
|
|
|
|
2023-12-21 10:02:28 +00:00
|
|
|
export const PasswordField = (props: Props) => {
|
|
|
|
const { t } = useLocalize()
|
|
|
|
const [showPassword, setShowPassword] = createSignal(false)
|
|
|
|
const [error, setError] = createSignal<string>()
|
|
|
|
|
2024-05-12 23:36:46 +00:00
|
|
|
const validatePassword = (passwordToCheck: string) => {
|
2023-12-21 10:02:28 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-03-07 08:07:46 +00:00
|
|
|
const handleInputBlur = (value: string) => {
|
2024-03-11 07:41:31 +00:00
|
|
|
if (props.variant === 'login' && props.onBlur) {
|
|
|
|
props.onBlur(value)
|
|
|
|
return
|
2024-03-07 08:07:46 +00:00
|
|
|
}
|
|
|
|
if (value.length < 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
props.onInput?.(value)
|
2024-05-12 23:36:46 +00:00
|
|
|
if (!props.noValidate) {
|
|
|
|
const errorValue = validatePassword(value)
|
|
|
|
if (errorValue) {
|
|
|
|
setError(errorValue)
|
|
|
|
} else {
|
|
|
|
setError()
|
|
|
|
}
|
2023-12-21 10:02:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-20 23:15:52 +00:00
|
|
|
createEffect(on(error, (er) => er && props.errorMessage?.(er), { defer: true }))
|
|
|
|
createEffect(() => setError(props.setError))
|
2023-12-21 10:02:28 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div class={clsx(styles.PassportField, props.class)}>
|
2024-03-07 08:07:46 +00:00
|
|
|
<div class="pretty-form__item">
|
2023-12-21 10:02:28 +00:00
|
|
|
<input
|
|
|
|
id="password"
|
|
|
|
name="password"
|
2024-02-06 14:34:27 +00:00
|
|
|
disabled={props.disabled}
|
2024-05-12 23:36:46 +00:00
|
|
|
onFocus={props.onFocus}
|
|
|
|
value={props.value ? props.value : ''}
|
2024-02-08 15:37:17 +00:00
|
|
|
autocomplete={props.disableAutocomplete ? 'one-time-code' : 'current-password'}
|
2023-12-21 10:02:28 +00:00
|
|
|
type={showPassword() ? 'text' : 'password'}
|
2024-02-06 14:34:27 +00:00
|
|
|
placeholder={props.placeholder || t('Password')}
|
2024-03-07 08:07:46 +00:00
|
|
|
onBlur={(event) => handleInputBlur(event.currentTarget.value)}
|
2023-12-21 10:02:28 +00:00
|
|
|
/>
|
|
|
|
<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-03-07 08:07:46 +00:00
|
|
|
<Show when={error()}>
|
|
|
|
<div
|
|
|
|
class={clsx(styles.registerPassword, styles.validationError, {
|
2024-06-26 08:22:05 +00:00
|
|
|
'form-message--error': props.setError
|
2024-03-07 08:07:46 +00:00
|
|
|
})}
|
|
|
|
>
|
|
|
|
{error()}
|
|
|
|
</div>
|
2023-12-21 10:02:28 +00:00
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|