import type { JSX } from 'solid-js' import { Show, createMemo, createSignal } from 'solid-js' import type { AuthModalSearchParams } from './types' import { clsx } from 'clsx' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' import { useRouter } from '../../../stores/router' import { hideModal } from '../../../stores/ui' import { validateEmail } from '../../../utils/validateEmail' import { AuthModalHeader } from './AuthModalHeader' import { PasswordField } from './PasswordField' import { SocialProviders } from './SocialProviders' import { email, setEmail } from './sharedLogic' import { GenericResponse } from '@authorizerdev/authorizer-js' import styles from './AuthModal.module.scss' type EmailStatus = 'not verified' | 'verified' | 'registered' | '' type FormFields = { fullName: string email: string password: string } type ValidationErrors = Partial> const handleEmailInput = (newEmail: string) => { setEmail(newEmail.toLowerCase()) } export const RegisterForm = () => { const { changeSearchParams } = useRouter() const { t } = useLocalize() const { signUp, isRegistered, resendVerifyEmail } = useSession() const [submitError, setSubmitError] = createSignal('') const [fullName, setFullName] = createSignal('') const [password, setPassword] = createSignal('') const [isSubmitting, setIsSubmitting] = createSignal(false) const [isSuccess, setIsSuccess] = createSignal(false) const [validationErrors, setValidationErrors] = createSignal({}) const [passwordError, setPasswordError] = createSignal() const [emailStatus, setEmailStatus] = createSignal('') const authFormRef: { current: HTMLFormElement } = { current: null } const handleNameInput = (newName: string) => { setFullName(newName) } const handleSubmit = async (event: Event) => { event.preventDefault() 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 isValid = createMemo(() => Object.keys(newValidationErrors).length === 0) if (!isValid()) { authFormRef.current .querySelector(`input[name="${Object.keys(newValidationErrors)[0]}"]`) .focus() return } setIsSubmitting(true) try { const opts = { given_name: cleanName, email: cleanEmail, password: password(), confirm_password: password(), redirect_uri: window.location.origin, } const { errors } = await signUp(opts) if (errors) return setIsSuccess(true) } catch (error) { console.error(error) } finally { setIsSubmitting(false) } } const handleResendLink = async (_ev) => { const response: GenericResponse = await resendVerifyEmail({ email: email(), identifier: 'basic_signup', }) setIsSuccess(response?.message === 'Verification email has been sent. Please check your inbox') } const handleCheckEmailStatus = (status: EmailStatus | string) => { switch (status) { case 'not verified': setValidationErrors((prev) => ({ ...prev, email: ( <> {t('This email is not verified')},{' '} {t('resend confirmation link')} ), })) break case 'verified': setValidationErrors((prev) => ({ email: ( <> {t('This email is verified')}. {t('You can')} changeSearchParams({ mode: 'login' })}> {t('enter')} ), })) break case 'registered': setValidationErrors((prev) => ({ ...prev, email: ( <> {t('This email is registered')}. {t('You can')}{' '} changeSearchParams({ mode: 'send-reset-link' })}> {t('Set the new password').toLocaleLowerCase()} ), })) break default: console.info('[RegisterForm] email is not registered') break } } const handleEmailBlur = async () => { if (validateEmail(email())) { const checkResult = await isRegistered(email()) setEmailStatus(checkResult) handleCheckEmailStatus(checkResult) } } return ( <>
(authFormRef.current = el)}>
{submitError()}
handleNameInput(event.currentTarget.value)} />
{validationErrors().fullName}
handleEmailInput(event.currentTarget.value)} onBlur={handleEmailBlur} />
{validationErrors().email}
setPasswordError(err)} onInput={(value) => setPassword(value)} />
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.")}
) }