diff --git a/biome.json b/biome.json index 6861f822..ba7464a5 100644 --- a/biome.json +++ b/biome.json @@ -2,7 +2,7 @@ "$schema": "https://biomejs.dev/schemas/1.5.3/schema.json", "files": { "include": ["*.tsx", "*.ts", "*.js", "*.json"], - "ignore": ["./dist", "./node_modules", ".husky", "docs", "gen"] + "ignore": ["./dist", "./node_modules", ".husky", "docs", "gen", "*.d.ts"] }, "vcs": { "defaultBranch": "dev", @@ -29,7 +29,7 @@ } }, "linter": { - "ignore": ["*.scss", "*.md", ".DS_Store", "*.svg"], + "ignore": ["*.scss", "*.md", ".DS_Store", "*.svg", "*.d.ts"], "enabled": true, "rules": { "all": true, diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 85f2a6cd..f4427991 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -377,6 +377,9 @@ "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?", "This comment has not yet been rated": "This comment has not yet been rated", "This email is": "This email is", + "This email is not verified": "This email is not verified", + "This email is verified": "This email is verified", + "This email is registered": "This email is registered", "This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.", "This month": "This month", "This post has not been rated yet": "This post has not been rated yet", @@ -407,7 +410,6 @@ "Upload video": "Upload video", "Upload": "Upload", "Uploading image": "Uploading image", - "User with this email already exists": "User with this email already exists", "Username": "Username", "Userpic": "Userpic", "Users": "Users", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index bc783798..febefff4 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -399,6 +399,9 @@ "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "В настройках публикации есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?", "This comment has not yet been rated": "Этот комментарий еще пока никто не оценил", "This email is": "Этот email", + "This email is not verified": "Этот email не подтвержден", + "This email is verified": "Этот email подтвержден", + "This email is registered": "Этот email уже зарегистрирован", "This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.", "This month": "За месяц", "This post has not been rated yet": "Эту публикацию еще пока никто не оценил", @@ -429,7 +432,6 @@ "Upload video": "Загрузить видео", "Upload": "Загрузить", "Uploading image": "Загружаем изображение", - "User with this email already exists": "Пользователь с таким email уже существует", "Username": "Имя пользователя", "Userpic": "Аватар", "Users": "Пользователи", diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index 35537140..15255eb2 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -74,7 +74,7 @@ export const AuthorBadge = (props: Props) => { on( () => props.isFollowed, () => { - setIsFollowed(props.isFollowed.value) + setIsFollowed(props.isFollowed?.value) }, ), ) diff --git a/src/components/Nav/AuthModal/AuthModal.module.scss b/src/components/Nav/AuthModal/AuthModal.module.scss index 3c1c8af8..23bd6aff 100644 --- a/src/components/Nav/AuthModal/AuthModal.module.scss +++ b/src/components/Nav/AuthModal/AuthModal.module.scss @@ -198,6 +198,14 @@ border-color: var(--background-color-invert); } } + + &.info, + &.info a { + color: var(--secondary-color); + border-color: var(--secondary-color); + + } + } .title { diff --git a/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx b/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx index 331c4009..c2e0e3bc 100644 --- a/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx +++ b/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx @@ -13,6 +13,7 @@ type Props = { errorMessage?: (error: string) => void onInput: (value: string) => void variant?: 'login' | 'registration' + disableAutocomplete?: boolean } export const PasswordField = (props: Props) => { @@ -69,7 +70,7 @@ export const PasswordField = (props: Props) => { id="password" name="password" disabled={props.disabled} - autocomplete="current-password" + autocomplete={props.disableAutocomplete ? 'one-time-code' : 'current-password'} type={showPassword() ? 'text' : 'password'} placeholder={props.placeholder || t('Password')} onInput={(event) => handleInputChange(event.currentTarget.value)} diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index 6b0b16f8..54e2e69e 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -1,8 +1,8 @@ import type { JSX } from 'solid-js' +import { Show, createEffect, createMemo, createSignal } from 'solid-js' import type { AuthModalSearchParams } from './types' import { clsx } from 'clsx' -import { Show, createEffect, createMemo, createSignal } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' @@ -17,6 +17,8 @@ import { email, setEmail } from './sharedLogic' import styles from './AuthModal.module.scss' +type EmailStatus = 'not verified' | 'verified' | 'registered' | '' + type FormFields = { fullName: string email: string @@ -39,22 +41,12 @@ export const RegisterForm = () => { const [isSubmitting, setIsSubmitting] = createSignal(false) const [isSuccess, setIsSuccess] = createSignal(false) const [validationErrors, setValidationErrors] = createSignal({}) + const [infoEmailMessage, setInfoEmailMessage] = createSignal(false) const [passwordError, setPasswordError] = createSignal() const [emailStatus, setEmailStatus] = createSignal('') const authFormRef: { current: HTMLFormElement } = { current: null } - const checkEmail = async (address: string) => { - const result: string = await isRegistered(address) - if (result) setEmailStatus((_s) => result) - } - - const handleEmailBlur = () => { - if (validateEmail(email())) { - checkEmail(email()) - } - } - const handleNameInput = (newName: string) => { setFullName(newName) } @@ -100,8 +92,8 @@ export const RegisterForm = () => { return } - setIsSubmitting(true) + setInfoEmailMessage(false) try { const opts = { given_name: cleanName, @@ -111,26 +103,7 @@ export const RegisterForm = () => { redirect_uri: window.location.origin, } const { errors } = await signUp(opts) - if (errors?.some((error) => error.message.includes('has already signed up'))) { - setValidationErrors((prev) => ({ - ...prev, - email: ( - <> - {t('User with this email already exists')},{' '} - - changeSearchParams({ - mode: 'login', - }) - } - > - {t('sign in')} - - - ), - })) - } + if (errors) return setIsSuccess(true) } catch (error) { console.error(error) @@ -138,9 +111,65 @@ export const RegisterForm = () => { setIsSubmitting(false) } } - createEffect(() => { - console.debug(emailStatus()) - }) + + const handleCheckEmailStatus = (status: EmailStatus | string) => { + switch (status) { + case 'not verified': + setInfoEmailMessage(true) + setValidationErrors((prev) => ({ + ...prev, + email: ( + <> + {t('This email is not verified')},{' '} + resendVerifyEmail({ email: email(), identifier: 'basic_signup' })} + > + {t('resend confirmation link')} + + + ), + })) + break + + case 'verified': + setInfoEmailMessage(true) + setValidationErrors((prev) => ({ + email: ( + <> + {t('This email is verified')},{' '} + changeSearchParams({ mode: 'login' })}> + {t('enter')} + + + ), + })) + break + case 'registered': + setValidationErrors((prev) => ({ + ...prev, + email: ( + <> + {t('This email is registered')},{'. '} + changeSearchParams({ mode: 'send-reset-link' })}> + {t('Set the new password').toLocaleLowerCase()} + + + ), + })) + break + default: + setInfoEmailMessage(false) + break + } + } + + const handleEmailBlur = async () => { + if (validateEmail(email())) { + const checkResult = await isRegistered(email()) + handleCheckEmailStatus(checkResult) + } + } return ( <> @@ -162,63 +191,37 @@ export const RegisterForm = () => { name="fullName" type="text" placeholder={t('Full name')} - autocomplete="" + autocomplete="one-time-code" onInput={(event) => handleNameInput(event.currentTarget.value)} /> - +
{validationErrors().fullName}
handleEmailInput(event.currentTarget.value)} onBlur={handleEmailBlur} /> -
{validationErrors().email}
- - {t('This email is')} {emailStatus() ? t(emailStatus()) : ''},{' '} - - - changeSearchParams({ mode: 'login' })}> - {t('enter')} - - - - resendVerifyEmail({ email: email(), identifier: 'basic_signup' })} - > - {t('resend confirmation link')} - - - - - changeSearchParams({ - mode: 'send-reset-link', - }) - } - > - {t('Set the new password').toLocaleLowerCase()} - - +
+ {validationErrors().email} +
setPasswordError(err)} onInput={(value) => setPassword(value)}