import type { AuthModalSearchParams } from './types' import type { JSX } from 'solid-js' import { clsx } from 'clsx' import { Show, createSignal } from 'solid-js' import { useLocalize } from '../../../context/localize' import { register } from '../../../stores/auth' import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' import { useRouter } from '../../../stores/router' import { hideModal } from '../../../stores/ui' import { ApiError } from '../../../utils/apiClient' import { validateEmail } from '../../../utils/validateEmail' import { Icon } from '../../_shared/Icon' import { AuthModalHeader } from './AuthModalHeader' import { email, setEmail } from './sharedLogic' import { SocialProviders } from './SocialProviders' import styles from './AuthModal.module.scss' type FormFields = { fullName: string email: string password: string } type ValidationErrors = Partial> const handleEmailInput = (newEmail: string) => { setEmail(newEmail) } export const RegisterForm = () => { const { changeSearchParams } = useRouter() const { t } = useLocalize() const { emailChecks } = useEmailChecks() const [submitError, setSubmitError] = createSignal('') const [fullName, setFullName] = createSignal('') const [password, setPassword] = createSignal('') const [isSubmitting, setIsSubmitting] = createSignal(false) const [showPassword, setShowPassword] = createSignal(false) const [isSuccess, setIsSuccess] = createSignal(false) const [validationErrors, setValidationErrors] = createSignal({}) const authFormRef: { current: HTMLFormElement } = { current: null } const handleEmailBlur = () => { if (validateEmail(email())) { checkEmail(email()) } } function isValidPassword(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 handlePasswordInput = (newPassword: string) => { setPassword(newPassword) } const handleNameInput = (newPasswordCopy: string) => { setFullName(newPasswordCopy) } const handleSubmit = async (event: Event) => { event.preventDefault() const passwordError = isValidPassword(password()) if (passwordError) { setValidationErrors((errors) => ({ ...errors, password: passwordError })) } else { setValidationErrors(({ password: _notNeeded, ...rest }) => rest) } setValidationErrors(({ email: _notNeeded, ...rest }) => rest) setValidationErrors(({ fullName: _notNeeded, ...rest }) => rest) setSubmitError('') const newValidationErrors: ValidationErrors = {} const cleanName = fullName().trim() const cleanEmail = email().trim() if (!cleanName) { newValidationErrors.fullName = t('Please enter a name to sign your comments and publication') } if (!cleanEmail) { newValidationErrors.email = t('Please enter email') } else if (!validateEmail(email())) { newValidationErrors.email = t('Invalid email') } if (!password()) { newValidationErrors.password = t('Please enter password') } setValidationErrors(newValidationErrors) const emailCheckResult = await checkEmail(cleanEmail) const isValid = Object.keys(newValidationErrors).length === 0 && !emailCheckResult if (!isValid) { authFormRef.current .querySelector(`input[name="${Object.keys(newValidationErrors)[0]}"]`) .focus() return } setIsSubmitting(true) try { await register({ name: cleanName, email: cleanEmail, password: password(), }) setIsSuccess(true) } catch (error) { if (error instanceof ApiError && error.code === 'user_already_exists') { return } setSubmitError(error.message) } finally { setIsSubmitting(false) } } return ( <>
(authFormRef.current = el)}>
  • {submitError()}
handleNameInput(event.currentTarget.value)} />
{validationErrors().fullName}
handleEmailInput(event.currentTarget.value)} onBlur={handleEmailBlur} />
{validationErrors().email}
handlePasswordInput(event.currentTarget.value)} />
{validationErrors().password}
changeSearchParams({ mode: 'login', }) } > {t('I have an account')}
{t('Almost done! Check your email.')}
{t("We've sent you a message with a link to enter our website.")}
) }