webapp/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx
Ilya Y a9f732d1a4
Feature/profile settings page (#452)
* Init change password form
2024-05-13 02:36:46 +03:00

114 lines
3.0 KiB
TypeScript

import { clsx } from 'clsx'
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
disabled?: boolean
placeholder?: string
errorMessage?: (error: string) => void
setError?: string
onInput?: (value: string) => void
onBlur?: (value: string) => void
variant?: 'login' | 'registration'
disableAutocomplete?: boolean
noValidate?: boolean
onFocus?: () => void
value?: string
}
const minLength = 8
const hasNumber = /\d/
const hasSpecial = /[!#$%&*@^]/
export const PasswordField = (props: Props) => {
const { t } = useLocalize()
const [showPassword, setShowPassword] = createSignal(false)
const [error, setError] = createSignal<string>()
const validatePassword = (passwordToCheck: string) => {
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 handleInputBlur = (value: string) => {
if (props.variant === 'login' && props.onBlur) {
props.onBlur(value)
return
}
if (value.length < 1) {
return
}
props.onInput(value)
if (!props.noValidate) {
const errorValue = validatePassword(value)
if (errorValue) {
setError(errorValue)
} else {
setError()
}
}
}
createEffect(
on(
() => error(),
() => {
props.errorMessage?.(error())
},
{ defer: true },
),
)
createEffect(() => {
setError(props.setError)
})
return (
<div class={clsx(styles.PassportField, props.class)}>
<div class="pretty-form__item">
<input
id="password"
name="password"
disabled={props.disabled}
onFocus={props.onFocus}
value={props.value ? props.value : ''}
autocomplete={props.disableAutocomplete ? 'one-time-code' : 'current-password'}
type={showPassword() ? 'text' : 'password'}
placeholder={props.placeholder || t('Password')}
onBlur={(event) => handleInputBlur(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>
<Show when={error()}>
<div
class={clsx(styles.registerPassword, styles.validationError, {
'form-message--error': props.setError,
})}
>
{error()}
</div>
</Show>
</div>
</div>
)
}