From 1d64d97f9fcd8fe419c386503cfb4765e2fb8813 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:07:46 +0300 Subject: [PATCH] Hotfix/parse auth errors (#423) Add fixes to login form parse errors --- public/locales/en/translation.json | 9 +- public/locales/ru/translation.json | 11 +- .../CommentDate/CommentDate.module.scss | 2 - .../Nav/AuthModal/AuthModal.module.scss | 17 +-- .../Nav/AuthModal/ChangePasswordForm.tsx | 7 +- .../Nav/AuthModal/EmailConfirm.module.scss | 13 --- src/components/Nav/AuthModal/EmailConfirm.tsx | 17 +-- src/components/Nav/AuthModal/LoginForm.tsx | 106 +++++++++--------- .../PasswordField/PasswordField.module.scss | 6 +- .../AuthModal/PasswordField/PasswordField.tsx | 41 ++++--- src/components/Nav/AuthModal/RegisterForm.tsx | 41 +++---- .../Nav/AuthModal/SendEmailConfirm.tsx | 24 ++++ .../Nav/AuthModal/SendResetLinkForm.tsx | 57 +++++----- .../SocialProviders.module.scss | 0 .../{ => SocialProviders}/SocialProviders.tsx | 8 +- .../Nav/AuthModal/SocialProviders/index.ts | 1 + src/components/Nav/AuthModal/index.tsx | 2 + src/components/Nav/AuthModal/types.ts | 8 +- src/styles/app.scss | 2 +- 19 files changed, 203 insertions(+), 169 deletions(-) delete mode 100644 src/components/Nav/AuthModal/EmailConfirm.module.scss create mode 100644 src/components/Nav/AuthModal/SendEmailConfirm.tsx rename src/components/Nav/AuthModal/{ => SocialProviders}/SocialProviders.module.scss (100%) rename src/components/Nav/AuthModal/{ => SocialProviders}/SocialProviders.tsx (70%) create mode 100644 src/components/Nav/AuthModal/SocialProviders/index.ts diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 15668aca..955ceb78 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -18,6 +18,7 @@ "Add signature": "Add signature", "Add subtitle": "Add subtitle", "Add url": "Add url", + "try": "попробуйте", "Add": "Add", "Address on Discours": "Address on Discours", "Album name": "Название aльбома", @@ -144,7 +145,6 @@ "Enter your new password": "Enter your new password", "Enter": "Enter", "Error": "Error", - "Please give us your email address": "Please provide us your email address to get the password reset link", "Experience": "Experience", "FAQ": "Tips and suggestions", "Favorite topics": "Favorite topics", @@ -254,7 +254,6 @@ "Nothing here yet": "There's nothing here yet", "Nothing is here": "There is nothing here", "Notifications": "Notifications", - "Now you can enter a new password, it must contain at least 8 characters and not be the same as the previous password": "Now you can enter a new password, it must contain at least 8 characters and not be the same as the previous password", "Or paste a link to an image": "Or paste a link to an image", "Ordered list": "Ordered list", "Our regular contributor": "Our regular contributor", @@ -323,7 +322,7 @@ "Self-publishing exists thanks to the help of wonderful people from all over the world. Thank you!": "Samizdat exists thanks to the help of wonderful people from all over the world. Thank you!", "Send link again": "Send link again", "Send": "Send", - "Set the new password": "Set the new password", + "Forgot password?": "Forgot password?", "Settings": "Settings", "Share publication": "Share publication", "Share": "Share", @@ -524,5 +523,7 @@ "video": "video", "view": "view", "viewsWithCount": "{count} {count, plural, one {view} other {views}}", - "yesterday": "yesterday" + "yesterday": "yesterday", + "It's OK. Just enter your email to receive a link to change your password": "It's OK. Just enter your email to receive a link to change your password", + "Restore password": "Restore password" } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 788d31cc..74156b69 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -150,7 +150,6 @@ "Enter your new password": "Введите новый пароль", "Enter": "Войти", "Error": "Ошибка", - "Please give us your email address": "Пожалуйста, укажите свою почту, чтобы получить ссылку для сброса пароля", "Experience": "Личный опыт", "FAQ": "Советы и предложения", "Favorite topics": "Избранные темы", @@ -266,7 +265,6 @@ "Nothing here yet": "Здесь пока ничего нет", "Nothing is here": "Здесь ничего нет", "Notifications": "Уведомления", - "Now you can enter a new password, it must contain at least 8 characters and not be the same as the previous password": "Теперь можете ввести новый пароль, он должен содержать минимум 8 символов и не совпадать с предыдущим паролем", "Or paste a link to an image": "Или вставьте ссылку на изображение", "Ordered list": "Нумерованный список", "Our regular contributor": "Наш постоянный автор", @@ -287,7 +285,7 @@ "Pin": "Закрепить", "Platform Guide": "Гид по дискурсу", "Please check your email address": "Пожалуйста, проверьте введенный адрес почты", - "Please check your inbox! We have sent a password reset link.": "Пожалуйста, проверьте ваш адрес почты, мы отправили ссылку для сброса пароля", + "Please check your inbox! We have sent a password reset link.": "Пожалуйста, проверьте свою почту, мы отправили вам письмо со ссылкой для сброса пароля", "Please confirm your email to finish": "Подтвердите почту и действие совершится", "Please enter a name to sign your comments and publication": "Пожалуйста, введите имя, которое будет отображаться на сайте", "Please enter email": "Пожалуйста, введите почту", @@ -328,7 +326,7 @@ "Reports": "Репортажи", "Required": "Поле обязательно для заполнения", "Resend code": "Выслать подтверждение", - "Set the new password": "Задать новый пароль", + "Forgot password?": "Забыли пароль?", "Rules of the journal Discours": "Правила журнала Дискурс", "Save draft": "Сохранить черновик", "Save settings": "Сохранить настройки", @@ -403,6 +401,7 @@ "This email is": "Этот email", "This email is not verified": "Этот email не подтвержден", "This email is verified": "Этот email подтвержден", + "try": "попробуйте", "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": "За месяц", @@ -550,5 +549,7 @@ "video": "видео", "view": "просмотр", "viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}", - "yesterday": "вчера" + "yesterday": "вчера", + "It's OK. Just enter your email to receive a link to change your password": "Ничего страшного. Просто укажите свою почту, чтобы получить ссылку для смены пароля", + "Restore password": "Восстановить пароль" } diff --git a/src/components/Article/CommentDate/CommentDate.module.scss b/src/components/Article/CommentDate/CommentDate.module.scss index 89d90585..50cf7d57 100644 --- a/src/components/Article/CommentDate/CommentDate.module.scss +++ b/src/components/Article/CommentDate/CommentDate.module.scss @@ -2,8 +2,6 @@ @include font-size(1.2rem); color: var(--secondary-color); - - // align-self: center; display: flex; align-items: flex-start; justify-content: flex-start; diff --git a/src/components/Nav/AuthModal/AuthModal.module.scss b/src/components/Nav/AuthModal/AuthModal.module.scss index 23bd6aff..2d4cbc98 100644 --- a/src/components/Nav/AuthModal/AuthModal.module.scss +++ b/src/components/Nav/AuthModal/AuthModal.module.scss @@ -1,5 +1,5 @@ .view { - background: #fff; + background: var(--background-color); min-height: 550px; position: relative; justify-content: center; @@ -154,17 +154,6 @@ margin-bottom: 1em; } -.authInfo { - font-weight: 400; - font-size: smaller; - margin-top: -2em; - position: absolute; - - .warn { - color: #a00; - } -} - .authForm { display: flex; flex: 1; @@ -221,3 +210,7 @@ line-height: 24px; margin-bottom: 52px; } + +.submitError { + margin: -1rem 0 -2rem; +} diff --git a/src/components/Nav/AuthModal/ChangePasswordForm.tsx b/src/components/Nav/AuthModal/ChangePasswordForm.tsx index 2fa9c3a9..a317e834 100644 --- a/src/components/Nav/AuthModal/ChangePasswordForm.tsx +++ b/src/components/Nav/AuthModal/ChangePasswordForm.tsx @@ -33,7 +33,7 @@ export const ChangePasswordForm = () => { event.preventDefault() setIsSubmitting(true) if (newPassword()) { - await changePassword(newPassword(), searchParams()?.token) + changePassword(newPassword(), searchParams()?.token) setTimeout(() => { setIsSubmitting(false) setIsSuccess(true) @@ -60,11 +60,6 @@ export const ChangePasswordForm = () => { >

{t('Enter a new password')}

-
- {t( - 'Now you can enter a new password, it must contain at least 8 characters and not be the same as the previous password', - )} -
{validationErrors().password}
diff --git a/src/components/Nav/AuthModal/EmailConfirm.module.scss b/src/components/Nav/AuthModal/EmailConfirm.module.scss deleted file mode 100644 index 323b5384..00000000 --- a/src/components/Nav/AuthModal/EmailConfirm.module.scss +++ /dev/null @@ -1,13 +0,0 @@ -.title { - font-size: 26px; - line-height: 32px; - font-weight: 700; - color: #141414; - margin-bottom: 16px; -} - -.text { - font-size: 15px; - line-height: 24px; - margin-bottom: 52px; -} diff --git a/src/components/Nav/AuthModal/EmailConfirm.tsx b/src/components/Nav/AuthModal/EmailConfirm.tsx index 1bd88086..2a7367bc 100644 --- a/src/components/Nav/AuthModal/EmailConfirm.tsx +++ b/src/components/Nav/AuthModal/EmailConfirm.tsx @@ -17,19 +17,20 @@ export const EmailConfirm = () => { const [emailConfirmed, setEmailConfirmed] = createSignal(false) createEffect(() => { - const e = session()?.user?.email - const v = session()?.user?.email_verified - if (e) { - setEmail(e.toLowerCase()) - if (v) setEmailConfirmed(v) + const email = session()?.user?.email + const isVerified = session()?.user?.email_verified + + if (email) { + setEmail(email.toLowerCase()) + if (isVerified) setEmailConfirmed(isVerified) if (authError()) { changeSearchParams({}, true) } } - }) - createEffect(() => { - if (authError()) console.debug('[AuthModal.EmailConfirm] auth error:', authError()) + if (authError()) { + console.debug('[AuthModal.EmailConfirm] auth error:', authError()) + } }) return ( diff --git a/src/components/Nav/AuthModal/LoginForm.tsx b/src/components/Nav/AuthModal/LoginForm.tsx index b708d32b..4ea5a5f6 100644 --- a/src/components/Nav/AuthModal/LoginForm.tsx +++ b/src/components/Nav/AuthModal/LoginForm.tsx @@ -1,7 +1,7 @@ import type { AuthModalSearchParams } from './types' import { clsx } from 'clsx' -import { Show, createSignal } from 'solid-js' +import { JSX, Show, createEffect, createSignal } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' @@ -27,12 +27,11 @@ type ValidationErrors = Partial> export const LoginForm = () => { const { changeSearchParams } = useRouter() const { t } = useLocalize() - const [submitError, setSubmitError] = createSignal('') + const [submitError, setSubmitError] = createSignal() const [isSubmitting, setIsSubmitting] = createSignal(false) const [password, setPassword] = createSignal('') const [validationErrors, setValidationErrors] = createSignal({}) - // TODO: better solution for interactive error messages - const [isEmailNotConfirmed, setIsEmailNotConfirmed] = createSignal(false) + const [isLinkSent, setIsLinkSent] = createSignal(false) const authFormRef: { current: HTMLFormElement } = { current: null } const { showSnackbar } = useSnackbar() @@ -52,43 +51,43 @@ export const LoginForm = () => { event.preventDefault() setIsLinkSent(true) - setIsEmailNotConfirmed(false) - setSubmitError('') - changeSearchParams({ mode: 'send-reset-link' }) - // NOTE: temporary solution, needs logic in authorizer - /* FIXME: - const { authorizer } = useSession() - const result = await authorizer().verifyEmail({ token }) - if (!result) setSubmitError('cant sign send link') - */ + setSubmitError() + changeSearchParams({ mode: 'send-confirm-email' }) } + const preSendValidate = async (value: string, type: 'email' | 'password'): Promise => { + if (type === 'email') { + if (value === '' || !validateEmail(value)) { + setValidationErrors((prev) => ({ + ...prev, + email: t('Invalid email'), + })) + return false + } + } else if (type === 'password') { + if (value === '') { + setValidationErrors((prev) => ({ + ...prev, + password: t('Please enter password'), + })) + return false + } + } + return true + } const handleSubmit = async (event: Event) => { event.preventDefault() + await preSendValidate(email(), 'email') + await preSendValidate(password(), 'password') + setIsLinkSent(false) - setIsEmailNotConfirmed(false) - setSubmitError('') - - const newValidationErrors: ValidationErrors = {} - - const validateAndSetError = (field, message) => { - if (!field()) { - newValidationErrors[field.name] = t(message) - } - } - - validateAndSetError(email, 'Please enter email') - validateAndSetError(() => validateEmail(email()), 'Invalid email') - validateAndSetError(password, 'Please enter password') - - if (Object.keys(newValidationErrors).length > 0) { - setValidationErrors(newValidationErrors) + setSubmitError() + if (Object.keys(validationErrors()).length > 0) { authFormRef.current - .querySelector(`input[name="${Object.keys(newValidationErrors)[0]}"]`) + .querySelector(`input[name="${Object.keys(validationErrors())[0]}"]`) ?.focus() - return } @@ -96,14 +95,27 @@ export const LoginForm = () => { try { const { errors } = await signIn({ email: email(), password: password() }) + console.error('[signIn errors]', errors) if (errors?.length > 0) { if (errors.some((error) => error.message.includes('bad user credentials'))) { setValidationErrors((prev) => ({ ...prev, password: t('Something went wrong, check email and password'), })) + } else if (errors.some((error) => error.message.includes('user not found'))) { + setSubmitError('Пользователь не найден') + } else if (errors.some((error) => error.message.includes('email not verified'))) { + setSubmitError( +
+ {t('This email is not verified')} + {'. '} + + {t('Send link again')} + +
, + ) } else { - setSubmitError(t('Error')) + setSubmitError(t('Error', errors[0].message)) } return } @@ -121,19 +133,6 @@ export const LoginForm = () => {
(authFormRef.current = el)}>
- -
-
{submitError()}
- - - {t('Send link again')} - - -
-
- -
{t('Link sent, check your email')}
-
{
- handlePasswordInput(value)} /> - -
- {validationErrors().password} -
+ handlePasswordInput(value)} + /> + + +
{submitError()}
@@ -175,7 +177,7 @@ export const LoginForm = () => { }) } > - {t('Set the new password')} + {t('Forgot password?')}
diff --git a/src/components/Nav/AuthModal/PasswordField/PasswordField.module.scss b/src/components/Nav/AuthModal/PasswordField/PasswordField.module.scss index 7faae657..f050d700 100644 --- a/src/components/Nav/AuthModal/PasswordField/PasswordField.module.scss +++ b/src/components/Nav/AuthModal/PasswordField/PasswordField.module.scss @@ -31,11 +31,11 @@ } /* Red/500 */ - color: #d00820; + color: orange; a { - color: #d00820; - border-color: #d00820; + color: orange; + border-color: orange; &:hover { color: var(--default-color-invert); diff --git a/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx b/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx index c2e0e3bc..bf7f00b1 100644 --- a/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx +++ b/src/components/Nav/AuthModal/PasswordField/PasswordField.tsx @@ -11,21 +11,23 @@ type Props = { disabled?: boolean placeholder?: string errorMessage?: (error: string) => void + setError?: string onInput: (value: string) => void + onBlur?: (value: string) => void variant?: 'login' | 'registration' disableAutocomplete?: boolean } +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() const validatePassword = (passwordToCheck) => { - const minLength = 8 - const hasNumber = /\d/ - const hasSpecial = /[!#$%&*@^]/ - if (passwordToCheck.length < minLength) { return t('Password should be at least 8 characters') } @@ -35,11 +37,17 @@ export const PasswordField = (props: Props) => { if (!hasSpecial.test(passwordToCheck)) { return t('Password should contain at least one special character: !@#$%^&*') } - return null } - const handleInputChange = (value) => { + const handleInputBlur = (value: string) => { + if (props.variant === 'login') { + return props.onBlur(value) + } + if (value.length < 1) { + return + } + props.onInput(value) const errorValue = validatePassword(value) if (errorValue) { @@ -58,14 +66,13 @@ export const PasswordField = (props: Props) => { { defer: true }, ), ) + createEffect(() => { + setError(props.setError) + }) return (
-
+
{ autocomplete={props.disableAutocomplete ? 'one-time-code' : 'current-password'} type={showPassword() ? 'text' : 'password'} placeholder={props.placeholder || t('Password')} - onInput={(event) => handleInputChange(event.currentTarget.value)} + onBlur={(event) => handleInputBlur(event.currentTarget.value)} /> - -
{error()}
+ +
+ {error()} +
diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index ec78b44e..383eaad5 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -28,10 +28,6 @@ type FormFields = { type ValidationErrors = Partial> -const handleEmailInput = (newEmail: string) => { - setEmail(newEmail.toLowerCase()) -} - export const RegisterForm = () => { const { changeSearchParams } = useRouter() const { t } = useLocalize() @@ -52,6 +48,7 @@ export const RegisterForm = () => { } const handleSubmit = async (event: Event) => { + console.log('!!! handleSubmit:', handleSubmit) event.preventDefault() if (passwordError()) { setValidationErrors((errors) => ({ ...errors, password: passwordError() })) @@ -137,7 +134,8 @@ export const RegisterForm = () => { setValidationErrors((prev) => ({ email: ( <> - {t('This email is verified')}. {t('You can')} + {t('This email is registered')}. {t('try')} + {', '} changeSearchParams({ mode: 'login' })}> {t('enter')} @@ -172,17 +170,18 @@ export const RegisterForm = () => { } } + const handleEmailInput = (newEmail: string) => { + setEmailStatus('') + setValidationErrors({}) + setEmail(newEmail.toLowerCase()) + } + return ( <> (authFormRef.current = el)}>
- -
-
{submitError()}
-
-
{ onBlur={handleEmailBlur} /> -
- {validationErrors().email} -
+ +
+ {validationErrors().email} +
+
{ -
{t('Almost done! Check your email.')}
-
{t("We've sent you a message with a link to enter our website.")}
-
- +
+
{t('Almost done! Check your email.')}
+
{t("We've sent you a message with a link to enter our website.")}
+
+ +
diff --git a/src/components/Nav/AuthModal/SendEmailConfirm.tsx b/src/components/Nav/AuthModal/SendEmailConfirm.tsx new file mode 100644 index 00000000..dd8c01dd --- /dev/null +++ b/src/components/Nav/AuthModal/SendEmailConfirm.tsx @@ -0,0 +1,24 @@ +import { clsx } from 'clsx' +import { useLocalize } from '../../../context/localize' +import { hideModal } from '../../../stores/ui' + +import styles from './AuthModal.module.scss' + +export const SendEmailConfirm = () => { + const { t } = useLocalize() + return ( +
+
{t('Link sent, check your email')}
+
+ +
+
+ ) +} diff --git a/src/components/Nav/AuthModal/SendResetLinkForm.tsx b/src/components/Nav/AuthModal/SendResetLinkForm.tsx index f429a256..c8d635d7 100644 --- a/src/components/Nav/AuthModal/SendResetLinkForm.tsx +++ b/src/components/Nav/AuthModal/SendResetLinkForm.tsx @@ -79,8 +79,12 @@ export const SendResetLinkForm = () => { ref={(el) => (authFormRef.current = el)} >
-

{t('Set the new password')}

-
{t(message()) || t('Please give us your email address')}
+

{t('Forgot password?')}

+ +
+ {t("It's OK. Just enter your email to receive a link to change your password")} +
+
{ class={'link'} onClick={() => changeSearchParams({ - mode: 'login', + mode: 'register', }) } > @@ -116,28 +120,31 @@ export const SendResetLinkForm = () => {
{validationErrors().email}
- -
- -
-
- - changeSearchParams({ - mode: 'login', - }) - } - > - {t('I know the password')} - -
+ {t(message())}
}> + <> +
+ +
+
+ + changeSearchParams({ + mode: 'login', + }) + } + > + {t('I know the password')} + +
+ +
) diff --git a/src/components/Nav/AuthModal/SocialProviders.module.scss b/src/components/Nav/AuthModal/SocialProviders/SocialProviders.module.scss similarity index 100% rename from src/components/Nav/AuthModal/SocialProviders.module.scss rename to src/components/Nav/AuthModal/SocialProviders/SocialProviders.module.scss diff --git a/src/components/Nav/AuthModal/SocialProviders.tsx b/src/components/Nav/AuthModal/SocialProviders/SocialProviders.tsx similarity index 70% rename from src/components/Nav/AuthModal/SocialProviders.tsx rename to src/components/Nav/AuthModal/SocialProviders/SocialProviders.tsx index d547bb1d..297a4749 100644 --- a/src/components/Nav/AuthModal/SocialProviders.tsx +++ b/src/components/Nav/AuthModal/SocialProviders/SocialProviders.tsx @@ -1,8 +1,8 @@ import { For } from 'solid-js' -import { useLocalize } from '../../../context/localize' -import { useSession } from '../../../context/session' -import { Icon } from '../../_shared/Icon' +import { useLocalize } from '../../../../context/localize' +import { useSession } from '../../../../context/session' +import { Icon } from '../../../_shared/Icon' import styles from './SocialProviders.module.scss' @@ -18,7 +18,7 @@ export const SocialProviders = () => {
{(provider) => ( - )} diff --git a/src/components/Nav/AuthModal/SocialProviders/index.ts b/src/components/Nav/AuthModal/SocialProviders/index.ts new file mode 100644 index 00000000..07a9863a --- /dev/null +++ b/src/components/Nav/AuthModal/SocialProviders/index.ts @@ -0,0 +1 @@ +export { SocialProviders } from './SocialProviders' diff --git a/src/components/Nav/AuthModal/index.tsx b/src/components/Nav/AuthModal/index.tsx index 760e58a0..d1df5650 100644 --- a/src/components/Nav/AuthModal/index.tsx +++ b/src/components/Nav/AuthModal/index.tsx @@ -16,12 +16,14 @@ import { RegisterForm } from './RegisterForm' import { SendResetLinkForm } from './SendResetLinkForm' import styles from './AuthModal.module.scss' +import { SendEmailConfirm } from './SendEmailConfirm' const AUTH_MODAL_MODES: Record = { login: LoginForm, register: RegisterForm, 'send-reset-link': SendResetLinkForm, 'confirm-email': EmailConfirm, + 'send-confirm-email': SendEmailConfirm, 'change-password': ChangePasswordForm, } diff --git a/src/components/Nav/AuthModal/types.ts b/src/components/Nav/AuthModal/types.ts index e2db3e78..185b5841 100644 --- a/src/components/Nav/AuthModal/types.ts +++ b/src/components/Nav/AuthModal/types.ts @@ -1,4 +1,10 @@ -export type AuthModalMode = 'login' | 'register' | 'confirm-email' | 'send-reset-link' | 'change-password' +export type AuthModalMode = + | 'login' + | 'register' + | 'confirm-email' + | 'send-confirm-email' + | 'send-reset-link' + | 'change-password' export type AuthModalSource = | 'discussions' | 'vote' diff --git a/src/styles/app.scss b/src/styles/app.scss index d563840e..db3a68bc 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -464,7 +464,7 @@ form { } .form-message--error { - color: #d00820; + color: var(--danger-color) !important; } select {